0

2 パートの質問

  1. このクライアントを正しく実装していますか?
  2. 独自の WebSocket サーバーを実装する場合、SignalR のトランスポート ネゴシエーション プロセスが WebSocket を認識し、それを通信に使用できるようにするための要件は何ですか?

私の技術的制約には現在以下が含まれていることに注意してください

  • Windows 7、
  • フレームワーク 4.5、
  • Owin セルフホスト (コンソール) SignalR サーバー、
  • Owin セルフホスト (コンソール) .NET クライアント、
  • Web クライアント (Javascript)

パート 1: System.Net.WebSockets.ClientWebSocket Client を使用して Katana サンプルを実装してみる

そのため、セルフホステッド SignalR プロセスを構築している最中であり、フィドラー トラフィックで、WebSocket を使用したいときに接続が LongPolling を使用していることに気付いたので、何が必要かを調査するプロセスに取り掛かりました。 WebSocket を利用できるようにします。

いくつかの迅速な調査の結果、さまざまな情報が得られました。一部の情報源は、WebSockets は Windows 8 および IIS 8 でのみ使用可能であり、WebSockets の実装は OS レベルで統合されていることを示していました。

一部の情報源は、その制限は HTTP.sys の使用を希望する関係者のみを対象としており、セルフホステッド ソリューションでは WebSocket を利用できることを示しています。 Katana サンプル WebSocket サーバー Katana サンプル WebSocket クライアント

そこで、Katana サンプル (WebSocket、.NET クライアント、および Web クライアントを介して公開したい SignalR サーバーがあります) を SignalR サーバーに実装し、. NET クライアント (現在関係のないクライアント コードの部分を省略):

static void Main(string[] args)
        {
            Console.WriteLine("╔════════════════════════════════════════════════════════════════════════════╗");
            Console.WriteLine("╠»»»-                     Starting Service.Host-                   «««╣");

            Console.WriteLine("║-- Connecting to Client Messaging Hub-- ");
            Console.WriteLine("║.....Attempting to upgrade to WebSockets ");

            //UseDefaultConnectionParameters();
            Connect("ws://localhost:8080");

            Console.WriteLine(String.Format("║-->Connection Established [{0}]", @"ws://localhost:8080"));
            Console.WriteLine("╠»»»                   Service.Host now  started                   «««╣");
            Console.WriteLine("╚════════════════════════════════════════════════════════════════════════════╝");
            Console.ReadLine();

        }
        private static async Task Connect(string uri)
        {
            ClientWebSocket websocket = null;
            try
            {
                websocket = new ClientWebSocket();//<= Throws exception
                await websocket.ConnectAsync(new Uri(uri), CancellationToken.None);
                await Task.WhenAll(Receive(websocket), Send(websocket));
            }
            catch(Exception ex)
            {
                Console.WriteLine("Exception: {0}", ex);
            }
            finally
            {
                if (websocket != null)
                    websocket.Dispose();
                Console.WriteLine();

                lock(master)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("WebSocket closed.");
                    Console.ResetColor();
                }
            }


        }

Connect() 関数内の行

ClientWebSocket websocket = new System.Net.WebSockets.ClientWebSocket();

スロー

Exception: System.PlatformNotSupportedException: The WebSocket protocol is not s
upported on this platform.
   at System.Net.WebSockets.ClientWebSocket..ctor().  

(私の CLR クライアント ライブラリは .NET Framework 4.5 を対象としています)

これは、実際には、Windows 8 なしで System.Net.WebSockets 名前空間から WebSocket クライアントを作成できないというハード リミットに達していますか?

パート 2: サードパーティ WebSocket サーバー/クライアントの影響の調査

パート 1 のコードが行き止まりであると仮定すると、次の実行可能なオプションは、サード パーティの Web ソケット サーバー ( SuperWebSocketなど) を適切なクライアント ( SignalR.Client.WebSocket4Net など) と共に 実装し、ソケット サーバーを公開することだと思います。 SignalR が消費するため。答えが「何もありません。うまくいく」と期待していますが、SuperWebSocket を立ち上げ、CLR クライアントを拡張して SignalR.Client.WebSocket4Net を実装すると、SignalR 通信がアップグレード要求をネゴシエートしてトランスポートを開始するために必要なものが必要になります。 ws:// で?


これら2つのパスのいずれかについて、誰かがガイダンスを提供できますか? 間違ったルートを選択すると、多くの時間を無駄にすることが予想されます。

4

1 に答える 1

0

パート1

Windows 8 および 2012 に出荷された http.sys の新しいバージョンは、通常の HTTP 要求を、WebSocket である永続的なバイナリの双方向 TCP 接続に変換する部分です。これにより、Websocket 接続が確立されたときに IIS がプロトコルを切り替えることができます。

Windows 7 で ClientWebSockets が機能しないのはなぜですか? まあ、それはまったく意味がありませんが、おそらくサーバーとクライアントの間にいくつかの共有機能があり、それが「古い」オペレーティングシステムでPlatformNotSupportedException.

パート2

おそらく、独自のITransportを実装して独自のWebSocketTransportを作成し、それをTransportManagerに登録する必要があります。これは純粋な憶測であり、私はそのようなことを試みたことはありません:) ただ、これについて見つけることができる小さなドキュメントや経験には注意してください...

しかし、ここで問題が発生します。クライアントが別のトランスポートに切り替えると、失敗します! オペレーティング システムは長いポーリングと WebSocket を同じポートでリッスンできないため、WebSocket コンポーネントへの通常の HTTP 要求は何の効果もありません。これは、http.sys が新しいバージョンで行うトリックであり、HTTP の通常のリクエストをリッスンし、必要に応じてそれらの 1 つを WebSocket で有効にすることができます。

私の0.02

なぜSignalR? これは、すぐには必要なくなるポリフィルです。WebSockets は、広くサポートされている標準のテクノロジーであり、websocket-jsを使用して古いブラウザーで簡単にポリフィルできます。SignalR は、一般的なデータをブロードキャストするアプリケーションに適しています(制限セクションを確認してください)。私はWebSocketListener という名前の WebSocket ライブラリを作成して維持しています。試してみることをお勧めします :) (ただし、クライアントはありません)。ライブラリを選択する前に、パフォーマンスとスケーラビリティについていくつかのライブラリをテストすることをお勧めします;)

于 2014-10-31T22:34:34.260 に答える