ws.binaryType = 'arraybuffer';
ws.onmessage = (e) => {
  if (typeof e.data === 'string') return onJson(e.data);
  return onBinary(e.data);
};

服务端改推 MessagePack,浏览器里 e.data 是 Blob,JSON.parse 报 Unexpected token 'o',十条消息全丢,控制台刷了十条同样的错。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。

原因不复杂,WebSocket 的 binaryType 默认是 blob,二进制帧到前端就是 Blob 对象而不是字符串。老代码默认所有消息都是文本,解析器里没有分支。

「二进制帧处理」排查到最后往往是很小的一处差异,前面那些复杂猜测可以先放一放。改完隔一天再看一次,当场正常不代表能稳住。

测试环境和线上的差别,往往就在版本号和那几行被忽略的配置上。线上出问题先对时间点,跟发布、备份、任务执行的时刻排一排,能省掉一半功夫。

日志级别临时调高可以,记得改回去,长期开着既占磁盘又掩盖真问题。

处理上按这个顺序:把 binaryType 设成 arraybuffer 拿到同步可读的字节;onmessage 里先判断 data 是 string 还是 ArrayBuffer;二进制走独立解析函数 和 JSON 分支分开;服务端用首字节或 type 字段区分两种帧。

改完只确认一件事:MessagePack 消息能正常解出对象 JSON 消息也不受影响 控制台没有解析错误。

作者 9823189