javascriptnode.jstypescriptarraybufferws

ws: Recieve data from client as ArrayBuffer


I am using the ws library in nodejs to create a little cursor lobby with other players. I have successfully implemented using the server to send ArrayBuffers with bit streams to the client, and also reading them successfully on the client, however when I send the streams the other way back I can't figure out how to transform them into ArrayBuffers.

This is my server code, which receives data from the client. However, the data variable seems to return a buffer with chopped up data which throws a wrench in decoding the bitstream. I am wondering how I can receive that data variable as an ArrayBuffer.

const server = new ws.Server({
    port: 3001,
    maxPayload: 1024
});
// ...
socket.on("message", (data) => { // <- the data variable here seems to be the problem
    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}`);
        }
    }
});

This is the client code that sends the data:

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}`);
});

It sends the buffer and logs the position it sent, but when MessageType is processed on the server, it returns 130 while ClientMessageType.TICK is 1. I can't put my finger on what the problem is here.
I'm guessing that the server reading it as a buffer/Uint8Array is the issue, but I don't know how to make ws return binary data as an ArrayBuffer as my client sent it. It's strange that it works server -> client but not client -> server, so any pointers would be helpful.


Solution

  • Turns out I had been dealing with the buffer incorrectly. Slicing it to the offset and length fixes this issue; posting this to help anybody else who happens to use the bit-buffer library.

    socket.on("message", (data: Buffer) => {
        const pkt = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength); // this is new
        const stream = new BitStream(pkt);
        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);
            }
        }
    });