Limiting the speed of data sent using WebSockets

We send a lot of data according to a web schedule (from the Node.js application to a web browser).

Data is binary data in the form of blobs .

Sometimes the end user is in a bad connection - in which case we would like to skip messages (leave them) and make sure that we are not copying more data than the user can receive.

On the server side, we tried:

 function sendBlob(blob, socket) { console.log('socket.bufferedAmount: ' + socket.bufferedAmount); // Always zero if (socket.bufferedAmount > 0) { return; // Never called } socket.send(blob); } 

Unfortunately, bufferedAmount always returns zero.

Is it right to see how much data is in the queue but not sent / received in websockets, or is there a better way to achieve this?

(Also tried logging socket.bufferedAmount on the client side, but it also always returns zero).

+4
source share
2 answers

The socket.bufferedAmount property that exists on clients (as well as the ws module for Node) is the number of bytes that it itself is buffered, not the console. This means that socket.bufferedAmount on the server means the number of bytes waiting to be sent to the client, and for the client, how many bytes are waiting for sending to the server.

The reason you are not getting any changes to the property is because your network is probably really enough to deliver data. If you really want to see the difference in socket.bufferedAmount , try limiting your browser's network access. This can be done using browser extensions or tools such as NetLimiter .

If you want to throttle connections by skipping messages, you might consider creating some kind of heart rate system between the client and server. There are many ways to do this, for example, apply this function:

 setInterval(function() { if (socket.bufferedAmount == 0) { socket.send('heartbeat'); } }, 1000); 

And then by detecting missed heartbeats by counting the time interval. This is quite inefficient, but there are other ways to do this, for example, to respond to the data sent from the server (although note that if you want to send a pulse when receiving data, then a heartbeat can cause throttling or other side effects).

An alternative solution will also be available if you want to upgrade to Socket.IO . It has a feature that allows you to send mutable messages, which are messages that are deleted if the client is busy or cannot receive messages for any reason.

 var io = require('socket.io').listen(80); io.sockets.on('connection', function (socket) { var timer = setInterval(function () { socket.volatile.emit('data', 'payload'); }, 100); socket.on('disconnect', function () { clearInterval(timer); }); }); 

Note that Socket.IO will be heavier for your application and will not use its own websocket protocol. It will use websockets when it is an option, but it is one of many transports. Socket.IO is built on Engine.IO, which uses the plug of the module you are currently using.

+5
source

The readtonly bufferedAmount attribute represents the number of bytes of UTF-8 text that have been queued using the send() method.

And your case shows that you are trying to access it in a message received from the server. therefore, bufferedAmount not installed.

+1
source

Source: https://habr.com/ru/post/1502019/


All Articles