ASP.NET Core 中的 WebSocket 支援(轉自MSDN)
本文介紹 ASP.NET Core 中 WebSocket 的入門方法。 WebSocket (RFC 6455) 是一個協議,支援通過 TCP 連線建立持久的雙向通道。 它用於從快速實時通訊中獲益的應用,如聊天、儀表板和遊戲應用。
系統必備
- ASP.NET Core 1.1 或更高版本
- 支援 ASP.NET Core 的任何作業系統:
- Windows 7/Windows Server 2008 或更高版本
- Linux
- macOS
- 如果應用在安裝了 IIS 的 Windows 上執行:
- Windows 8 / Windows Server 2012 及更高版本
- IIS 8 / IIS 8 Express
- 必須在 IIS 中啟用 WebSocket(請參閱 IIS/IIS Express 支援部分。)
- 如果應用在 HTTP.sys 上執行:
- Windows 8 / Windows Server 2012 及更高版本
何時使用 WebSocket
通過 WebSocket 可直接使用套接字連線。 例如,使用 WebSocket 可以讓實時遊戲達到最佳效能。
ASP.NET Core SignalR 是一個庫,可用於簡化嚮應用新增實時 Web 功能。 它會盡可能地使用 WebSocket。
如何使用 Websocket
- 安裝 Microsoft.AspNetCore.WebSockets 包。
- 配置中介軟體。
- 接受 WebSocket 請求。
- 傳送和接收訊息。
配置中介軟體
在 Startup 類的 Configure 方法中新增 WebSocket 中介軟體:
app.UseWebSockets();
可配置以下設定:
- KeepAliveInterval - 向客戶端傳送“ping”幀的頻率,以確保代理保持連線處於開啟狀態。
- ReceiveBufferSize - 用於接收資料的緩衝區的大小。 高階使用者可能需要對其進行更改,以便根據資料大小調整效能。
var webSocketOptions = new WebSocketOptions() { KeepAliveInterval = TimeSpan.FromSeconds(120), ReceiveBufferSize = 4 * 1024 }; app.UseWebSockets(webSocketOptions);
接受 WebSocket 請求
在請求生命週期後期(例如在 Configure 方法或 MVC 操作的後期,實際上下面的app.Use我覺得應該放在Configure 方法中的app.UseMvc之前,否則請求就被MVC的中介軟體先執行了),檢查它是否是 WebSocket 請求並接受 WebSocket 請求。
以下示例來自 Configure 方法的後期:
app.Use(async (context, next) => { if (context.Request.Path == "/ws") { if (context.WebSockets.IsWebSocketRequest) { WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync(); await Echo(context, webSocket); } else { context.Response.StatusCode = 400; } } else { await next(); } });
WebSocket 請求可以來自任何 URL,但此示例程式碼只接受 /ws 路徑的請求。
傳送和接收訊息
AcceptWebSocketAsync 方法將 TCP 連線升級到 WebSocket 連線,並提供 WebSocket 物件。 使用 WebSocket 物件傳送和接收訊息。
之前顯示的接受 WebSocket 請求的程式碼將 WebSocket 物件傳遞給 Echo 方法。 程式碼接收訊息並立即發回相同的訊息。 迴圈傳送和接收訊息,直到客戶端關閉連線:
private async Task Echo(HttpContext context, WebSocket webSocket) { var buffer = new byte[1024 * 4]; WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None); while (!result.CloseStatus.HasValue) { //個人覺得實際上可以將下面的webSocket.SendAsync方法放到一個Task裡面,來啟動另一個執行緒然後在內部不斷迴圈來處理髮送資料的任務,避免和下面的webSocket.ReceiveAsync輪流執行,從而提高效率 await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None); result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None); } await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None); }
如果在開始迴圈之前接受 WebSocket 連線,中介軟體管道會結束。 關閉套接字後,管道展開。 即接受 WebSocket 時,請求停止在管道中推進。 迴圈結束且套接字關閉時,請求繼續回到管道。
IIS/IIS Express 支援
安裝了 IIS/IIS Express 8 或更高版本的 Windows Server 2012 或更高版本以及 Windows 8 或更高版本支援 WebSocket 協議。
在 Windows Server 2012 或更高版本上啟用對 WebSocket 協議的支援:
- 通過“管理”選單或“伺服器管理器”中的連結使用“新增角色和功能”嚮導。
- 選擇“基於角色或基於功能的安裝”。 選擇“下一步”。
- 選擇適當的伺服器(預設情況下選擇本地伺服器)。 選擇“下一步”。
- 在“角色”樹中展開“Web 伺服器 (IIS)”、然後依次展開“Web 伺服器”和“應用程式開發”。
- 選擇“WebSocket 協議”。 選擇“下一步”。
- 如果無需其他功能,請選擇“下一步”。
- 選擇“安裝” 。
- 安裝完成後,選擇“關閉”以退出嚮導。
在 Windows 8 或更高版本上啟用對 WebSocket 協議的支援:
- 導航到“控制面板” > “程式” > “程式和功能” > “開啟或關閉 Windows 功能”(位於螢幕左側)。
- 開啟以下節點:“Internet Information Services” > “全球資訊網服務” > “應用程式開發功能”。
- 選擇“WebSocket 協議”功能。 選擇“確定”。
在 node.js 上使用 socket.io 時禁用 WebSocket
如果在 Node.js 的 socket.io 中使用 WebSocket 支援,請使用 web.config 或 applicationHost.config 中的 webSocket 元素禁用預設的 IIS WebSocket 模組。如果不執行此步驟,IIS WebSocket 模組將嘗試處理 WebSocket 通訊而不是 Node.js 和應用。
<system.webServer> <webSocket enabled="false" /> </system.webServer>