对WebSockets发送的数据进行速率限制

Chr*_*let 4 javascript websocket node.js

我们从websocket(从Node.js应用程序到Web浏览器)发送大量数据.

数据是二进制数据的形式blobs.

偶尔,最终用户连接不良 - 在这种情况下,我们希望'跳过'消息(将它们排除)并确保我们不会填写比用户可以接收的数据更多的数据.

在服务器端,我们尝试过:

function sendBlob(blob, socket) {
  console.log('socket.bufferedAmount: ' + socket.bufferedAmount); // Always zero

  if (socket.bufferedAmount > 0) {
    return; // Never called
  }

  socket.send(blob);
}
Run Code Online (Sandbox Code Playgroud)

不幸的是bufferedAmount总是返回零.

这是查看排队数据但在websockets中没有发送/接收的数据的正确方法,还是有更好的方法来实现这一目标?

(还尝试登录socket.bufferedAmount客户端,但它也始终返回零).

hex*_*ide 7

socket.bufferedAmount客户端(以及Node 的ws模块)上存在的属性是它自己缓冲的字节数,而不是远程.这意味着socket.bufferedAmount在服务器上意味着等待发送到客户端的字节数,对于客户端,它是等待发送到服务器的字节数.

您没有对该属性进行任何更改的原因是您的网络可能确实足以提供数据.如果您确实希望看到差异socket.bufferedAmount,请尝试限制浏览器网络访问.这可以通过浏览器扩展或NetLimiter等工具完成.

如果要通过跳过消息来限制连接,可以考虑在客户端和服务器之间创建某种类型的心跳系统.您可以通过多种方式执行此操作,例如应用此功能:

setInterval(function() {
  if (socket.bufferedAmount == 0) {
    socket.send('heartbeat');
  }
}, 1000);
Run Code Online (Sandbox Code Playgroud)

然后通过计算时间间隔来检测错过的心跳.这是相当低效的,但还有其他方法可以做到这一点,例如响应从服务器发送的数据(尽管考虑到如果你想在接收数据时发送心跳,心跳本身可能会受到限制或其他副作用) .

如果您愿意切换到Socket.IO,也可以使用替代解决方案.它具有允许您发送易失性消息的功能,这些消息是在客户端繁忙或由于任何原因无法接受消息时丢弃的消息.

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);
  });
});
Run Code Online (Sandbox Code Playgroud)

请注意,Socket.IO将在您的应用程序上更重,并且不使用本机websocket协议.当它是一个选项时它将使用websockets,但它是许多传输之一.Socket.IO构建于Engine.IO之上,它使用您当前使用的模块的分支.