user606521
user606521

Reputation: 15434

WebSocket not able to send/receive string longer than 65536 characters

I encountered strange websocket problem:

server in node.js:

var websocket     = require('websocket');
var http          = require('http');

var transportServer = http.createServer(function(request, response) {});
var wsServer = new websocket.server({ httpServer: transportServer });

wsServer.on('request',function(request) {
    var connection = request.accept(null,request.origin);
    console.log('connected');

    connection.on('message',function(message) {
        console.log('message received');
    });

    connection.on('close',function(){
        console.error('connection closed');
        process.exit(0);
    });
});

transportServer.listen(5000);

client in browser:

var ws = new ReconnectingWebSocket 'ws://localhost:5000'
ws.onopen = function(){
    var buf = '';
    for(var i = 1; i <= 65536; ++i) buf = buf + 'a';
    ws.send(buf);
}

Example above works but if I change 65536 in for loop to 65537 it fails - server does not print 'message received' and prints 'connection closed' instead and no error is reported on server or client. Is there any maximum message length in WebSocket?

Upvotes: 4

Views: 3665

Answers (1)

bodokaiser
bodokaiser

Reputation: 15742

WebSocket frames have their payload length defined in byte representation. Two bytes can maximal have a value of 0xffff (65535). To represent 65536 in bytes you need at least three bytes (0x010000).

So we have a limitation of the server side WebSocket implementation. You should consider using node-walve as server side WebSocket package as this will support lengths up to 4MiB. Serving bigger frames is currently not straight to do in node.js without downsides as unsigned 32Bit integers is the biggest number supported by nodes buffer module.

More detailed answer:

A single WebSocket frame supports three different frame lengths:

  1. Single byte (up to 0x7d)
  2. Two bytes (first byte will be 0x7e so we know to interpret following two bytes as length)
  3. Eight bytes (first byte is 0x7f so we interpret following eight bytes as length)

However as pointed out in the beginning. Eight bytes would be a unsigned 64bit integer which is not supported by javascript natively. The "websocket" package seems only to support two bytes of length determing bytes. "walve" is up to four bytes.

Upvotes: 2

Related Questions