WebSocket发送二进制数据需满足三点:类型合法(ArrayBuffer/Blob/Uint8Array/字符串)、连接就绪、服务端匹配接收方式;binaryType须设为"arraybuffer";后端须用专用方法接收二进制。

WebSocket 发送二进制数据不是“能不能”的问题,而是“怎么发才不踩坑”的问题——核心就三点:类型必须合法、连接状态必须就绪、服务端接收方式必须匹配。
send() 只认四种类型:ArrayBuffer、Blob、Uint8Array、字符串
你不能直接 ws.send({type: 'img', data: buffer}),这会报 TypeError: Failed to execute 'send' on 'WebSocket'。对象必须先序列化(文本)或拆解为二进制原生类型。
-
ArrayBuffer:适合构造协议头(如 4 字节长度 + 1 字节类型),用DataView写入后直接ws.send(buf) -
Blob:用户选图后input.files[0]就是 Blob,ws.send(file)最简路径,服务端收到的是原始字节流 -
Uint8Array:Canvas 截图后ctx.getImageData().data是Uint8ClampedArray,取其.buffer或直接ws.send(u8arr)都行 - 别用
toDataURL()再包 JSON——等于把二进制转 Base64(+33% 体积),再转字符串,纯属双重浪费
binaryType 必须设为 "arraybuffer" 才能高效收图
默认 ws.binaryType === 'blob',这意味着即使你发的是 ArrayBuffer,收到的 event.data 也是 Blob,想读内容还得调 blob.arrayBuffer()——异步、多一次拷贝、主线程卡顿。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 务必在
open事件之后立刻设置:ws.binaryType = 'arraybuffer' - 此时
event.data直接是ArrayBuffer,用new Uint8Array(event.data)秒级访问字节 - 若服务端要解析帧头(比如前 2 字节是 magic number),用
new DataView(event.data)比遍历Uint8Array清晰得多 - 没设这句?控制台打
typeof event.data,如果是"object"且event.data.constructor.name === "Blob",就是它了
FastAPI 和 Javalin 接收二进制必须用专用方法
前端发的是二进制,后端不能用 receive_text() 或普通 POST 解析——会乱码或抛异常。
- FastAPI 必须用
await websocket.receive_bytes(),返回bytes对象;receive_text()收二进制会触发WebSocketDisconnect - Javalin 必须注册
onBinaryMessage回调,从ctx.data()拿ByteArray,不是ctx.message() - Node.js +
ws库默认支持Buffer,但需确认ws.send(imgBuf, { binary: true })中binary: true显式传入,否则可能被当文本发 - 如果发的是分片语音(
MediaRecorder的多个Blob),服务端必须按序拼接——单个Blob不代表完整文件
图片直传 Canvas 展示的关键链路
这不是“发完就完”的流程,而是一条必须闭环的链路:ArrayBuffer → Blob → object URL → img.onload → drawImage。漏任何一环,Canvas 就是空的。
- 确保
event.data instanceof ArrayBuffer,不是null或undefined - 构造 Blob 时 MIME 类型要对:
new Blob([event.data], { type: 'image/jpeg' }),错写成'image/png'会导致img.onload不触发 -
URL.createObjectURL(blob)后必须在img.onload里绘制,不能在onmessage里直接ctx.drawImage(img)——此时图片还没加载完 - 用完记得
URL.revokeObjectURL(url),否则内存泄漏(尤其高频帧流场景)
最常被忽略的是连接就绪检查和 MIME 类型一致性——前者导致 send 静默失败,后者让图片加载失败却无报错。这两处不盯住,其他都白搭。

















