跳转到内容

移动端与大屏交互 ​

本节说明移动端如何与大屏配对、建立长连接,以及提问/回答的完整链路。


一、移动端配对(ScanPair.vue) ​

  • 扫码自动配对:onMounted 时同时兼容 history 模式(?code= 在 search)与 hash 模式(#/mobile?code= 在 hash);
  • 手动输入:12 位上限,回车提交;
  • 错误分型:invalid(码错误/无效/不存在)、expired(过期)、network(网络/连接)、validation(未输入),各自配不同图标、配色与处理建议;invalid/expired 提供"重新配对"按钮;
  • 自动配对失败会 replaceState 清掉 URL 上的 code,避免刷新后反复用失效码触发连接而一直转圈;
  • 配对超时保护 5 分钟(usePairing)。

大屏侧的配对码生成与设备管理见 配对码功能。


二、WebSocket 通道 ​

{ws|wss}://{VITE_AI_APP_HOST}/ws/digital-human
  ?clientType=screen|mobile&clientId=xxx[&pairingCode=xxx]
  • 协议随页面协议自动切换(https → wss);
  • 心跳 30 秒 一次 HEARTBEAT_REQ;
  • 大屏端断线指数退避自动重连:最多 5 次,延迟 min(1000 × 2^n, 30000) ms。

消息类型:

type方向说明
SCREEN_REGISTER后端 → 大屏下发屏幕端 clientId
PAIRING_SUCCESS后端 → 双端携带 { deviceIp, deviceName, userAgent, pairedAt }
PAIRING_FAIL后端 → 手机断开并提示原因
COMMAND手机 → 大屏{ text, type: 'text'|'voice', mode, knowledgeCategory? }
RESPONSE大屏 → 手机字符串 / { text } / { error } / { text, subtype:'search', searchResult }
DISCONNECT后端 → 双端携带原因
KICKED后端 → 手机被大屏踢出,弹提示后 store.reset() 回到扫码页
HEARTBEAT_REQ / HEARTBEAT_RESP双向保活

模式同步采用 piggyback:移动端不发送独立的 MODE_CHANGE 消息,而是把 mode 挂在 COMMAND 载荷里,大屏收到后先 setMode 再处理。


三、移动端遥控面板(RemotePanel.vue) ​

仿微信对话布局,MobileEntry.vue 在 isPaired && isConnected 时切换到面板,否则显示扫码页。

  • 顶部:连接状态灯 + 模式切换下拉(智能交互 / 专家问答 / 系统导览)+ 断开连接(二次确认);
  • 消息区:AI Markdown 气泡 / 用户气泡 / 系统提示 + "大屏回复中…"等待气泡,消息与等待态变化均自动滚底;
  • 底部 ChatInputBar:文本输入(500 字上限,回车发送)/ 按住说话,错误以 toast 层展示;
  • 右下角 Fab + 左侧抽屉,两种形态:
    • 系统导览 → "演示问题"抽屉(复用大屏端 demoList,点击即发送);
    • 智能交互 / 专家问答 → "猜你想问"(支持换一批)/ "选择知识库"抽屉;
  • 三种模式均显示输入栏(系统导览支持自由输入,与大屏端行为对齐);
  • 切出系统导览自动关闭演示抽屉,切到系统导览自动关闭猜你想问抽屉;
  • 高度使用 100dvh 兼容移动端地址栏伸缩,顶部/底部预留 env(safe-area-inset-*) 安全区。

四、移动端问答链路 ​

手机 COMMAND → 大屏 handleMobileCommand → 按当前模式走 interactive / expert / demo 分支 → 大屏渲染回答并 TTS 播报 → RESPONSE 回推手机渲染。系统导览的自定义问题不重复走内置问答,回复由 NLU 回调通过 resolveMobileDemoAnswer 回传。

实现位置:移动端指令处理、RESPONSE 回推与配对相关逻辑都在 core/connection.js(拆分前位于 useAssistantCore.js)。

数字人「小慧」项目文档