当前位置: 首页 > news >正文

[VoiceRAG] 前端实时通信 | useRealTime钩子

第5章:前端实时通信(useRealTime钩子)

在第4章:浏览器音频处理中,我们学习了浏览器如何作为精密麦克风与扬声器,捕获你的语音并播放AI的响应。

但录音如何从浏览器传送到AI的"大脑"(后端的RTMiddleTier)?AI的语音回答和附加信息(如RAG工具集的来源引用)又如何实时返回浏览器?

这正是前端实时通信的核心,特别是通过useRealTime钩子实现

问题:建立浏览器与AI的实时连接

设想你需要与AI进行闪电般快速的语音对话。

浏览器已准备好录音,后端AI也已待命,但两者之间缺少实时通信的"电话线"。

常规网页交互通常是发送请求后等待完整响应(如加载新页面)。但语音对话需要更快速、更持续的通信:

  • 持续输入:说话时,语音小片段需持续流向AI
  • 持续输出:AI思考与回答时,其语音和支持信息(如答案来源)需实时返回,通常在说完前就开始传输
  • 低延迟:任何延迟都会让对话感觉不自然

这需要WebSocket——专为实时双向通信设计的特殊网络连接。

解决方案:useRealTime钩子——AI的专用对讲机

useRealTime钩子是客户端引擎,管理浏览器与后端RTMiddleTier之间的WebSocket连接。它如同直接连接浏览器与AI的对讲机,功能包括:

  • 建立连接:打开持久的双向"电话线"(WebSocket)
  • 发送语音:持续发送录音输入(来自第4章的base64音频块)至后端
  • 监听AI响应:持续接收AI的语音响应,通过浏览器播放
  • 接收工具结果:监听AI的其他重要消息,如report_grounding工具的来源引用(见第2章)

该钩子确保你的语音直达AI,答案直返给你,实现流畅的实时对话。

如何使用useRealTime钩子

让我们看看主页面组件App.tsx如何用此钩子管理对话。

1. 设置useRealTime钩子

App.tsx组件导入并调用useRealTime钩子,提供各种"事件监听器"(特定事件触发的函数):

// app/frontend/src/App.tsx
import useRealTime from "@/hooks/useRealtime"; 
import useAudioRecorder from "@/hooks/useAudioRecorder";
import useAudioPlayer from "@/hooks/useAudioPlayer";function App() 
{const [isRecording, setIsRecording] = useState(false);const [groundingFiles, setGroundingFiles] = useState([]); // 存储AI的来源引用const { startSession, addUserAudio, inputAudioBufferClear } = useRealTime({onWebSocketOpen: () => console.log("WebSocket连接已开启"),onReceivedResponseAudioDelta: message => {isRecording && playAudio(message.delta); // 实时播放AI语音},onReceivedExtensionMiddleTierToolResponse: message => {// 处理AI的工具结果(如来源引用)const result = JSON.parse(message.tool_result);const files = result.sources.map(x => ({id: x.chunk_id, name: x.title, content: x.chunk}));setGroundingFiles(prev => [...prev, ...files]); // 更新显示的来源}// ...其他事件处理器...});const { play: playAudio } = useAudioPlayer(); // 播放AI语音const { start: startAudioRecording, stop: stopAudioRecording } = useAudioRecorder({ onAudioRecorded: addUserAudio });// ...其余代码...
}

说明

  • useRealTime钩子调用时会建立WebSocket连接
  • onWebSocketOpen在连接就绪时触发
  • onReceivedResponseAudioDelta至关重要:接收AI语音块(message.delta)并立即通过playAudio播放,实现实时语音
  • onReceivedExtensionMiddleTierToolResponse处理工具结果(如report_grounding的来源引用),更新groundingFiles状态以显示来源

2. 开始与结束对话

点击应用中的麦克风按钮时,onToggleListening函数处理实时通信的启停:

// app/frontend/src/App.tsxconst onToggleListening = async () => {if (!isRecording) {startSession(); // 开启新对话会话await startAudioRecording(); // 开始录音setIsRecording(true);} else {await stopAudioRecording(); // 停止录音inputAudioBufferClear(); // 清除后端待处理音频setIsRecording(false);}};

说明

  • 开始录音时:
    • startSession()发送初始化消息,准备AI的新对话轮次
    • startAudioRecording()开始捕获麦克风输入,通过onAudioRecorded回调(即addUserAudio)持续发送语音块至后端
  • 停止录音时:
    • stopAudioRecording()停止捕获
    • inputAudioBufferClear()通知后端清除待处理音频

3. 发送你的音频

如前述,useAudioRecorder通过addUserAudio发送语音块:

