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

SignalR WebSocket终端报错排查:网站可通信但终端持续报错

问题:SignalR WebSocket连接报错但功能正常

报错信息

"WebSocket failed to connect. The connection could not be found on the server, either the endpoint may not be a SignalR endpoint, the connection ID is not present on the server, or there is a proxy blocking WebSockets. If you have multiple servers check that sticky sessions are enabled"

尽管网站控制台无警告、能正常连接服务器,且可通过connectionId接收其他客户端消息、在ASP.NET中正常完成授权,但运行程序时终端始终弹出上述报错。

相关代码

Angular 客户端代码

public connect(): void {
    this.hubConnection = new signalR.HubConnectionBuilder()
      .withUrl(this.webSockeUrl, {
        transport: signalR.HttpTransportType.WebSockets,
        skipNegotiation:true,
        accessTokenFactory: () => { return this.token!},
      })
      .withAutomaticReconnect()
      .build();

    this.hubConnection
      .start()
      .then(() => console.log("Connection started"))
      .catch(err => console.error("Error establishing connection: ", err));
  }

  public addReceiveMessageListener(): void {
    this.hubConnection.on("ReceiveMessage", (message: string) => {
      console.log("Receive Message from server:", message);
    });

    this.hubConnection.on("ReceivePrivateMessage", (message: string) => {
      console.log("Receive Message from another client:", message);
    });
  }

ASP.NET 服务器端代码

[Authorize]
public class ChatHub : Hub
{
    public async Task SendMessage(string connectionId, string message)
    {
        await Clients.Client(connectionId).SendAsync("ReceivePrivateMessage", message);   
    }

    public override async Task OnConnectedAsync()
    {
        var connectionId = Context.ConnectionId;
        await Clients.All.SendAsync("ReceiveMessage", $"{connectionId} has joined");
    }
}

已尝试的解决方案

  • 移除skipNegotiation,但出现协商未完成问题
  • 添加服务器端口44398至防火墙入站规则
  • 开启Windows功能中的“WebSocket协议”
  • 查阅多篇相关文章并尝试方案,但报错仍未消除

建议的排查方向

  1. 排查自动重连的触发原因
    启用了withAutomaticReconnect(),终端的报错可能是重连过程中出现的临时失败。可以添加重连状态监听,确认报错是否来自重连阶段:

    this.hubConnection.onreconnecting(error => {
      console.error("Reconnecting failed: ", error);
    });
    this.hubConnection.onreconnected(connectionId => {
      console.log("Reconnected with connectionId: ", connectionId);
    });
    
  2. 确认WebSocket传输的配置兼容性
    强制指定WebSockets传输并开启skipNegotiation,需要确保服务器端配置完全支持无协商的WebSocket连接。检查服务器Startup/Program.cs中是否正确配置了SignalR:

    app.MapHub<ChatHub>("/chathub"); // 确保路由与客户端的webSockeUrl一致
    

    同时,若服务器使用HTTPS,需确认客户端的webSockeUrl是wss://开头而非ws://。

  3. 检查服务器端的连接日志
    在ASP.NET服务器端添加日志,查看连接断开的细节,确认是否有连接被意外断开后触发重连:

    public override async Task OnDisconnectedAsync(Exception? exception)
    {
        if (exception != null)
        {
            Console.WriteLine($"Connection {Context.ConnectionId} disconnected with error: {exception.Message}");
        }
        else
        {
            Console.WriteLine($"Connection {Context.ConnectionId} disconnected normally");
        }
        await base.OnDisconnectedAsync(exception);
    }
    
  4. 排查代理或SSL中间件影响
    即使防火墙规则已添加,若服务器部署在反向代理(如IIS、Nginx)之后,需确保代理已正确配置WebSocket支持:

    • IIS需确保WebSocket协议已启用,且站点的WebSocket设置未被禁用
    • 若使用Nginx,需在配置中添加WebSocket的转发规则
  5. 验证连接ID的有效性
    报错中提到“connection ID is not present on the server”,可以在客户端连接成功后,打印当前的connectionId,并在服务器端通过IHubContext<ChatHub>验证该ID是否存在于活跃连接列表中。

内容的提问来源于stack exchange,提问作者Long

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 22:39:54