You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET WebAPI中SignalR无法通过WebSocket/SSE连接,仅LongPolling可用

问题分析与解决方案

一、WebSocket返回200而非101的核心排查点

  • 确认站点级WebSocket模块启用:别只看服务器全局设置,得针对你的站点单独开启。操作步骤:
    1. 打开IIS管理器,选中目标站点
    2. 右侧功能视图找到「WebSocket协议」,双击查看状态——如果是灰色,说明没给该站点启用
    3. 点击「启用」,然后重启站点
  • 移除WebDAV模块:WebDAV会直接拦截WebSocket的Upgrade请求并返回200,在web.config中添加以下配置移除它:
    <system.webServer>
      <modules>
        <remove name="WebDAVModule" />
      </modules>
    </system.webServer>
    
    同时确保ASP.NET Core模块为V2版本,web.config中的handler节点配置正确:
    <handlers>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
    </handlers>
    
  • SSL/绑定检查:使用HTTPS时,站点绑定的SSL设置里「客户端证书」要设为「忽略」——强制要求客户端证书会直接破坏握手流程;使用HTTP时,检查站点绑定端口未被占用,且IIS「请求筛选」中允许Upgrade方法

二、SSE握手错误的解决思路

  • CORS策略放开SSE相关响应头:跨域场景下,Startup/Program.cs中的CORS策略必须暴露SSE所需的响应头,否则客户端会拦截握手响应。示例代码:
    builder.Services.AddCors(options =>
    {
        options.AddPolicy("AllowSignalR", policy =>
        {
            policy.WithOrigins("https://你的客户端域名")
                  .AllowAnyHeader()
                  .AllowAnyMethod()
                  .AllowCredentials()
                  .WithExposedHeaders("X-AspNetCore-SignalR-Protocol", "X-AspNetCore-Transport-Type", "Transfer-Encoding", "Connection");
        });
    });
    
  • 禁用IIS输出缓存:IIS输出缓存会缓存SSE的分块响应,直接导致握手失败。可以在站点「输出缓存」功能中添加规则排除Hub路径(比如/hubs/*),或者直接在web.config中配置:
    <system.webServer>
      <caching>
        <profiles>
          <add extension="*" policy="DisableCache" kernelCachePolicy="DisableCache" />
        </profiles>
      </caching>
    </system.webServer>
    

三、防火墙与网络层补充排查

  • Windows防火墙放行端口:除了确认80/443端口开放,还要确保防火墙未拦截Upgrade方法的请求。用PowerShell检查相关规则:
    Get-NetFirewallRule | Where-Object {$_.DisplayName -like "*WebSocket*"}
    
    若没有对应规则,手动添加允许站点端口的入站HTTP/HTTPS请求即可
  • 反向代理/负载均衡配置:如果站点前端有代理(比如Nginx、Azure网关),必须配置代理支持WebSocket和SSE:
    • WebSocket:需传递Upgrade、Connection、Sec-WebSocket-Key等头部
    • SSE:需设置Connection: keep-alive和Transfer-Encoding: chunked,同时禁用响应缓存

四、日志与调试技巧

  • 开启SignalR详细日志:在Program.cs中添加以下配置,捕获握手过程的详细错误:
    builder.Logging.AddFilter("Microsoft.AspNetCore.SignalR", LogLevel.Debug);
    builder.Logging.AddFilter("Microsoft.AspNetCore.Http.Connections", LogLevel.Debug);
    
    随后查看服务器的stdout日志或Windows事件查看器,定位WebSocket握手失败的具体原因
  • 浏览器开发者工具抓包:在客户端浏览器的「网络」标签中,查看WebSocket请求的响应头——如果没有Upgrade: websocket和Connection: Upgrade,说明IIS或代理未正确处理请求

内容的提问来源于stack exchange,提问作者Yusuf Mert Çelikarslan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 09:22:10