web-dev-qa-db-ja.com

MVCコントローラー内でWebSocketチャネルを開く

誰もがMVCコントローラー内でWebSocket接続を開くのに良い経験がありますか?

テクノロジスタック:ASPNET Core 1.0(RC1)MVC、dnx46、System.Net.WebSockets

ミドルウェアの代わりにMVCを使用する理由:全体的な整合性、ルーティング、すでに挿入されているリポジトリ、同じコントローラでプライベートメソッドを呼び出すオプション。

[HttpGet("v1/resources/{id}")]
public async Task<IActionResult> GetAsync(string id)
{
    var resource = await this.repository.GetAsync(id);
    if (resource == null)
    {
        return new HttpStatusCodeResult(404);
    }

    if (this.HttpContext.WebSockets.IsWebSocketRequest)
    {
        var webSocket = await this.HttpContext.WebSockets.AcceptWebSocketAsync();
        if (webSocket != null && webSocket.State == WebSocketState.Open)
        {
            while (true)
            {
                var response = string.Format("Hello! Time {0}", System.DateTime.Now.ToString());
                var bytes = System.Text.Encoding.UTF8.GetBytes(response);

                await webSocket.SendAsync(new System.ArraySegment<byte>(bytes),
                    WebSocketMessageType.Text, true, CancellationToken.None);

                await Task.Delay(2000);
            }
        }
    }

    return new HttpStatusCodeResult(101);           
}

質問:ミドルウェアでWebSocket接続を処理する代わりに、既知の欠点がありますか?ハンドシェイクはどうですか、HTTP 101ステータスコードを返す以外に何かする必要がありますか?

更新1:SignalRを使用しないのはなぜですか?フォールバック手法を使用する必要がないので、優れた製品ですが、依存関係を追加してもメリットはありません。この状況。

更新2:すでに気づいた1つの欠点-while(true)が存在する場合(単純化のため、上の例には示されていません)たとえば、チャネルを閉じる必要がある場合)、メソッドは何かを返す必要があります(タスク)。それはどうあるべきですか? HTTP 200ステータス応答? WebSocketのドキュメントには「閉じる」フレームの後に何も送信するべきではないため、そうではないと思います。

更新3:1つのことは、Visual Studio 2015でのデバッグ中にWebSocketsを機能させる場合、IIS Windows 10のExpress 10.0でも、 https://github.com/aspnet/WebSockets を使用して、Startup.csファイルでapp.UseWebSockets()を構成する必要があります。それ以外の場合は、IsWebSocketRequest誰もが理由を知っていますか?握手?

18
Zygimantas

元気そうです。

  • クライアントの切断を検出してリクエストを終了するために、おそらくwhile(true)while (!HttpContext.RequestAborted.IsCancellationRequested)に変更する必要があります。
  • Acceptを呼び出した後、nullまたはWebSocketの状態を確認する必要はありません。

そのコードはすべて一時的なものであり、実際にはWebSocketから何かを読み取ることになります。

通常のすべてのWebSocketルールが適用されます。

  • SSLを使用する(実際にホスティングしている場合)
  • 複数のサーバーでは機能しません(ポイントツーポイントソケット接続です)。
  • 部分フレームの処理をサポートする必要があります。クライアントが何も送信しないことがわかっている場合は、これをパントできます。
6
davidfowl