在MVC控制器内打开websocket通道

有没有人在MVC控制器内打开websocket连接有任何经验?

技术堆栈: ASPNET Core 1.0(RC1)MVC,dnx46,System.Net.WebSockets

为什么MVC而不是中间件:为了整体一致性,路由,已经注入的存储库,在同一个控制器中调用私有方法的选项。

[HttpGet("v1/resources/{id}")] public async Task 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(bytes), WebSocketMessageType.Text, true, CancellationToken.None); await Task.Delay(2000); } } } return new HttpStatusCodeResult(101); } 

问题:是否存在任何已知的缺点,而不是在中间件中处理websocket连接? 握手怎么样,除了返回HTTP 101状态代码之外,还需要做什么吗?

更新1:为什么不SignalR? 没有必要使用回退技术,因此虽然它是一个很好的产品,但在这种情况下,它看不到添加额外依赖性的好处。

更新2:我已经注意到的一个缺点 – 当while(true)存在时(出于简单的原因,上面的例子中没有显示,让我们说,当需要关闭一个通道时),方法需要返回一些东西(任务)。 应该是什么? HTTP 200状态响应? 我想不,因为在编写WebSockets文档时,在“关闭”框架之后不应该发送任何内容。

更新3:有一点我学到了很多困难,如果你想在Windows 10上使用IIS Express 10.0在Visual Studio 2015中调试时使WebSockets工作,你仍然需要使用https://github.com/aspnet/WebSockets和在Startup.cs文件中配置app.UseWebSockets()。 否则,IsWebSocketRequest将为false。 谁知道为什么? 握手?

看起来很好。

  • 您可能希望将while(true)更改为while (!HttpContext.RequestAborted.IsCancellationRequested)以便检测客户端断开连接并结束请求。
  • 在调用accept之后,您不需要检查null或websocket的状态。

我假设所有代码都是临时的,你实际上是从websocket读取的东西。

所有通常的websocket规则都适用:

  • 使用SSL(当您托管forreal时)
  • 它不适用于多个服务器(它是点对点套接字连接)
  • 您需要支持处理部分帧。 如果您知道客户端不会发送任何内容,您可以解决这个问题。