c# - 在 MVC Controller 中打开一个 websocket channel

标签 c# asp.net-mvc websocket asp.net-core asp.net-core-mvc

有没有人有在 MVC Controller 中打开 websocket 连接的良好经验?

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

为什么选择 MVC 而不是中间件:为了整体一致性、路由、已经注入(inject)的存储库、在同一 Controller 中调用私有(private)方法的选项。

[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:我已经注意到一个缺点 - 当 while(true) 存在时(为简单起见,上面的示例中没有显示,比方说,当一个 channel 需要关闭),方法需要返回一些东西(任务)。它应该是什么? HTTP 200 状态响应?我想不会,因为在 WebSockets 文档中写道,在“关闭”帧之后不应发送任何内容。

更新 3: 我通过艰难的方式学到了一件事,如果你想在 Windows 10 上使用 IIS Express 10.0 在 Visual Studio 2015 中调试时让 WebSockets 工作,你仍然必须使用 https://github.com/aspnet/WebSockets 和在 Startup.cs 文件中配置 app.UseWebSockets()。否则,IsWebSocketRequest 将为假。任何人都知道为什么?握手?

最佳答案

看起来不错。

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

我假设所有这些代码都是临时的,您实际上会从 websocket 中读取一些东西。

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

  • 使用 SSL(当您真正托管它时)
  • 它不能在多个服务器上工作(它是点对点套接字连接)
  • 您需要支持处理部分帧。如果您知道客户不会发送任何信息,您可以下注。

关于c# - 在 MVC Controller 中打开一个 websocket channel ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35554128/

相关文章:

javascript - 代码完成无法识别来自 OpenLayers js 文件的成员

Javax WebSockets 不适用于 programmattic Tomcat 7 实例化

c# - ASP.NET MVC Excel 导出文件格式错误

javascript - window.location.href重复的url地址

Python Websocket : infinite lock on client recv

c - 运行 lwIP 1.3.2 的 stellaris 板上的 Websockets

c# - 如何测试类在 C# 中是否正常工作?

c# - Xamarin:绑定(bind) ios 协议(protocol)/委托(delegate)无法访问 structs.cs 中定义的枚举

c# - 实现数据库搜索

c# - 将物理路径转换为 ​​web 路径 asp.net