Открытие канала 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 (когда вы принимаете его заново)
- Он не будет работать на нескольких серверах (это соединение с точкой точка-точка)
- Вам необходимо поддерживать обработку частичных кадров. Вы можете использовать это, если знаете, что клиент не отправит.