// app/frontend/src/hooks/useRealtime.tsx
import useWebSocket from "react-use-websocket";export default function useRealTime({ /* ...参数... */ }) 
{const { sendJsonMessage } = useWebSocket(/* ...WebSocket配置... */);const addUserAudio = (base64Audio: string) => {sendJsonMessage({type: "input_audio_buffer.append", // 消息类型:发送音频audio: base64Audio // 编码为文本的录音});};// ...其他函数...
}

说明addUserAudio构建包含base64Audio的消息,通过sendJsonMessage经WebSocket发送至后端。说话时此函数会每秒多次调用。

底层原理:实时通信流程

追踪语音输入如何通过useRealTime钩子和WebSocket连接触发AI响应及来源引用:

在这里插入图片描述

代码解析:useRealTime.tsx

useRealTime钩子基于React库react-use-websocket,简化了WebSocket在React应用中的使用。

1. 建立WebSocket连接

useRealTime核心是通过useWebSocket建立连接:

// app/frontend/src/hooks/useRealtime.tsx(简化)
import useWebSocket from "react-use-websocket";export default function useRealTime({ /* ...参数... */ }) {const wsEndpoint = useDirectAoaiApi ? `${aoaiEndpointOverride}/openai/realtime?...` // 直连Azure OpenAI: `/realtime`; // 默认连接RTMiddleTier(第3章)const { sendJsonMessage } = useWebSocket(wsEndpoint, {onOpen: () => onWebSocketOpen?.(), // 连接开启回调onMessage: event => onMessageReceived(event), // 处理所有接收消息shouldReconnect: () => true // 断开时自动重连});// ...其余代码...
}

说明

  • wsEndpoint决定连接目标(默认/realtime路径指向RTMiddleTier)
  • useWebSocket返回sendJsonMessage函数,用于发送JSON消息
  • onMessageReceived是处理接收消息的核心
2. 接收与路由消息(onMessageReceived

onMessageReceived如同消息接待台,根据type字段调用对应处理器:

// app/frontend/src/hooks/useRealtime.tsx(简化)const onMessageReceived = (event: MessageEvent<any>) => {const message = JSON.parse(event.data); // 解析JSON消息switch (message.type) {case "response.audio.delta":onReceivedResponseAudioDelta?.(message); // 处理AI语音块break;case "extension.middle_tier_tool_response":onReceivedExtensionMiddleTierToolResponse?.(message); // 处理工具结果break;case "response.done":onReceivedResponseDone?.(message); // AI完成响应break;case "error":onReceivedError?.(message); // 错误处理break;}};

说明:通过switch语句根据message.type路由消息,如response.audio.delta触发语音播放,extension.middle_tier_tool_response更新来源引用显示。

关键消息类型

app/frontend/src/types.ts定义了前后端通信的消息结构,关键类型包括:

消息类型方向描述对应处理器
session.update前端->后端初始化/更新会话startSession
input_audio_buffer.append前端->后端发送用户音频块addUserAudio
response.audio.delta后端->前端发送AI语音块onReceivedResponseAudioDelta
extension.middle_tier_tool_response后端->前端发送RAG工具结果(如来源引用)onReceivedExtensionMiddleTierToolResponse

此表展示了前后端如何通过结构化消息进行"对话"。

总结

useRealTime钩子是连接浏览器音频能力(第4章)与后端AI智能(RTMiddleTier和RAG工具集)的关键通信层。

通过稳健的WebSocket连接,它确保你的语音流畅传输至AI,而AI的语音响应和工具结果(如来源引用)实时返回,使整个语音对话生动而响应迅速。

现在应用已具备听说与实时思考能力,最后一步是学习如何将项目部署至Azure。在第6章:Azure部署(Azure开发者CLI)中,我们将探索如何在云端运行你的AI语音助手。

http://www.dtcms.com/a/465470.html

相关文章:

  • Typora 配置 PicGo 使用 Gitee 图床实现图片自动上传(Mac 详细教程)
  • 安装elk
  • RNN-seq2seq 英译法案例
  • 房地产 网站 案例电商网站建设与运营方向
  • 2025年企微SCRM工具核心功能深度测评:微盛AI·企微管家领跑赛道
  • Deepwiki AI技术揭秘 - 系统架构分析篇
  • 做斗图的网站html5 手机网站 教程
  • Flink面试题及详细答案100道(61-80)- 时间与窗口
  • Git 报错:fatal: update_ref failed for ref ‘ORIG_HEAD‘ 解决记录
  • 关于域名和主机论坛的网站北京实创装修公司官网
  • Apache Spark 上手指南(基于 Spark 3.5.0 稳定版)
  • COA学习,Chain of Agents
  • winform本地上位机-ModbusRTC1.上位机控制台与数据监控(数据监控架构思维与图表系列)
  • 如何建立“长期主义+短期收益”并存的商业闭环?
  • 敏捷管理之看板方法:可视化管理的流程设计与优化技巧
  • Linux学习笔记--查询_唤醒方式读取输入数据
  • 信道编码定理和信道编码逆定理
  • 订餐网站开发流程wordpress显示运行时间
  • ubuntu 24.04 FFmpeg编译 带Nvidia 加速记录
  • 关于springboot定时任务和websocket的思考
  • 做文字logo的网站我国网络营销现状分析
  • STM32F103RCT6+STM32CubeMX+keil5(MDK-ARM)+Flymcu实现简单的通信协议
  • 昂瑞微:踏浪前行,铸就射频芯片领域新辉煌
  • Roo Code系统提示覆写功能详解
  • 时钟周期约束(三)
  • 基于Hadoop的京东电商平台手机推荐系统的设计与实现
  • 没有logo可以做网站的设计吗卡密网站怎么做
  • 做侵权视频网站网站规划问题
  • 鸿蒙:用Toggle组件实现选择框、开关样式
  • html css js网页制作成品——YSL口红红色 html+css (6 页)(老版)附源码