rcv
rcv

Reputation: 6318

Sending BSON from python to javascript over websockets

I have a python application that contains an Autobahn websocket server to send to an HTML5/javascript GUI. I have been transferring data between them using JSON, but am now really starting to stress my bandwidth as I need to send arrays of 1000's of (single precision) 3D positions in some of my messages. Writing each of those floats as text for JSON seems like an obvious waste when I could just in theory just send 4 bytes for each number. BSON seems like a much better idea, but I can't seem to get it working.

Here is the gist of my code:

# Python side
class BroadcastServerFactory(WebSocketServerFactory):
    # ...
    def broadcast_message(message):
        bson_msg = bson.BSON.encode(msg)
        prepared_msg = self.prepareMessage(bson_msg, isBinary=True)
        for c in self.clients:
            self.clients[c].sendPreparedMessage(prepared_msg)
// Javascript side
app.sock = new WebSocket('ws://127.0.0.1:9090');
app.sock.binaryType = "arraybuffer";
// ...
sock.onmessage = function(e) {
    var msg = null;
    try {
        msg = BSON.deserialize(e.data);
    }
    catch(err) {
        console.log('Failed to deserialize: ', err);
    }
    if(msg) app.onmessage(msg);
};

Unfortunately, as soon as I get a message on the javascript side, my exception handler triggers with:

Failed to deserialize:  Error: corrupt bson message {stack: (...), message: "corrupt bson message"}

I am using the browser build of the mongodb bson library on the javascript side, and the pymongo bson implementation on the Python side.

Upvotes: 3

Views: 1613

Answers (1)

rcv
rcv

Reputation: 6318

After much fiddling, I seem to have a working solution:

// Javascript side
app.sock = new WebSocket('ws://127.0.0.1:9090');
app.sock.binaryType = "blob"; // Changed from "arraybuffer"
// ...
sock.onmessage = function(e) {
    try {
        var reader = new FileReader();
        reader.onload  = function() {
            uint8Array  = new Uint8Array(this.result);
            app.onmessage(BSON.deserialize(uint8Array));
        }
        reader.readAsArrayBuffer(e.data);

    }
    catch(err) {
        console.log('Failed to deserialize: ', err);
    }
};

Upvotes: 3

Related Questions