【问题标题】:SignalR Core detect if connection is closed by client or serverSignalR Core 检测连接是否被客户端或服务器关闭
【发布时间】:2019-09-09 06:06:10
【问题描述】:

在 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 documentation,onclose 方法应该有一个Error 回调:

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

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

【问题讨论】:

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


    【解决方案1】:

    更新

    我的解决方案似乎不适用于所有情况。例如。当dotnet 控制台窗口关闭时,没有异常,因此也没有重新连接。我假设 .NET 核心在这种情况下正确关闭了连接。

    我尝试通过覆盖集线器的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")
        }
    })
    

    原创回答

    这只有在服务器被意外终止时才有效。

    发现错误回调指的是服务器端问题:当连接被服务器中止(例如服务器重启)时,我得到一个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")
        }
    })
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-30
      • 2019-05-20
      • 2014-05-26
      • 2018-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多