4

私たちは大量のデータを 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);
}

残念ながらbufferedAmount、常にゼロを返します。

これは、キューに入れられているがWebSocketで送受信されていないデータの量を確認する正しい方法ですか、それともこれを達成するためのより良い方法はありますか?

socket.bufferedAmount(クライアント側でもログを記録しようとしましたが、常にゼロを返します)。

4

2 に答える 2

14

socket.bufferedAmountクライアント (および Node の ws モジュール) に存在するプロパティはリモートではなく、それ自体がバッファリングしたバイト数です。つまりsocket.bufferedAmount、サーバーでは、クライアントへの送信を待機しているバイト数を意味し、クライアントでは、サーバーへの送信を待機しているバイト数を意味します。

プロパティが変更されない理由は、ネットワークがおそらくデータを配信するのに十分であるためです。実際に の違いを確認したい場合はsocket.bufferedAmount、ブラウザのネットワーク アクセスを制限してみてください。これは、ブラウザー拡張機能またはNetLimiterなどのツールを使用して行うことができます。

メッセージをスキップして接続を抑制したい場合は、クライアントとサーバーの間にある種のハートビート システムを作成することを考えることができます。この関数を適用するなど、これを行う方法はたくさんあります。

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

そして、時間間隔をカウントすることで欠落したハートビートを検出します。これはかなり非効率的ですが、サーバーから送信されたデータに応答するなど、これを行う他の方法もあります (ただし、データを受信するときにハートビートを送信する場合、ハートビート自体が抑制されたり、その他の副作用が発生する可能性があることを考慮してください)。 .

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);
  });
});

Socket.IO はアプリケーションにとってより重く、ネイティブの websocket プロトコルを使用しないことに注意してください。オプションの場合は Websocket を使用しますが、これは多くのトランスポートの 1 つです。Socket.IO は、現在使用しているモジュールのフォークを使用する Engine.IO に基づいて構築されています。

于 2013-09-16T04:05:45.310 に答える