Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug: Data corruption when sending binary #210

Open
DomNomNom opened this issue Mar 6, 2024 · 1 comment
Open

bug: Data corruption when sending binary #210

DomNomNom opened this issue Mar 6, 2024 · 1 comment

Comments

@DomNomNom
Copy link

Hi, I was sending icons over websocket OSC and some of them got corrupted.
It seemed like larger ones were fine but smaller ones have trouble.

I've made a minimal example that shows the problem clearly:

const http = require('node:http');
const WebSocket = require("ws");
const osc = require('osc');

// The data we want to send
const bytes = new Uint8Array([ 4,4,4,4,4,4 ]);

// server
const hostname = '127.0.0.1';
const port = 7000;
const server = http.createServer(async (req, res) => {});
server.listen(port, hostname, () => {
    // console.log(`Server running at http://${hostname}:${port}/`);
});
const wss = new WebSocket.Server({ server });
wss.on("connection", function(socket) {
    const osc_port = new osc.WebSocketPort({
        socket: socket,
        metadata: true
    });
    osc_port.on("message", (osc_msg) => {
        // console.log('rx osc_msg=', osc_msg)
        console.log("rx osc_msg.args[0].value=", osc_msg.args[0].value)
        console.log();
        process.exit();
    });
});

// client
const ui_url = `ws://${hostname}:${port}/`;
ui_port = new osc.WebSocketPort({
    // url: ui_url,
    metadata: true,
    socket: new WebSocket(ui_url),
});
ui_port.on("ready", function () {
    const osc_msg = {
      address: '/foo',
      args: [
        { type: 'b', value: bytes }
      ]
    };
    // console.log('tx osc_msg=', osc_msg)
    console.log('tx osc_msg.args[0].value=', osc_msg.args[0].value)
    ui_port.send(osc_msg);
});

want:

tx osc_msg.args[0].value= Uint8Array(6) [ 4, 4, 4, 4, 4, 4 ]
rx osc_msg.args[0].value= Uint8Array(6) [ 4, 4, 4, 4, 4, 4 ]

got:

tx osc_msg.args[0].value= Uint8Array(6) [ 4, 4, 4, 4, 4, 4 ]
rx osc_msg.args[0].value= Uint8Array(6) [ 0, 0, 0, 0, 0, 6 ]
@colinbdclark
Copy link
Owner

Hi @DomNomNom, my apologies for the very slow response. Thank you so much for the simplified test case for this issue, it makes a huge difference in trying to triage issues like this.

Since it's been a while, did you ever come up with a workaround or fix?

It seems like the bug you've found is legit, though so far I'm puzzled by it. It looks like the output you're receiving is reading the zero padding and the four-byte size of the binary blob, so there's an incorrect offset somewhere.

But, playing with your example, it appears that the bug is not in the low-level OSC API, where all the low-level packing/unpacking happens:

This code:

let packet = osc.writePacket(osc_msg, {metadata: true});
let parsed = osc.readPacket(packet, {metadata: true});
console.log('parsed.args[0].value=', parsed.args[0].value);

resulted in:

parsed.args[0].value= Uint8Array(6) [ 4, 4, 4, 4, 4, 4 ]

So you might be able to work around the issue by receiving raw OSC data and reading it yourself, I'm not sure. I'll need to look into this further and expand the unit tests to including sending and receiving binary data over multiple transports.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants