websocket发送二进制数据应按需选用blob或arraybuffer:blob适合文件、媒体流分片等场景;arraybuffer适用于需字节级控制、协议头拼接、加密压缩等底层操作,且须设置binarytype="arraybuffer"。

WebSocket 发送二进制数据,Blob 和 ArrayBuffer 不是“选哪个更好”的问题,而是“该用哪个”的问题——取决于你手上的数据形态、控制粒度需求和后端协议设计。直接 send(File) 或 new Blob([...]) 能跑通,不代表它适合你的场景;硬套 Uint8Array 也能发,但可能白费力气做无谓转换。
ws.send() 支持哪些类型?别传错就对了
send() 只接受四种原生类型:字符串、Blob、ArrayBuffer、ArrayBufferView(比如 Uint8Array、DataView)。其他一切——Object、null、undefined、JSON 对象——都得先处理:
- JSON 控制指令必须
JSON.stringify()成字符串再 send -
File是Blob子类,可直接ws.send(file),无需转 base64 - Canvas 截图后想发二进制?优先
canvas.toBlob(callback)拿Blob,别用toDataURL()得到字符串再包一层 - 要加自定义帧头(如 4 字节长度 + 1 字节类型)?必须用
ArrayBuffer拼接:blob.arrayBuffer()读出原始数据,再用Uint8Array合并
MediaRecorder 流式发音频,用 Blob 就够了
语音流不是等录完再传的文件,而是靠 mediaRecorder.ondataavailable 分块触发。这时候 Blob 是最自然的选择:
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
-
mediaRecorder.start(200)设置 200ms 分片间隔,太短易触发 GC,太长失去流式意义 - 回调里
event.data就是Blob,直接ws.send(event.data)即可,不用new Blob([event.data])套娃 - 移动端 Safari 对单次 send 的
Blob大小敏感,建议上限设为 512KB,超限时用blob.slice(0, 512 * 1024) - 别依赖 Cookie 鉴权——WebSocket 不带跨域 Cookie,首次发一个文本帧
{ "auth": "xxx" }更可靠
需要字节级控制或高频拼接?切到 ArrayBuffer
当你需要写协议头、加密、压缩、或对接硬件/嵌入式设备时,ArrayBuffer 才是正解。但它不是“更高级”,只是“更底层”:
- 必须在
ws.onopen后立刻设ws.binaryType = "arraybuffer",否则收到的event.data是Blob,还得异步转arrayBuffer() - 发送前构造数据:用
new ArrayBuffer(4)+DataView写整数,或new Uint8Array([0x01, 0x02])直接 send - 接收端拿到的是
ArrayBuffer,可用new Uint8Array(event.data)快速访问字节,避免Blob的异步读取开销 - 大文件分片上传若需带序号、校验和、偏移量,必须用
ArrayBuffer构造帧结构,Blob不支持随机写入
后端怎么区分文本帧和二进制帧?别漏重载方法
WebSocket 协议不区分业务语义,后端收到什么类型,完全取决于前端 send 什么。混用文本和二进制帧合法,但后端代码必须能同时接住:
- Node.js +
ws库:监听message事件时,用event.isBinary === true判断是否为二进制帧,对应数据是Buffer - Java +
@ServerEndpoint:必须重载两个@OnMessage方法——一个参数为String,一个为ByteBuffer,否则二进制帧会被忽略或报错 - 不要等所有二进制帧收完再处理——音频/视频流必须按序拼接,建议加简单帧头(如 uint32_t seq + uint32_t total),避免丢帧后无法恢复
- WAV 文件生成陷阱:前端发的是 raw opus/webm 片段,后端不能直接 cat 成 WAV;需解码 + PCM 重采样 + 写 WAV header,这步常被跳过导致播放失败
真正容易被忽略的,是连接状态检查和分片节奏控制——ws.readyState !== WebSocket.OPEN 时 send 会静默失败;而 mediaRecorder.start() 后没监听 error 事件,用户拒授麦克风会导致后续所有 ondataavailable 不触发,整个流就卡死在开头。










