4

socket.io を使用するサーバーがあり、サーバー データの送信速度が速すぎるクライアントを調整する方法が必要です。サーバーは、TCP インターフェースと socket.io インターフェースの両方を公開します - TCP サーバー (netモジュールから) を使用socket.pause()してsocket.resume()、 と を使用できます。これにより、クライアントが効果的に調整されます。しかし、socket.io のsocketクラスにはpause()andresume()メソッドがありません。

サーバーを圧倒していて速度を落とす必要があるというフィードバックをクライアントに得る最も簡単な方法は何ですか? 私が気に入ったのは、クライアント側で追加のコードを必要socket.pause()socket.resume()しなかったためです-TCPソケットをバックアップすると、自然に速度が低下します。socket.ioに相当するものはありますか?

更新: サーバーと対話するための API を提供します (現在、TCP 上で実行される Python バージョンと、socket.io を使用する JavaScript バージョンがあります)。したがって、クライアントが何をするかを実際に制御することはできません。socket.pause()これがand の使用が非常に優れている理由socket.resume()です。TCP ストリームをバックアップすると、Python クライアントが何をしようとしても速度が低下します。JavaScript クライアントに相当するものを探しています。

4

6 に答える 6

3

十分に掘り下げて、これを見つけました:

this.manager.transports[this.id].socket.pause();

this.manager.transports[this.id].socket.resume();

確かに、socket.io 接続が Web ソケット接続でない場合、これはおそらく機能せず、将来の更新で壊れる可能性がありますが、今のところはそれで行くつもりです。将来時間ができたらQUOTA_EXCEEDED、パスカルが提案した解決策に変更するでしょう。

于 2013-02-21T20:21:27.483 に答える
3

これは、スロットリングを実現する汚い方法です。これは古い投稿ですが。一部の人々はそれから恩恵を受けるかもしれません:

最初にミドルウェアを登録します。

io.on("connection", function (socket) {

 socket.use(function (packet, next) {
    if (throttler.canBeServed(socket, packet)) {
        next();
    }
 });
 //You other code ..
});

canBeServed は、以下に示す単純なスロットルです。

function canBeServed(socket, packet) {
 if (socket.markedForDisconnect) {
     return false;
 }

 var previous = socket.lastAccess;
 var now = Date.now();
 if (previous) {
    var diff = now - previous;

    //Check diff and disconnect if needed.
    if (diff < 50) {
        socket.markedForDisconnect = true;
        setTimeout(function () {
            socket.disconnect(true);
        }, 1000);
        return false;
    }
}

socket.lastAccess = now;

return true;
}

Date.time() の代わりに process.hrtime() を使用できます。

于 2017-03-28T08:37:40.080 に答える
1

サーバーのどこかにコールバックがあり、通常はクライアントに応答を返す場合は、次のように変更してみてください。

前:

  var respond = function (res, callback) {
    res.send(data);
  };

var respond = function (res, callback) {
    setTimeout(function(){
        res.send(data);
      }, 500); // or whatever delay you want.
  };
于 2013-02-21T01:34:19.680 に答える
1

クライアントの速度を落とす必要があるようです。1 つのクライアントの送信速度が速すぎてサーバーが追いつかない場合、数百のクライアントではうまくいきません。

これを行う 1 つの方法は、クライアントに、他のメッセージを送信する前に各送信の応答を待機させることです。このようにして、サーバーは、たとえば準備ができたときにのみ応答するか、設定された時間後にのみ応答することにより、クライアントが送信できる速度を制御できます。

これで十分でない場合は、クライアントが 1 秒あたり x リクエストを超えたときに、QUOTA_EXCEEDED エラーなどの応答を開始し、送信されたデータを無視します。これにより、外部開発者はアプリを意図したとおりに動作させることができます。

于 2013-02-21T00:32:59.787 に答える
0

別の提案として、次のような解決策を提案します。MySQL が大量のリクエストを取得することは一般的であり、リクエストの受信速度よりも適用に時間がかかります。サーバーは、リクエストを db のテーブルに記録できます。このアクションは、リクエストが入ってくる速度に対して十分に高速であると想定し、サーバーが維持できるように通常の速度でキューを処理します。このバッファ システムにより、サーバーの実行速度は遅くなりますが、それでもすべてのリクエストを処理できます。

ただし、シーケンシャルなものが必要な場合は、クライアントが別のリクエストを送信する前に、リクエストのコールバックを確認する必要があります。この場合、サーバーの準備完了フラグが必要です。フラグがまだ赤いときにクライアントがリクエストを送信している場合は、クライアントに減速するように伝えるメッセージが表示されることがあります。

于 2013-03-08T18:43:13.313 に答える