这个项目算是我自己探索实时通信技术的一个记录。一开始我的目标很简单:就是想用 Node.js 和原生的 WebSocket 从零搭一个聊天室,不想用 Socket.IO 这种把底层细节都藏起来的库。
后来,聊天室做完了,我就想能不能更进一步,加上视频直播?于是我开始研究 WebRTC,最终把这两者结合了起来。下面就是这个应用跑起来的样子:
- 实时音视频直播: 基于 WebRTC,主播可以将摄像头和麦克风的画面实时推给观众。
- 视频弹幕浮层: 聊天信息会像弹幕一样,优雅地浮现在视频画面之上。
- 角色区分: 分为主播和观众两种角色,拥有不同的界面和权限。
- 房间系统: 主播可以创建房间,观众可以从列表选择并加入。
- 实时聊天互动:
- 主播和观众可以进行双向文字聊天。
- “正在输入”状态提示。
- 主播可以发布全局公告。
- 在线状态显示: 实时显示房间内的在线用户数和用户列表。
- 连接稳定性:
- 客户端拥有断线自动重连机制。
- 服务器拥有心跳检测,能自动清理无效连接。
- 基础安全:
- 对聊天消息的发送频率进行限制,防止刷屏。
- 对用户输入内容进行 HTML 转义,防御 XSS 攻击。
- WebRTC 与 WebSocket 的协同工作: 项目清晰地展示了两种技术的黄金搭档关系。WebSocket 轻量、高效,非常适合作为信令服务器,用于交换建立连接所需的信息;而 WebRTC 则专注于处理点对点的音视频流,服务器无需承担高昂的流量成本。
- 原生 API 的运用: 坚持使用浏览器原生的
WebSocketAPI 和 Node.js 的ws库,而不是封装好的库。这让我能更深入地理解协议的细节,比如手动实现心跳和消息的 JSON 序列化。
主播可以创建直播间,应用会请求摄像头和麦克风权限,并将实时画面通过 WebRTC 推送给所有观众。观众加入后,就能看到主播的音视频流。
| 主播端视角 | 观众端视角 |
|---|---|
![]() |
![]() |
在看直播的同时,观众和主播可以实时聊天。聊天内容直接覆盖在视频上,并且清晰可读。
| 1. 选择身份 | 2. 观众选择房间 | 3. 观看直播 | 4. 直播结束 |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
你需要先安装 Node.js 和 npm。
-
把项目克隆到本地:
git clone https://github.com/535601882/WebSocket-example.git cd WebSocket-example -
安装依赖:
npm install
-
启动服务器:
node server.js
看到提示“服务器已启动,正在监听 http://localhost:3000”,就说明成功了。
-
打开 App: 在浏览器里打开
http://localhost:3000。 -
试试看:
- 打开一个浏览器标签页,选择“我是主播”。
- 点击按钮开始直播。这时浏览器会请求摄像头和麦克风权限,一定要点“允许”。
- 再打开一个(或多个)标签页,选择“我是观众”。
- 你应该能看到主播的房间,点击加入,稍等片刻就能看到视频了。
* 获取用户媒体:通过navigator.mediaDevices.getUserMedia获取用户的摄像头和麦克风。
* 创建PeerConnection:创建一个新的RTCPeerConnection对象。
* 添加媒体流:将获取到的媒体流添加到PeerConnection中。
* 创建Offer:创建一个Offer,并通过信令服务器发送给对方。
* 设置本地描述:将创建的Offer设置为本地描述。
* 处理Answer:接收对方的Answer,并将其设置为远端描述。
* 创建PeerConnection:同样需要创建一个新的RTCPeerConnection对象。
* 接收Offer:通过信令服务器接收对方的Offer。
* 创建Answer:创建一个Answer,并通过信令服务器发送给对方。
* 设置本地描述:将创建的Answer设置为本地描述。
* 处理媒体流:接收对方的媒体流,并将其展示在网页上。
这毕竟只是个学习项目,离真正的线上产品还有距离。下面这些是我想到的问题和未来可以做的事:
- 需要 TURN 服务器: WebRTC 在本地网络里跑得很顺畅,但要是在复杂的公网环境(比如用户在不同的路由器后面),就需要一个 TURN 服务器来帮忙转发视频流量。这个项目里我还没配置。
- 没有正经的用户系统: 现在的用户名都是随机生成的,下一步可以加上真正的登录注册功能。
- 聊天记录不保存: 聊天消息是临时的,一刷新就没了。
希望这个项目能让你觉得有点意思。对我来说,这是一个搞懂直播技术背后原理的有趣过程。




