普通网友 2025-07-05 14:20 采纳率: 98.7%
浏览 1
已采纳

问题:.NET 8 配置 WebSocket 出现握手失败如何解决?

在使用 .NET 8 配置 WebSocket 时,常会遇到“握手失败”的问题。常见原因之一是未正确配置中间件顺序,导致 WebSocket 请求被其他中间件拦截或拒绝。此外,未设置合适的请求头(如 `Upgrade` 和 `Connection`)也可能引发握手失败。还可能是服务器未启用 WebSocket 协议支持,或客户端使用的 URL 协议未正确指定为 `ws://` 或 `wss://`。解决方法包括:确保在 `Program.cs` 中正确使用 `UseWebSockets()` 中间件并置于管道前端、检查请求头是否符合规范、确认服务器已启用 WebSocket 协议,并使用正确的 URL 格式进行连接。
  • 写回答

1条回答 默认 最新

  • 希芙Sif 2025-07-05 14:20
    关注

    深入解析 .NET 8 中 WebSocket 握手失败问题

    在构建基于 .NET 8 的实时通信应用时,WebSocket 是一种常用的技术手段。然而,在配置过程中,“握手失败”是一个常见的问题,可能由多个因素导致。本文将从浅入深、由表及里地分析该问题的成因,并提供系统性的排查和解决方法。

    1. 初步认识 WebSocket 握手流程

    WebSocket 握手本质上是 HTTP 协议的一个升级过程。客户端发送一个带有 Upgrade: websocketConnection: Upgrade 请求头的 HTTP 请求,服务器识别后返回 101 Switching Protocols 响应,从而完成协议切换。

    GET /ws HTTP/1.1
    Host: example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Sec-WebSocket-Version: 13

    2. 握手失败的常见原因

    • 中间件顺序错误:未将 UseWebSockets() 放置在管道前端,导致请求被其他中间件(如静态文件中间件)提前处理。
    • 请求头不完整或错误:缺少必要的 UpgradeConnection 头信息。
    • 服务器未启用 WebSocket 协议支持:某些托管环境(如 IIS Express 或反向代理)未正确配置 WebSocket。
    • URL 协议格式错误:客户端使用了 http:// 而非 ws://wss://

    3. 排查与解决步骤详解

    3.1 确保中间件顺序正确

    .NET 中间件管道是按添加顺序执行的。若在 UseWebSockets() 之前有中间件拦截了 WebSocket 请求(例如 UseStaticFiles()),会导致握手失败。

    // Program.cs 示例
    var builder = WebApplication.CreateBuilder(args);
    builder.Services.AddWebSockets();
    
    var app = builder.Build();
    app.UseWebSockets(); // 必须置于其他可能拦截请求的中间件之前
    app.Use(async (context, next) =>
    {
        if (context.WebSockets.IsWebSocketRequest)
        {
            var webSocket = await context.WebSockets.AcceptWebSocketAsync();
            await EchoWebSocket(webSocket);
        }
        else
        {
            await next(context);
        }
    });
    app.Run();

    3.2 检查请求头是否符合规范

    确保客户端发起的 WebSocket 请求包含如下必要头部字段:

    Header NameExpected Value
    Upgradewebsocket
    ConnectionUpgrade
    Sec-WebSocket-KeyBase64 encoded random string
    Sec-WebSocket-Version13

    3.3 验证服务器端是否启用 WebSocket 支持

    在 Kestrel 上默认已启用 WebSocket。但在某些部署环境中(如 IIS Express、Kubernetes Ingress、Nginx 反向代理等),需要额外配置。

    graph TD A[Client Connects via ws:// or wss://] --> B{Server Accepts Connection?} B -- No --> C[Check Server Configuration] B -- Yes --> D{WebSocket Middleware Enabled?} D -- No --> E[Enable UseWebSockets()] D -- Yes --> F{Headers Correct?} F -- No --> G[Fix Headers] F -- Yes --> H[Handshake Success]

    3.4 使用正确的 URL 格式连接

    客户端必须使用 ws://(非加密)或 wss://(加密)协议进行连接。如果误用 http://,则不会触发 WebSocket 握手。

    // 客户端示例
    const socket = new WebSocket('wss://yourdomain.com/ws');
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 10月23日
  • 创建了问题 7月5日