Открытие канала websocket внутри контроллера MVC

Есть ли у кого-нибудь хороший опыт открытия соединения с websocket внутри контроллера MVC?

Технологический стек: 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: один недостаток, который я уже заметил, - когда существует (истинное) значение (по причинам простоты, не показанным в примере выше, допустим, когда канал должен быть закрыто), методы должны что-то вернуть (задача). Что это должно быть? Ответ HTTP 200? Я думаю, нет, потому что в документации на WebSockets написано, что ничего не следует отправлять после кадра "закрыть".

Обновление 3:. Я научился с трудом: если вы хотите, чтобы WebSockets работали при отладке в Visual Studio 2015 с использованием IIS Express 10.0 в Windows 10, вам все равно придется использовать https://github.com/aspnet/WebSockets и настройте app.UseWebSockets() в файле Startup.cs. В противном случае IsWebSocketRequest будет ложным. Кто-нибудь знает почему? Рукопожатие?

Ответы

Ответ 1

Кажется прекрасным.

  • Вероятно, вы хотите изменить while(true) на while (!HttpContext.RequestAborted.IsCancellationRequested), чтобы обнаружить клиентские разъединения и завершить запрос.
  • Вам не нужно проверять значение null или состояние веб-узла после того, как вы вызываете accept.

Я предполагаю, что весь этот код является временным, и вы действительно будете читать что-то из websocket.

Применяются все обычные правила websocket:

  • Использовать SSL (когда вы принимаете его заново)
  • Он не будет работать на нескольких серверах (это соединение с точкой точка-точка)
  • Вам необходимо поддерживать обработку частичных кадров. Вы можете использовать это, если знаете, что клиент не отправит.