WebRTC 开发路线图
本文件用于规划和记录本仓库(WebRTC)的学习向开发计划与 TODO 列表。
定位: 本项目是一个基于 Go 的最小可用 WebRTC 示例项目,仅用于本地 Demo 和自我学习,不面向生产环境。
1. 项目定位与当前状态
- 名称:WebRTC
- 目标:
- 理解 WebRTC 一对一通话的基本流程(信令、ICE、媒体流)。
- 通过逐步扩展 Demo,学习常见的 WebRTC 能力(静音、屏幕共享、DataChannel、简单多人房间等)。
- 不涉及复杂生产级运维(高可用、监控、鉴权体系等)。
- 当前状态(初始版本):
- 已实现 Go 写的 WebSocket 信令服务(房间 + offer/answer/candidate 转发)。
- 已实现浏览器前端 Demo,可在同一房间内通过 ID 发起一对一通话。
- 项目结构清晰,适合做教学和自我学习的起点。
2. 开发阶段总览
为方便逐步学习,将开发拆成若干阶段,你可以按顺序推进,也可以根据兴趣跳读:
-
阶段 1:打磨一对一 Demo 体验
提升现有一对一通话 Demo 的体验与可读性,增加错误处理和状态展示。 -
阶段 2:学习更多 WebRTC 能力(可选,偏前端)
在当前一对一基础上增加静音/摄像头开关、屏幕共享、DataChannel 聊天、本地录制等能力。 -
阶段 3:房间与小规模多人通话(进阶)
引入房间成员列表和简单的 Mesh 多人通话,理解多人场景下连接数量和复杂度。 -
阶段 4:可选扩展(部署与网络)
简单尝试 TURN/HTTPS 和 Docker 打包,理解在不同网络环境下如何让 Demo 跑起来。
3. 阶段 1:打磨一对一 Demo 体验
目标:在不增加太多复杂度的前提下,让现有的一对一 Demo 更稳定、更易懂、更好用。
3.1 后端(Go 信令服务)
- 增加基础日志输出
在internal/signal/hub.go中:- WebSocket 升级失败时,打印请求路径和错误信息。
- 读取 JSON 消息失败时,打印错误并包含房间/客户端信息(若有)。
- 写入 JSON 失败时,同样记录日志,便于调试。
- 更稳健的连接清理
- 在
HandleWS的循环中,只要出现读/写错误,就调用removeClient,确保房间中不会残留“僵尸连接”。 - 在
removeClient中确认:当房间成员为空时删除该房间。
- 在
- (可选)简单心跳机制
- 前端每隔 N 秒发送一个
type: "ping"的消息。 - 后端可以选择忽略或返回一个
type: "pong",主要用于学习“保活”概念,不做复杂超时逻辑。
- 前端每隔 N 秒发送一个
3.2 前端(web/app.js + web/index.html)
- 连接与通话状态展示
- 在页面中增加一个状态文本区域,用来显示:
- “未连接”
- “已加入房间”
- “通话中”
- “已挂断”
- 在关键动作(join、呼叫成功、挂断)时更新状态文本。
- 在页面中增加一个状态文本区域,用来显示:
- 按钮状态管理
- 根据状态禁用/启用
Join / Call / Hangup按钮,避免误触。 - 例如:
- 未加入房间:只能点
Join。 - 已加入房间但未通话:可以点
Call,Hangup禁用。 - 通话中:
Call禁用,只能点Hangup。
- 未加入房间:只能点
- 根据状态禁用/启用
- 错误提示体验
getUserMedia被拒绝或失败时,在页面中展示简单提示(而不是静默失败)。- WebSocket 连接关闭或出错时,在页面提示“信令服务器连接已断开,请刷新页面或稍后重试”。
4. 阶段 2:学习更多 WebRTC 能力(可选)
目标:在不改动后端结构的前提下,通过前端尝试更多 WebRTC API,理解媒体轨道、屏幕共享、数据通道和录制。
4.1 媒体控制:静音与关闭摄像头
- 静音/取消静音
- 在页面增加一个
Mute / Unmute按钮。 - 通过操作
localStream.getAudioTracks()中 track 的enabled属性来实现静音。
- 在页面增加一个
- 关闭/打开摄像头
- 在页面增加一个
Camera On/Off按钮。 - 通过操作视频 track 的
enabled属性控制是否发送视频。
- 在页面增加一个
4.2 屏幕共享
- 基础屏幕共享
- 在页面添加一个
Share Screen按钮,使用navigator.mediaDevices.getDisplayMedia获取屏幕流。 - 将现有的摄像头视频轨道替换为屏幕共享轨道,或新增一个屏幕视频窗口。
- 在页面添加一个
4.3 DataChannel 文本聊天
- 简单文本聊天频道
- 在建立
RTCPeerConnection时,创建一个RTCDataChannel(例如命名为chat)。 - 在另一端通过
ondatachannel事件接收该通道。 - 在页面增加一个聊天输入框和消息显示区域,通过 DataChannel 发送/接收文本消息。
- 在建立
4.4 本地录制(MediaRecorder)
- 录制本地或远端流
- 使用
MediaRecorder对本地或远端的MediaStream进行录制。 - 提供“开始录制 / 停止录制”按钮,停止录制后生成 Blob 并提供下载链接(如
.webm文件)。
- 使用
5. 阶段 3:房间与小规模多人通话(进阶)
目标:理解多人房间的基本概念和复杂度,在 Demo 级别尝试 3–4 人的小房间。
5.1 房间成员列表
- 后端:广播房间成员
- 在
Hub中维护房间成员时,支持在有成员加入/离开时向房间内广播一个type: "room_members"的消息,内容为当前房间的成员 ID 列表。
- 在
- 前端:显示成员列表
- 在页面添加一个区域显示当前房间在线成员列表(显示成员 ID 即可)。
- 支持点击某个成员,将其 ID 自动填入
Remote ID输入框。
5.2 小规模 Mesh 多人通话(可选,难度稍高)
- 多 PeerConnection 管理
- 为每个远端成员创建一个单独的
RTCPeerConnection实例。 - 管理一张
remoteId -> pc的映射表,分别处理 offer/answer/candidate。
- 为每个远端成员创建一个单独的
- 多路视频布局
- 在页面中为每个远端成员添加一个
<video>元素,用来展示该成员的视频流。 - 简单实现网格布局,便于观察多人通话效果。
- 在页面中为每个远端成员添加一个
提示:
- Mesh 模式适合 3–4 人的小房间,用于学习很合适;
- 真正大规模多人场景通常会用 SFU,这里不做生产级接入,只做概念了解即可。
6. 阶段 4:可选扩展(部署与网络)
目标:在保持 Demo 定位的前提下,理解 TURN/HTTPS 和 Docker 打包的基本概念,方便在不同机器上演示。
- 基础 TURN 支持(可选)
- 搭建或使用一个简单的 TURN 服务器(例如 coturn)。
- 在前端
iceServers中增加 TURN 配置(注意不要在仓库中泄露真实凭证)。
- HTTPS / WSS(可选)
- 使用 Nginx/Caddy 等为本项目提供 HTTPS 反向代理,信令走
wss://。
- 使用 Nginx/Caddy 等为本项目提供 HTTPS 反向代理,信令走
- Docker 打包
- 编写多阶段
Dockerfile,包含 Go 服务与静态前端文件。 - 通过
docker build和docker run即可在其他机器上快速运行 Demo。
- 编写多阶段
7. 建议的实践顺序
如果你希望有一个推荐顺序,可以参考:
- 优先完成阶段 1:
- 让当前一对一 Demo 更稳定、可读,便于后面继续扩展。
- 按兴趣选择阶段 2 的能力点:
- 对媒体流和 UI 感兴趣:先做静音/摄像头/屏幕共享。
- 对数据传输感兴趣:优先做 DataChannel 聊天。
- 有精力再尝试阶段 3:
- 从“房间成员列表”开始,再尝试小规模 Mesh 多人通话。
- 阶段 4 完全可选:
- 仅在需要在局域网/公网演示时,才考虑 TURN/HTTPS 和 Docker。