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

使用SignalR实现一对一聊天跳转时连接状态异常问题求助

解决SignalR Hub连接未就绪时调用方法的问题

你的核心问题是**window.onload仅确保脚本文件加载完成,但SignalR Hub的连接是异步建立的**,所以当执行notificationsConnection.invoke()时,Hub还没完成握手,导致连接状态异常。以下是具体解决思路:

1. 等待SignalR Hub连接成功后再执行业务逻辑

SignalR的HubConnection提供了状态监听和异步链式调用,你需要确保在连接进入Connected状态后再调用invoke方法:

方案A:直接检查连接状态并等待

在顾问角色的逻辑中,先判断连接状态,未就绪则等待连接完成后执行:

window.addEventListener('load', function() {
    var chatId = document.cookie
    var chatDB = "@ViewData["ChatDb"]";
    var consultorId = "@ViewData["ConsultorId"]";
    var userId = "@ViewData["UserId"]";

    // 封装要执行的业务逻辑
    const sendToChat = () => {
        notificationsConnection.invoke("SendUserToChat", userId, chatId, chatDB)
            .catch(err => console.error("调用SendUserToChat失败:", err));
    };

    // 检查当前连接状态
    if (notificationsConnection.connectionState === signalR.ConnectionState.Connected) {
        sendToChat();
    } else {
        // 若未连接,启动连接后执行逻辑
        notificationsConnection.start()
            .then(sendToChat)
            .catch(err => console.error("Notifications Hub连接失败:", err));
    }
});

方案B:在notifications.js中统一管理连接就绪回调

可以在Hub初始化脚本中统一处理连接逻辑,对外暴露回调接口,避免重复代码:

// notifications.js 中的代码
const notificationsConnection = new signalR.HubConnectionBuilder()
    .withUrl("/notificationsHub")
    .build();

// 存储连接就绪后的回调队列
const readyCallbacks = [];

// 启动连接并触发回调
notificationsConnection.start()
    .then(() => {
        console.log("Notifications Hub连接成功");
        readyCallbacks.forEach(cb => cb());
    })
    .catch(err => console.error("Notifications Hub连接失败:", err));

// 对外暴露添加回调的方法
window.onNotificationsReady = function(callback) {
    if (notificationsConnection.connectionState === signalR.ConnectionState.Connected) {
        callback();
    } else {
        readyCallbacks.push(callback);
    }
};

然后在页面脚本中调用:

@if(User.IsInRole(Constantes.userRoleConsultor))
{
    @:window.addEventListener('load', function() {
        @:var chatId = document.cookie
        @:var chatDB = "@ViewData["ChatDb"]";
        @:var consultorId = "@ViewData["ConsultorId"]";
        @:var userId = "@ViewData["UserId"]";

        @:onNotificationsReady(function() {
            @:notificationsConnection.invoke("SendUserToChat", userId, chatId, chatDB)
                @:.catch(err => console.error("调用失败:", err));
        @:});
    @:});
}

2. 修复window.onload的覆盖问题

当前代码中两个@if块直接赋值window.onload,若角色判断逻辑出现重叠(虽理论上不会),会导致后写的逻辑覆盖前者。建议改用addEventListener绑定load事件,确保多个逻辑都能执行:

// 替换 window.onload = function() {} 的写法
window.addEventListener('load', function() {
    // 业务逻辑代码
});

3. 排查SignalR连接初始化问题

检查notifications.js中的基础初始化代码:

  • 确认withUrl指向的Hub端点路径正确
  • 确保没有遗漏start()方法的调用
  • 添加连接断开后的重连逻辑,提升稳定性:
notificationsConnection.onclose(async () => {
    console.log("Notifications Hub连接断开,尝试重连...");
    await new Promise(resolve => setTimeout(resolve, 5000)); // 等待5秒后重连
    notificationsConnection.start()
        .catch(err => console.error("重连失败:", err));
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 11:43:17