You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中WebSocket网络指标监控方案咨询

解决方案建议

一、自定义客户端埋点(最易快速实现)

直接在现有WebSocket代码里嵌入监控逻辑,自己记录关键指标:

  • 发送消息时记录发送时间戳,同时计算payload的字节大小;
  • 收到服务器消息时,计算当前时间与对应发送时间的差值,得到往返响应时间;
  • 把这些数据打印到控制台或写入本地日志,方便后续分析。

示例修改代码:

// 存储每个消息的发送时间(假设消息为可哈希的数值类型)
final Map<num, int> _messageSendTimes = {};

void emitMessage(num numValue) {
  // 记录毫秒级发送时间戳
  _messageSendTimes[numValue] = DateTime.now().millisecondsSinceEpoch;
  // 计算payload字节大小
  final payloadSize = utf8.encode(numValue.toString()).length;
  print('Sent: $numValue | Payload Size: ${payloadSize}bytes');
  channel!.sink.add(numValue);
}

// 修改消息监听逻辑
channel.stream.listen((message) {
  final numMessage = num.parse(message.toString());
  final sendTime = _messageSendTimes.remove(numMessage);
  if (sendTime != null) {
    final roundTripTime = DateTime.now().millisecondsSinceEpoch - sendTime;
    final payloadSize = utf8.encode(message.toString()).length;
    print('Received: $message | Payload Size: ${payloadSize}bytes | RTT: ${roundTripTime}ms');
  }
  print('Received: $message');
  channel!.sink.add(message);
});

二、封装WebSocket监控类(更优雅解耦)

把监控逻辑封装成独立类,避免污染业务代码:

class MonitoredWebSocketChannel {
  final IOWebSocketChannel _channel;
  final Map<String, int> _messageTimestamps = {};

  MonitoredWebSocketChannel(this._channel);

  Stream<dynamic> get stream => _channel.stream.transform(StreamTransformer.fromHandlers(
    handleData: (data, sink) {
      final timestamp = _messageTimestamps.remove(data.toString());
      if (timestamp != null) {
        final rtt = DateTime.now().millisecondsSinceEpoch - timestamp;
        final size = utf8.encode(data.toString()).length;
        print('WebSocket | RTT: ${rtt}ms | Payload Size: ${size}bytes');
      }
      sink.add(data);
    },
  ));

  void send(dynamic message) {
    _messageTimestamps[message.toString()] = DateTime.now().millisecondsSinceEpoch;
    final size = utf8.encode(message.toString()).length;
    print('WebSocket | Sent: $message | Size: ${size}bytes');
    _channel.sink.add(message);
  }
}

// 使用方式
final monitoredChannel = MonitoredWebSocketChannel(IOWebSocketChannel.connect('ws://127.0.0.1:3000/ws/$client_id'));
// 发送消息
monitoredChannel.send(numValue);
// 监听消息
monitoredChannel.stream.listen((message) {
  print('Received: $message');
  monitoredChannel.send(message);
});

三、后端配合监控(交叉验证数据)

在FastAPI的WebSocket端点加入日志,记录消息的接收/发送时间,和客户端数据交叉验证,得到更准确的单向延迟:

from fastapi import WebSocket, WebSocketDisconnect
import time

@app.websocket("/ws/{client_id}")
async def websocket_endpoint(websocket: WebSocket, client_id: str):
    await websocket.accept()
    try:
        while True:
            data = await websocket.receive_text()
            receive_time = time.time() * 1000  # 毫秒级时间戳
            print(f"[{client_id}] Received: {data} | Time: {receive_time:.0f}ms")
            
            # 你的循环计数逻辑
            # ...
            
            send_time = time.time() * 1000
            await websocket.send_text(data)
            print(f"[{client_id}] Sent: {data} | Time: {send_time:.0f}ms | Processing Delay: {send_time - receive_time:.0f}ms")
    except WebSocketDisconnect:
        print(f"Client {client_id} disconnected")

四、系统级抓包工具(获取底层网络数据)

如果需要更全面的指标(比如握手延迟、帧碎片、底层传输耗时),可以用抓包工具:

  • Android:用tcpdump命令抓包,导出后用Wireshark分析,过滤websocket协议即可查看所有帧的时间、大小;
  • iOS:使用Xcode的Network Instrument工具直接监控WebSocket流量;
  • 桌面端:用Wireshark监听本地网卡,过滤tcp port 3000捕获WebSocket通信。

内容的提问来源于stack exchange,提问作者CrimsonDay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 21:10:08