Maestro Web/Mobile 前端实现全解:React SPA 远程控制界面设计与最佳实践
【免费下载链接】MaestroAgent Orchestration Command Center项目地址: https://gitcode.com/GitHub_Trending/maestro41/Maestro
Maestro的 Web/Mobile 前端是一套独立的React SPA 远程控制界面,让你用手机或平板通过局域网实时查看并指挥桌面上的 Agent 会话。它由 Electron 主进程内置的 Fastify Web 服务托管,基于 WebSocket 实时通信,配合 Service Worker 实现离线命令队列。本文将完整解析它的架构、目录组织、安全令牌设计与移动端交互模式。
一、整体架构:一个 React SPA + 一个内嵌 Web 服务
Maestro 的 Web 端与桌面渲染进程是两个独立的 React 应用:桌面端通过 Electron IPC 与主进程通信,而 Web 端通过HTTP + WebSocket与主进程中内嵌的 Web 服务通信。
- 服务端:Fastify +
@fastify/websocket、@fastify/cors、@fastify/rate-limit、@fastify/static,见 WebServer.ts - 客户端:
src/web/下的 React SPA,通过 Vite 单独构建 - 实时通道:REST API(
/$TOKEN/api/*)处理一次性操作,WebSocket(/$TOKEN/ws)推送会话状态、日志与主题
Cue 流水线等高级功能同样可以通过这个远程控制界面查看:
💡 完整架构文档见官方指南:WEB-MOBILE.md
二、目录结构速览:src/web 如何组织
Web 前端源码位于 src/web/,分层非常清晰:
| 目录 | 职责 |
|---|---|
| src/web/components/ | 共享 UI 组件(Button、Badge、Card、ThemeProvider 等) |
| src/web/hooks/ | 核心逻辑 Hooks(WebSocket、会话管理、手势、离线队列等 20+ 个) |
| src/web/mobile/ | 移动端专属组件(约 40 个:命令输入栏、会话网格、终端等) |
| src/web/utils/ | 配置读取、Service Worker、本地视图状态持久化 |
入口文件 main.tsx 仅负责挂载根组件;根组件 App.tsx 负责提供三个关键 Context:离线状态(OfflineContext)、导航模式(MaestroModeContext,区分仪表盘与单会话视图)和主题同步(桌面端主题经 WebSocket 推送到手机端)。
三、安全设计:URL 令牌是远程控制的第一道门
远程控制最怕的就是"被陌生人打开"。Maestro 的方案非常克制且有效:
- 每次启动 Web 服务时生成一个UUID 安全令牌,并随机分配端口
- 令牌直接嵌入 URL 路径:
http://局域网IP:端口/$令牌/(仪表盘)或.../$令牌/session/$会话ID(单会话) - 所有 API 与 WebSocket 请求都必须携带该令牌,缺失或错误的令牌直接被拒绝
- 配置由服务端注入到
window.__MAESTRO_CONFIG__,前端通过 config.ts 中的getMaestroConfig()读取
这意味着知道链接的人才能控制你的 Agent——无需账号体系,令牌即身份。想固定端口用于防火墙或反向代理,可在 Live 面板开启 Custom Port(详见 remote-control.md)。
四、实时通信:useWebSocket 与 useSessions 双 Hook
前端实时能力的核心是两层 Hook:
- useWebSocket.ts:管理连接生命周期(
disconnected → connecting → connected → authenticated),定义SessionData数据模型(会话状态、AI 多标签页、用量统计、最后回复预览等),并在断线时自动重连(指数退避) - useSessions.ts:在连接之上封装高层操作——发送命令、中断会话、切换 AI/终端模式、标签页增删切换,会话还按 Group 分组展示
为省流量,服务端对最后回复做了截断预览(前 3 行或约 500 字符),手机端只在小屏上展示摘要,完整内容留在桌面端。
五、断网不慌:离线命令队列 + PWA 离线支持
这是整个 Web 端最"工程化"的部分之一:
- 离线队列(useOfflineQueue.ts):断网期间输入的命令会入队,持久化到
localStorage(最多 50 条,刷新页面不丢失);恢复连接后以 100ms 间隔逐条自动补发,支持手动重试与清空 - Service Worker(serviceWorker.ts):缓存静态资源实现 PWA 离线加载,并配合
isOffline()检测驱动全局离线 UI - 未读角标(useUnreadBadge.ts):浏览器标签页实时显示未读回复数,Agent 出结果时不用盯屏幕
📱 手机上断网时界面会显示
OfflineQueueBanner横幅,清晰提示队列状态——这是移动端容错体验的关键细节。
六、移动端 UX 模式:手势、触觉反馈与通知
MobileApp 入口 将 40 来个组件组织成完整的移动端体验,几个值得一提的模式:
- 手势导航:左右滑动切换会话(useSwipeGestures.ts)、上滑展开历史、下拉刷新、长按弹出上下文菜单(AI ↔ 终端模式切换)
- 触觉反馈:通过
navigator.vibrate()提供轻触/成功/错误三种振动模式(constants.ts) - 语音输入:基于 Web Speech API 的 useVoiceInput.ts,解放双手
- 浏览器推送通知:useNotifications.ts 请求系统通知权限,会话完成即推送
- 虚拟键盘适配:useKeyboardVisibility.ts 感知软键盘弹出并调整布局
实际效果——手机上的聊天视图:
七、快速开启远程控制:三步上手
- 在桌面端左侧栏点击OFFLINE按钮,按钮变为LIVE并弹出二维码
- 手机扫码(或复制带令牌的 URL),即可访问仪表盘查看全部 live 会话
- 需要外网访问?在 Live 面板开启Remote Control,约 30 秒生成 Cloudflare 隧道 URL,无需账号、无时限
Web 端本地开发可运行npm run dev:web,桌面端与 Web 端共享 src/shared/ 下的类型与工具,保证两端行为一致。
总结
Maestro 的 Web/Mobile 前端用一套React SPA + WebSocket + URL 令牌的轻量方案,解决了"随时随地指挥 AI Agent"的核心问题:独立于桌面端构建、令牌即权限、离线队列兜底、移动端手势与触觉完整覆盖。它麻雀虽小五脏俱全,是学习"桌面应用如何做安全远程控制界面"的优质参考——核心源码都在 src/web/ 与 src/main/web-server/ 中,欢迎深入阅读。
【免费下载链接】MaestroAgent Orchestration Command Center项目地址: https://gitcode.com/GitHub_Trending/maestro41/Maestro
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考