25、信令服务器测试:使用 WebSocket 客户端模拟信令交互,验证信令服务器逻辑。
信令服务器,说白了就是 WebRTC 的“调度中心”。
它不负责传音视频数据,但负责帮两个 Peer 牵线搭桥。如果信令服务器挂了,或者逻辑有 bug,那你的 WebRTC 应用根本跑不起来。我见过不少团队,花大把时间调音视频质量,结果发现是信令层在丢消息——这种坑,踩一次就记住了。
所以,今天咱们聊聊怎么用 WebSocket 客户端模拟信令交互,把信令服务器的逻辑测透。
为什么需要模拟信令交互?
你想想看,信令服务器本质上就是个消息中转站。它接收客户端的 SDP、ICE Candidate,然后转发给对端。逻辑本身不复杂,但容易出问题的点在于:
- 消息格式对不对? 比如 JSON 字段名拼错了,或者类型不对。
- 房间管理有没有 bug? 两个人能不能正确加入同一个房间?第三个人进来会怎样?
- 异常情况怎么处理? 比如客户端中途断连,或者发了个非法消息。
这些问题,靠浏览器跑完整 WebRTC 流程来测,效率太低了。你每次都要打开两个页面,点按钮,看日志…… 我个人习惯是,先用 WebSocket 客户端模拟信令交互,把核心逻辑跑通,再上浏览器集成测试。
测试环境准备
我们需要一个 WebSocket 客户端工具。我推荐用 wscat(Node.js 命令行工具)或者 WebSocket King(浏览器插件)。
安装 wscat 很简单:
npm install -g wscat
然后连接你的信令服务器:
wscat -c ws://localhost:8080
连接成功后,你就可以手动发送 JSON 消息了。
核心测试场景
我一般会按以下顺序测试,从简单到复杂:
1. 连接与心跳
先确认 WebSocket 能连上,并且服务器会回复心跳。比如:
// 客户端发送
{"type": "ping"}
// 期望服务器回复
{"type": "pong"}
嗯,这一步看似简单,但能快速发现网络问题或服务器没启动。
2. 创建房间与加入房间
模拟两个客户端,一个创建房间,一个加入房间。
客户端 A:
{"type": "create-room", "roomId": "test123"}
期望回复:
{"type": "room-created", "roomId": "test123"}
客户端 B:
{"type": "join-room", "roomId": "test123"}
期望回复:
{"type": "room-joined", "roomId": "test123"}
同时,客户端 A 应该收到一条通知:
{"type": "peer-joined", "peerId": "clientB"}
我曾经遇到过一个问题:服务器在创建房间时,忘记把创建者加入房间成员列表。结果客户端 A 永远收不到 peer-joined 消息。这种 bug 用模拟测试一测就现形。
3. SDP 与 ICE 转发
这是信令的核心功能。模拟客户端 A 发送 SDP offer:
{
"type": "sdp",
"to": "clientB",
"sdp": "v=0\no=- 123456 2 IN IP4 127.0.0.1\ns=-\nt=0 0\n..."
}
期望客户端 B 收到:
{
"type": "sdp",
"from": "clientA",
"sdp": "v=0\no=- 123456 2 IN IP4 127.0.0.1\ns=-\nt=0 0\n..."
}
ICE Candidate 同理:
{
"type": "ice-candidate",
"to": "clientB",
"candidate": "candidate:1 1 UDP 2122252543 192.168.1.1 54321 typ host"
}
这里要注意:消息中的 to 字段必须正确。我见过一个 bug,服务器把 to 和 from 搞反了,结果 A 发的 offer 又回到了 A 自己手里……
4. 异常场景测试
光测正常流程不够,还得测异常。我习惯用以下用例:
- 加入不存在的房间: 应该返回错误消息,而不是崩溃。
- 重复加入同一房间: 服务器应该拒绝,或者给出明确提示。
- 发送非法 JSON: 服务器应该优雅地断开连接,而不是挂掉。
- 客户端断连: 服务器应该通知房间内其他成员。
举个例子,测试加入不存在的房间:
// 客户端发送
{"type": "join-room", "roomId": "nonexistent"}
// 期望回复
{"type": "error", "message": "Room not found"}
如果服务器直接返回 200 OK 或者没反应,那就有问题了。
自动化测试脚本
手动测几次还行,但每次改完代码都要重测,那就太累了。我建议写个简单的自动化脚本,用 Node.js 的 ws 库来模拟多个客户端。
下面是一个示例脚本,模拟两个客户端完成一次完整的信令交互:
const WebSocket = require('ws');
function createClient(name) {
const ws = new WebSocket('ws://localhost:8080');
ws.on('open', () => {
console.log(`${name} connected`);
});
ws.on('message', (data) => {
console.log(`${name} received:`, data.toString());
});
return ws;
}
// 模拟客户端 A 和 B
const clientA = createClient('ClientA');
const clientB = createClient('ClientB');
// 等待连接建立
setTimeout(() => {
// A 创建房间
clientA.send(JSON.stringify({type: 'create-room', roomId: 'auto-test'}));
}, 1000);
setTimeout(() => {
// B 加入房间
clientB.send(JSON.stringify({type: 'join-room', roomId: 'auto-test'}));
}, 2000);
setTimeout(() => {
// A 发送 SDP offer
clientA.send(JSON.stringify({
type: 'sdp',
to: 'ClientB',
sdp: 'fake-sdp-offer'
}));
}, 3000);
setTimeout(() => {
// B 发送 SDP answer
clientB.send(JSON.stringify({
type: 'sdp',
to: 'ClientA',
sdp: 'fake-sdp-answer'
}));
}, 4000);
这个脚本跑起来,你就能看到完整的消息流转。如果哪一步没收到预期回复,那就是 bug。
信令测试的核心逻辑图
下面这张图,展示了一次典型的信令交互流程。我把它画出来,方便你对照测试:
测试结果验证
测试完了,怎么判断信令服务器逻辑对不对?我列个检查清单:
| 测试项 | 预期结果 | 常见失败原因 |
|---|---|---|
| 连接与心跳 | 收到 pong 回复 | 服务器未启动、端口错误 |
| 创建房间 | 返回 room-created | 房间 ID 重复、数据库写入失败 |
| 加入房间 | 双方收到通知 | 房间不存在、成员列表未更新 |
| SDP 转发 | 对端收到完整 SDP | 消息格式错误、to 字段错误 |
| ICE 转发 | 对端收到 candidate | candidate 字段缺失、序列化错误 |
| 异常消息 | 返回 error 或断开 | 服务器未做校验、异常未捕获 |
核心原则:信令服务器的测试,重点不是性能,而是消息的完整性和正确性。每条消息都必须被正确转发,不能丢,不能错,不能乱序。
我的小技巧:在信令服务器里加一个“消息日志”功能,把每个 WebSocket 连接收发的消息都打印出来。测试时对照日志,一眼就能看出问题出在哪一步。
注意:不要在生产环境直接测试!用本地或测试环境的信令服务器。我曾经手滑在线上环境发了个非法消息,导致服务器重启…… 嗯,从那以后我学乖了。
好了,用 WebSocket 客户端模拟信令交互,说白了就是手动扮演两个 Peer,看服务器能不能正确传话。这个方法简单、高效,能帮你把信令层的 bug 扼杀在摇篮里。等你把这一套跑熟了,再去集成 WebRTC 的完整流程,会顺畅很多。
公众号:蓝海资料掘金营,微信deep3321