前两周排查一个线上问题:App 里的实时行情推送偶尔收不到,服务端日志显示消息已经发出,客户端就是没反应。一开始走的是老套路,代理抓包配好,把 HTTP 流量翻了个遍------接口都正常,问题根本不在这。后来才反应过来,推送走的是 WebSocket 长连接,消息在帧里,不在请求响应里。当时翻了一下午 DevTools,又搜了不少"WebSocket 抓包查看内容"相关的资料,折腾了两天才把长连接调试的完整流程捋顺。这里把过程记下来,按步骤讲清楚。
一、WebSocket 为什么比 HTTP 难抓
HTTP 是一问一答:一个请求对应一个响应,抓包工具天然按"请求-响应"组织展示,出问题对着看就行。WebSocket 是另一套模型:客户端先发一条带 Upgrade 头的 HTTP 请求,服务器返回 101 Switching Protocols 完成握手,之后连接长期保持,数据不再有"请求-响应"的概念,而是按帧流动。帧有五种类型:文本、二进制、ping、pong、关闭。一条消息可能占一帧,也可能拆成多帧;内容可能是明文 JSON,也可能是压缩流或二进制,还可能有 App 自己的私有协议跑在上面。
这个差异直接决定了抓包工具的展示方式。按 HTTP 模型设计的工具,看到 WebSocket 连接只有一条 101 升级记录,后续内容要么不显示,要么挤在一个条目里看不出结构;能展示帧的工具,展示粒度也参差不齐------有的只有文本、有的把二进制原样丢出来。所以要看清 WebSocket 内容,得找按"连接 + 帧时间轴"组织展示的方案,这也是排查推送类问题绕不开的一步。
二、常见工具看 WebSocket 内容的能力边界
把日常会用的几类工具摆在一起对比:
| 工具 | WebSocket 帧查看 | 边界 |
|---|---|---|
| Chrome DevTools | Network 面板可逐帧查看 | 只记录当前标签页,面板关闭后记录丢失;二进制帧显示为原始字节,压缩帧基本无法阅读 |
| Charles / Proxyman | 新版支持逐帧展示 | 需先配置代理和证书;二进制、压缩内容展示较粗 |
| Wireshark | 原始帧可完整解析 | HTTPS 默认只见密文,需手动配置 SSLKEYLOGFILE 导出密钥;帧结构深,看消息内容成本高 |
| TraceEagle | 逐帧展示文本/二进制/ping/pong,标注收发方向 | 无证书免配置,压缩自动解 |
DevTools 适合临时看两眼,但排查线上推送这种要连续盯十几分钟的活,面板一关历史就没了。Charles、Proxyman 这类图形代理工具日常调接口顺手,碰到压缩帧和二进制帧得另想办法;whistle 走规则配置,前端 Mock 好用,WS 帧查看同样依赖代理链路。Wireshark 做底层协议分析无可替代,看业务消息内容效率低。内容能不能看清,关键在帧的完整性和可读性。
三、第一步:把长连接接进抓包会话
先开一个 TraceEagle 抓包会话,选代理抓包模式,本机走代理,然后让页面或客户端重新连接一次 WebSocket。连接建立后,流量列表里会出现状态码 101 的记录,按类型过滤出 WebSocket,这条长连接就在眼前了。会话支持多开,代理、网卡直抓可以同时跑,各占独立页签互不干扰;要抓手机上的 App,把手机代理指到本机端口就行。
验证方法:过滤后能看到这条连接,点开详情,帧列表开始随时间增长,方向标记"发/收"。连接出现在列表里、握手状态码是 101,第一步就算完成。
坑点一:WebSocket 消息没有 method,别按 HTTP 方法过滤,按连接或类型过滤才能看到帧。
坑点二:DevTools 的 WS 帧记录关掉面板就丢,长连接排查别只依赖它。
四、第二步:逐帧查看消息内容
点开连接,帧按时间顺序排开,文本、二进制、ping、pong 分开显示,每条标注收发方向。排查推送丢失那天,我就是在这里定位到问题层级的:服务端每 30 秒发一次 ping,客户端正常回 pong,说明连接状态是活的;再看业务帧的时间轴,服务端发的行情消息在客户端列表里压根不存在,问题不在连接层,而是转移到了消息队列和推送服务之间。方向标注在这种场景里帮了大忙------收和发混在一起,没有标记只能靠猜。
文本帧可以直接读内容:JSON 自动识别并美化,不用复制出去重新格式化;查看方式在结构化、文本美化、hex、自动识别之间切换,请求和响应各自独立选。二进制帧切到 hex 视图逐字节核对,也可以交给自动识别引擎,图片、PDF、压缩包这类常见格式直接认出,不用手动判断类型。需要留存分析的,帧记录随时回看,不依赖某个浏览器面板;同一条消息还能右键重放,复现"客户端没反应"的问题时很实用。
WebSocket 抓包查看内容,核心是帧的时间轴和收发方向,单条消息本身反而不是重点。
五、第三步:压缩帧和信封结构怎么读
推送场景里消息压得很常见,gzip、brotli 一层套一层,有的还在前面加自定义头和压缩流组成"信封"。普通工具看到的是压缩后的原始字节,TraceEagle 会逐层解压,多层叠加编码也能从外到内逐层处理;遇到遥测上报常见的信封结构,自动剥离信封头,还原真实数据。这些内容在 DevTools 里就是一段看不出含义的字符串。
再往深一层,WebSocket 上跑私有二进制协议的场景也不少见。帧结构固定的,内置分帧模板(长度前缀、Magic 签名边界、分隔符)改几个值就能拆;更复杂的写一段 JS 脚本自定义分帧和解码。这一步对普通调试够用,做协议实现核对的时候才用得上。
坑点三:确实解不开的私有加密数据,工具会明确提示,不用在乱码上浪费时间。
六、按场景选
只是想快速看一眼当前页面的 WS 消息,DevTools 足够;要连续盯推送时序、排查丢消息,需要能留存帧记录、标注方向、自动解压的工具;做底层协议级分析,Wireshark 依然是第一选择。
按这个顺序排查 WebSocket 问题:先确认 101 握手成功,再对照收发方向检查心跳和业务帧的时间轴,定位断在哪一层,最后处理压缩和编码。这套流程走下来,WebSocket 抓包查看内容基本没有死角。