答案
Whistle 提供了 WebSocket 代理功能,可以捕获、调试和修改 WebSocket 连接和消息。
WebSocket 代理基础
1. 基本 WebSocket 代理
配置规则:
shellws://example.com host 127.0.0.1:8080 wss://example.com host 127.0.0.1:8080
或者使用 forward 操作符:
shellws://example.com forward ws://127.0.0.1:8080 wss://example.com forward wss://127.0.0.1:8080
2. WebSocket 消息捕获
Whistle 会自动捕获 WebSocket 连接和消息:
- 连接建立:记录 WebSocket 握手信息
- 消息发送:记录客户端发送的消息
- 消息接收:记录服务器返回的消息
- 连接关闭:记录连接关闭原因
WebSocket 调试功能
1. 查看消息详情
在 whistle 管理界面中:
- 点击 "Network" 标签
- 筛选 "WS" 类型的请求
- 点击 WebSocket 连接查看详情
- 查看 "Messages" 标签中的消息历史
2. 消息格式化
Whistle 会自动格式化 JSON 消息:
json{ "type": "message", "data": { "id": 1, "content": "Hello" } }
3. 消息过滤
可以使用过滤器快速查找特定消息:
- 按消息类型过滤
- 按消息内容搜索
- 按时间范围过滤
WebSocket 消息修改
1. 使用插件修改消息
创建插件:websocket-modifier.js
javascriptmodule.exports = function(server, options) { server.on('upgrade', function(req, socket, head) { console.log('WebSocket upgrade:', req.url); }); server.on('connection', function(ws, req) { ws.on('message', function(message) { console.log('Received message:', message.toString()); // 修改消息 const modifiedMessage = modifyMessage(message); ws.send(modifiedMessage); }); }); }; function modifyMessage(message) { const data = JSON.parse(message.toString()); data.timestamp = Date.now(); return JSON.stringify(data); }
配置规则:
shellws://example.com plugin://websocket-modifier
2. 拦截和修改握手
创建脚本:websocket-handshake.js
javascriptmodule.exports = function(req, res) { // 修改 WebSocket 握手头 if (req.headers['upgrade'] === 'websocket') { req.headers['X-Custom-Header'] = 'Custom Value'; } };
配置规则:
shellws://example.com reqScript://{websocket-handshake.js}
WebSocket 性能监控
1. 连接时间监控
Whistle 会记录 WebSocket 连接的各个阶段时间:
- DNS 解析时间
- TCP 连接时间
- SSL/TLS 握手时间(对于 wss)
- 连接建立时间
2. 消息统计
- 消息数量:发送和接收的消息总数
- 消息大小:消息的平均大小和总大小
- 消息频率:消息发送和接收的频率
3. 连接状态监控
- 连接状态:连接是否活跃
- 连接时长:连接持续时间
- 重连次数:连接重连的次数
WebSocket 调试技巧
1. 模拟服务器响应
创建脚本:websocket-mock.js
javascriptmodule.exports = function(server, options) { server.on('upgrade', function(req, socket, head) { console.log('Mock WebSocket server'); // 模拟服务器行为 socket.on('data', function(data) { console.log('Client message:', data.toString()); // 返回模拟响应 const response = JSON.stringify({ type: 'response', data: 'Mock response', timestamp: Date.now() }); socket.write(response); }); }); };
2. 消息延迟模拟
创建脚本:websocket-delay.js
javascriptmodule.exports = function(server, options) { server.on('connection', function(ws, req) { ws.on('message', function(message) { // 模拟延迟 setTimeout(() => { ws.send(message); }, 1000); // 延迟 1 秒 }); }); };
3. 消息丢失模拟
创建脚本:websocket-drop.js
javascriptmodule.exports = function(server, options) { let messageCount = 0; server.on('connection', function(ws, req) { ws.on('message', function(message) { messageCount++; // 每 10 条消息丢弃 1 条 if (messageCount % 10 !== 0) { ws.send(message); } else { console.log('Dropped message:', messageCount); } }); }); };
常见问题解决
1. WebSocket 连接失败
检查项:
- 确认代理规则正确
- 检查目标服务器是否支持 WebSocket
- 确认防火墙设置
- 检查 SSL 证书(对于 wss)
2. 消息乱码
解决方法:
- 确认消息编码格式
- 检查消息是否为二进制数据
- 使用正确的解码方式
3. 连接频繁断开
原因:
- 网络不稳定
- 服务器超时设置
- 心跳机制问题
解决方法:
- 增加超时时间
- 实现心跳机制
- 优化网络环境
最佳实践
-
使用插件进行复杂处理
- 插件提供更强大的功能
- 便于复用和维护
-
记录消息日志
- 便于问题排查
- 分析消息模式
-
测试异常场景
- 测试网络中断
- 测试消息丢失
- 测试连接超时
-
性能优化
- 减少不必要的消息处理
- 使用消息压缩
- 优化消息格式