1. 程式人生 > >ASP.NET Core 中的 WebSocket 支持(轉自MSDN)

ASP.NET Core 中的 WebSocket 支持(轉自MSDN)

ocs 接收 緩沖 任務 ica uget 本地服務器 tcp msdn

本文介紹 ASP.NET Core 中 WebSocket 的入門方法。 WebSocket (RFC 6455) 是一個協議,支持通過 TCP 連接建立持久的雙向信道。 它用於從快速實時通信中獲益的應用,如聊天、儀表板和遊戲應用。

如果不明白什麽是WebSocket可以參考這篇文章

系統必備


  • 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 協議的支持:

  1. 通過“管理”菜單或“服務器管理器”中的鏈接使用“添加角色和功能”向導。
  2. 選擇“基於角色或基於功能的安裝”。 選擇“下一步”。
  3. 選擇適當的服務器(默認情況下選擇本地服務器)。 選擇“下一步”。
  4. 在“角色”樹中展開“Web 服務器 (IIS)”、然後依次展開“Web 服務器”和“應用程序開發”。
  5. 選擇“WebSocket 協議”。 選擇“下一步”。
  6. 如果無需其他功能,請選擇“下一步”。
  7. 選擇“安裝” 。
  8. 安裝完成後,選擇“關閉”以退出向導。

在 Windows 8 或更高版本上啟用對 WebSocket 協議的支持:

  1. 導航到“控制面板” > “程序” > “程序和功能” > “打開或關閉 Windows 功能”(位於屏幕左側)。
  2. 打開以下節點:“Internet Information Services” > “萬維網服務” > “應用程序開發功能”。
  3. 選擇“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>

原文鏈接

ASP.NET Core 中的 WebSocket 支持(轉自MSDN)