You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js中ws库接收客户端ArrayBuffer数据异常问题求助

问题

在Node.js中使用ws库开发多人光标大厅时,服务端向客户端发送带比特流的ArrayBuffer能正常解析,但客户端回传数据时,服务端message事件的data是Buffer类型,导致比特流解码错误——客户端发送的ClientMessageType.TICK为1,但服务端读取到的messageType却是130。需要解决服务端如何正确接收客户端发来的ArrayBuffer数据的问题。

服务端代码:

const server = new ws.Server({
    port: 3001,
    maxPayload: 1024
});
// ...
socket.on("message", (data) => { // <- 此处data变量存在问题
    const stream = new BitStream(data);
    const messageType = stream.readUint8();
    switch(messageType) {
        case ClientMessageType.TICK: {
            const x = stream.readUint16();
            const y = stream.readUint16();
            plrCursor.pos = [x, y];
            updatedCursors.push(plrCursor.id);
            console.log(`Cursor ${plrCursor.id} moved to ${x}, ${y}`);
        }
    }
});

客户端发送代码:

document.addEventListener("mousedown", (event) => {
    if(!connected) return;
    const stream = new BitStream(new ArrayBuffer(8 + 16 * 2));
    stream.writeUint8(ClientMessageType.TICK);
    stream.writeUint16(event.clientX);
    stream.writeUint16(event.clientY);
    socket.send(stream.buffer);
    console.log(`Sent tick: ${event.clientX}, ${event.clientY}`);
});
解决方案

方法一:配置ws服务端直接接收ArrayBuffer

ws库默认会把二进制数据转为Buffer,你可以通过配置binaryType让服务端直接接收ArrayBuffer,确保和客户端发送的数据类型一致:

全局配置(所有连接生效)

const server = new ws.Server({
    port: 3001,
    maxPayload: 1024,
    perMessageDeflate: false, // 启用压缩会导致binaryType配置失效,建议关闭
    binaryType: 'arraybuffer' // 关键配置
});

单个socket配置(针对特定连接)

server.on('connection', (socket) => {
    socket.binaryType = 'arraybuffer'; // 为当前连接设置二进制类型
    socket.on("message", (data) => {
        // 此时data为ArrayBuffer,直接传入BitStream即可
        const stream = new BitStream(data);
        const messageType = stream.readUint8();
        // 后续逻辑保持不变
    });
});

方法二:手动将Buffer转换为ArrayBuffer(兼容旧代码)

如果不想修改全局配置,可手动把接收到的Buffer转为ArrayBuffer,避免数据类型不匹配导致的解码错误:

socket.on("message", (data) => {
    // 精准截取Buffer对应的ArrayBuffer片段
    const arrayBuffer = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
    const stream = new BitStream(arrayBuffer);
    const messageType = stream.readUint8();
    // 后续逻辑保持不变
});

错误原因说明

之前出现130的错误,是因为BitStream直接读取Buffer时,字节处理逻辑不匹配,导致原本的uint8值1被错误解析为130(二进制10000010),本质是数据类型不一致引发的解码异常。

内容的提问来源于stack exchange,提问作者Vercte

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 09:42:49