必须显式调用send()发送数据,且仅支持string、ArrayBuffer、Blob等类型;传对象会静默失败或触发TypeError,须用JSON.stringify()序列化后再发送。

WebSocket 数据传输不是“开启连接后自动开始”,而是必须显式调用 send() 才能发出数据,且发送内容类型直接影响服务端解析逻辑和性能表现。
为什么 send() 传字符串却收不到?
常见错误是直接传对象:ws.send({type: 'login', user: 'alice'}) —— 这会触发 TypeError: Data must be a string or ArrayBuffer。WebSocket 原生 API 不接受裸对象,必须序列化。
- 正确做法:始终用
JSON.stringify()包一层,再传给send() - 服务端若用 Node.js 的
ws库,收到的仍是字符串,需手动JSON.parse();Spring Boot 的@MessageMapping则可自动反序列化(依赖 Jackson 配置) - 如果漏掉序列化,控制台看不到报错,但消息根本发不出去——
send()调用会静默失败,ws.readyState仍为1(OPEN)
发送 JSON 和发送纯文本的性能差异在哪?
本质没有运行时性能差异,都是 UTF-8 字节流。真正影响体验的是「协议层解析成本」和「网络字节量」。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 纯文本(如
"PING")适合心跳、指令类轻量通信,体积小、服务端无需 JSON 解析 - JSON(如
{"action":"update","id":123,"value":45.6})自带字段语义,便于扩展,但多出引号、冒号、逗号等冗余字符;高频场景下建议启用服务端压缩(如permessage-deflate扩展) - 千万别在 JSON 字符串里嵌套未转义的换行或双引号,否则
JSON.parse()直接抛错——前端应统一用JSON.stringify()生成,而非手拼
二进制数据(Blob/ArrayBuffer)怎么安全发送?
浏览器中直接 send() 二进制是可行的,但容易因类型误判导致服务端解析失败。关键点不在“能不能发”,而在“服务端是否按预期接收”。
- 发送
ArrayBuffer时,服务端收到的是Buffer(Node.jsws)或byte[](Java Spring),不是字符串——别试图toString()当文本处理 - 发送
Blob时,ws.send(blob)会自动读取并转为ArrayBuffer,但大文件可能阻塞主线程;建议用blob.arrayBuffer().then(buf => ws.send(buf))显式控制 - 服务端若期望文本却收到二进制,会报类似
Unexpected token in JSON at position 0—— 这说明协议约定不一致,不是代码 bug
最容易被忽略的是:WebSocket 没有内置消息分隔机制。连续发两个 send("a") 和 send("b"),服务端可能合并成一次 onmessage 事件收到 "ab",也可能拆成两次。需要应用层定义帧格式(如长度前缀、换行分隔)才能可靠解析多条消息。

















