【发布时间】:2016-02-22 12:48:00
【问题描述】:
有没有人在 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: 我已经注意到一个缺点 - 当 while(true) 存在时(为了简单起见,上面的示例中没有显示,比如说,当频道需要关闭),方法需要返回一些东西(任务)。它应该是什么? HTTP 200 状态响应?我猜不是,因为在 WebSockets 文档中写到,在“关闭”帧之后什么都不应该发送。
更新 3: 我学到了一件事,那就是如果你想在 Windows 10 上使用 IIS Express 10.0 在 Visual Studio 2015 中调试时让 WebSockets 工作,你仍然必须使用 @987654321 @ 并在 Startup.cs 文件中配置 app.UseWebSockets()。否则,IsWebSocketRequest 将为 false。有谁知道为什么?握手?
【问题讨论】:
-
使用 SignalR asp.net/signalr
-
我已经成功地将 websocketsharp 与 MVC6 / MVC Core 1.0 / 本周他们称之为的任何东西混合在一起。事情不通过 OWIN 中间件管道,但您可以在不同的端口上运行 Web 套接字服务器并让它为 WS 连接提供服务。只是思考的食物。
-
未验证,但我怀疑“最正确”的方法是定义您自己的
IActionResult自定义实现,并在其ExecuteResultAsync方法中使用 websocket 循环。然后控制器只返回一个实例。 -
我只是这样做了——我将 websocket 处理循环放在自定义 IActionResult 类的 ExecuteResultAsync 中。这避免了其他中间件尝试在 OnStartup 中设置内容但已发送标头的问题。
-
能否请您与我们分享您的最终实现,了解您是如何在 asp.net MVC 5 的操作方法中运行 WebSocket 的?
标签: c# asp.net-mvc websocket asp.net-core asp.net-core-mvc