乐闻世界logo
搜索文章和话题

whistle 如何支持 WebSocket 代理和调试?

2月21日 16:27

答案

Whistle 提供了 WebSocket 代理功能,可以捕获、调试和修改 WebSocket 连接和消息。

WebSocket 代理基础

1. 基本 WebSocket 代理

配置规则:

shell
ws://example.com host 127.0.0.1:8080 wss://example.com host 127.0.0.1:8080

或者使用 forward 操作符:

shell
ws://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 管理界面中:

  1. 点击 "Network" 标签
  2. 筛选 "WS" 类型的请求
  3. 点击 WebSocket 连接查看详情
  4. 查看 "Messages" 标签中的消息历史

2. 消息格式化

Whistle 会自动格式化 JSON 消息:

json
{ "type": "message", "data": { "id": 1, "content": "Hello" } }

3. 消息过滤

可以使用过滤器快速查找特定消息:

  • 按消息类型过滤
  • 按消息内容搜索
  • 按时间范围过滤

WebSocket 消息修改

1. 使用插件修改消息

创建插件:websocket-modifier.js

javascript
module.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); }

配置规则:

shell
ws://example.com plugin://websocket-modifier

2. 拦截和修改握手

创建脚本:websocket-handshake.js

javascript
module.exports = function(req, res) { // 修改 WebSocket 握手头 if (req.headers['upgrade'] === 'websocket') { req.headers['X-Custom-Header'] = 'Custom Value'; } };

配置规则:

shell
ws://example.com reqScript://{websocket-handshake.js}

WebSocket 性能监控

1. 连接时间监控

Whistle 会记录 WebSocket 连接的各个阶段时间:

  • DNS 解析时间
  • TCP 连接时间
  • SSL/TLS 握手时间(对于 wss)
  • 连接建立时间

2. 消息统计

  • 消息数量:发送和接收的消息总数
  • 消息大小:消息的平均大小和总大小
  • 消息频率:消息发送和接收的频率

3. 连接状态监控

  • 连接状态:连接是否活跃
  • 连接时长:连接持续时间
  • 重连次数:连接重连的次数

WebSocket 调试技巧

1. 模拟服务器响应

创建脚本:websocket-mock.js

javascript
module.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

javascript
module.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

javascript
module.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. 连接频繁断开

原因:

  • 网络不稳定
  • 服务器超时设置
  • 心跳机制问题

解决方法:

  • 增加超时时间
  • 实现心跳机制
  • 优化网络环境

最佳实践

  1. 使用插件进行复杂处理

    • 插件提供更强大的功能
    • 便于复用和维护
  2. 记录消息日志

    • 便于问题排查
    • 分析消息模式
  3. 测试异常场景

    • 测试网络中断
    • 测试消息丢失
    • 测试连接超时
  4. 性能优化

    • 减少不必要的消息处理
    • 使用消息压缩
    • 优化消息格式
标签:Whistle