uWebSockets.jsおよびWebsocket-SharpでのWebsocket圧縮の使用


11

接続にwebsocketを使用するモバイルゲームがあります。サーバーはuWebSockets.jsライブラリを使用するNode.jsアプリで、クライアントはWebsocket-Sharpライブラリを使用するUnityアプリです。どちらも上手くプレイしており、問題は発生していません。

最近、WebSocket圧縮を有効にしたいと考えました。どちらのライブラリも、メッセージごとの圧縮の拡張をサポートしていると述べていましたが、互換性がないものがあるようです。圧縮を使用するように設定すると、WebSocket接続がハンドシェイクですぐに閉じるためです。

また、wsライブラリを使用してクライアントをテストしましたが、同じ結果の圧縮の例が提供されています。ws圧縮オプションをいじってみましたが、serverMaxWindowBitsオプション(デフォルトはネゴシエートされた値)をコメント化すると、接続が確立され、メッセージの送受信が問題なく機能することがわかりました。また、uWebsocketsでのserverMaxWindowBitsの制御についても質問しました。

最後に試みたのは、最小限のuWSサーバーとwebsocket-sharpクライアントを接続することでした。サーバーのコードは次のとおりです。

const uWS = require('uWebSockets.js');
const port = 5001;

const app = uWS.App({
    }).ws('/*', {
        /* Options */
        compression: 1, // Setting shared compression method
        maxPayloadLength: 4 * 1024,
        idleTimeout: 1000,
        /* Handlers */
        open: (ws, req) => {
            console.log('A WebSocket connected via URL: ' + req.getUrl() + '!');
        },
        message: (ws, message, isBinary) => {
            /* echo every message received */
            let ok = ws.send(message, isBinary);
        },
        drain: (ws) => {
            console.log('WebSocket backpressure: ' + ws.getBufferedAmount());
        },
        close: (ws, code, message) => {
            console.log('WebSocket closed');
        }
    }).any('/*', (res, req) => {
        res.end('Nothing to see here!');
    }).listen(port, (token) => {
        if (token) {
            console.log('Listening to port ' + port);
        } else {
            console.log('Failed to listen to port ' + port);
        }
    });

これがクライアントコードです:

using System;
using WebSocketSharp;

namespace Example
{
  public class Program
  {
    public static void Main (string[] args)
    {
      using (var ws = new WebSocket ("ws://localhost:5001")) {
        ws.OnMessage += (sender, e) =>
            Console.WriteLine ("server says: " + e.Data);

        ws.Compression = CompressionMethod.Deflate; // Turning on compression
        ws.Connect ();

        ws.Send ("{\"comm\":\"example\"}");
        Console.ReadKey (true);
      }
    }
  }
}

サーバーとクライアントを実行すると、クライアントは次のエラーを出力します。

エラー| WebSocket.checkHandshakeResponse |サーバーは 'server_no_context_takeover'を送り返していません。Fatal | WebSocket.doHandshake |無効なSec-WebSocket-Extensionsヘッダーが含まれています。

クライアントはserver_no_context_takeoverヘッダーを予期しているようで、受信しませんでした。我々は、レビューuWebsocketsのソース(uWebsockets.jsモジュールのC ++一部)、見つかったコメント条件バックserver_no_context_takeoverヘッダを送信するために。したがって、条件のコメントを外してuWebsockets.jsをビルドし、再度テストして、クライアントで次のエラーが発生するようにしました。

WebSocketSharp.WebSocketException:フレームのヘッダーをストリームから読み取ることができません。

これら2つのライブラリを連携させるための提案はありますか?


確かに役に立ちますが、socket.ioはデフォルトで圧縮します。Best HTTP 2がsocket.io-websocketsをかなりサポートしていることは知っています
Samuel G

@SamuelGありがとうございます。ただし、現在、最小リソースで5k以上の同時接続を処理しているため、socket.ioを使用することはできません。
Koorosh Pasokhi

@KooroshPasokhi socket.ioが負荷を処理できない、またはリソースを大量に消費するという推論の結論は何ですか?あなたのテストについてもっと聞きたいです。
Samuel G

@SamuelGコメントは議論のためではありませんが、主な理由は、socket.ioの焦点がパフォーマンスではなく、socket.ioで上位層の抽象化を必要としないことだとしましょう。
Koorosh Pasokhi

回答:


3

更新:でのコードの読み取りに基づいて、圧縮を有効にするために必要なuWebSockets.jsすべてのパラメーターを有効にするために変更を加える必要がありますwebsocket-sharp。高性能JavaサーバーであるVertxでは、次の設定がUnity互換で動作しwebsocket-sharp、圧縮が行われます。

vertx.createHttpServer(new HttpServerOptions()
                .setMaxWebsocketFrameSize(65536)
                .setWebsocketAllowServerNoContext(true)
                .setWebsocketPreferredClientNoContext(true)
                .setMaxWebsocketMessageSize(100 * 65536)
                .setPerFrameWebsocketCompressionSupported(true)
                .setPerMessageWebsocketCompressionSupported(true)
                .setCompressionSupported(true));

以前は:

エラーは、実際、あるwebsocket-sharpだけをサポートしpermessage-deflate、使用DEDICATED_COMPRESSORcompression: 2代わりに)。


残念ながら、圧縮方法を2に設定してもエラーメッセージは変わりませんでした:(
Koorosh Pasokhi

次に、uWebSocketsにいくつかの根本的な問題があります。私は、より多くの構成フィールドを持つクライアントで、WebSocketSharpを使用して圧縮したJavaのvertx Webソケットを使用します。
DoctorPangloss

WebSocket.csヘッダーの拒否の動作を再現するuWebSockets.jsで直接テストを作成してみてください。DEDICATED_COMPRESSOR本当にうまくいくはずです!
DoctorPangloss

どういうテストですか?uWebSockets.jsのアーキテクチャは少し複雑です。JS、C ++、Cで記述された3つのレイヤーがあり、デバッグが困難になります。
Koorosh Pasokhi

ハンドシェイクwebsocket-sharpを再現するuWebSockets.jsプロジェクトディレクトリでテストを作成することを意味します。これは、準拠サーバーに接続して何が起こるかを確認することで発見できますか?
DoctorPangloss
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.