SignalR Core检测客户端或服务器是否关闭了连接

时间:2019-09-07 12:24:17

标签: c# asp.net-core signalr asp.net-core-2.1 asp.net-core-signalr

在ASP.NET Core 2.1 LTS上,有no automatically reconnect for SignalR。因此,我使用onclose event of the js client自己实现了它。在这种情况下,它有一个副作用:当客户端自身取消连接时,例如关闭浏览器选项卡时,客户端也会尝试重新连接。

重新连接将在短时间内起作用,直到关闭选项卡。由于在这种情况下我要在重新连接时重新加载通知以使用户保持最新状态,因此这是浪费资源的,因为我对关闭选项卡的用户执行了一些SQL查询。

let reconnectWaitTime = 5000
let client = new signalR.HubConnectionBuilder()
    .withUrl("/overviewHub")
    .build();
client.onclose(async (e) => {
    await tryReconnect(client)
    notificationsManager.handleReConnect()
})

await tryReconnect(client)
let notificationsManager = new ULNotificationsManager(client)

async function tryReconnect(client,) {
    try {
        let started = await client.start()
        return started;
    } catch (e) {
        await new Promise(resolve => setTimeout(resolve, reconnectWaitTime));
        return await tryReconnect(client)
    }
}

如何检测客户端或服务器是否关闭了连接,以便仅在服务器关闭连接后才能重新加载通知数据?

方法

According to the documentationError方法应有一个onclose回调:

client.onclose(function(ev){
    console.warn(ev)
})

我的想法是使用此错误来获取更详细的信息,例如使我可以过滤掉客户端中止的一些错误代码。但这似乎不起作用,我的日志中有undefined

1 个答案:

答案 0 :(得分:0)

更新

我的解决方案似乎并非在所有情况下都有效。例如。关闭dotnet控制台窗口时,没有例外,因此也没有重新连接。我认为在这种情况下,.NET Core可以正确关闭连接。

我尝试通过覆盖集线器的Dispose方法来解决此问题,在客户端上调用一些触发我重新连接的事件。运作不正常。我最终使用window.onbeforeunload事件来检测用户是否离开了

window.onbeforeunload = function () {
    window.userIsNavigatingAway = true
    return
};

并检查此布尔值而不是关闭错误

client.onclose(async (error) => {
    // https://stackoverflow.com/a/57833660/3276634
    if (!window.userIsNavigatingAway) {
        await tryReconnect(client, initialReConnectWaitTime)
        console.log('ReConnect worked')
        notificationsManager.handleReConnect()
    } else {
        console.log("Client closed the WS connection, so no reconnect attemp is made")
    }
})

原始answear

这仅在服务器被意外终止时有效

发现错误回调涉及服务器端问题:当服务器中止连接(例如服务器重新启动)时,我得到一个Error对象:

 Error: "WebSocket closed with status code: 1006 ()."

因此,通过检查错误是否未定义,可以轻松解决我的问题:

client.onclose(async (error) => {
    if (typeof error !== 'undefined') {
        await tryReconnect(client)
        notificationsManager.handleReConnect()
    } else {
        console.log("Client closed the WS connection, so no reconnect attemp is made")
    }
})

当客户端失去网络连接(例如在移动设备上)时,我将不得不尝试这种方法是否还能正常工作,在这种情况下重新连接会很有用。