Unexpected Signalr connection abort in Firefox

2019-04-29 00:09发布

I am using SignalR (with cross-domain request), version 2.3.0 for webchat integrated to ASP.NET site. Everything is working fine. But I found strange behaviour of SignalR connection. When I clicked to the reference from tab of the chat for file downloading SignalR connection was aborted and onDisconnected method was triggered in my Hub class. FireBug show me next POST-request:

http://*:81/signalr/abort?transport=longPolling&clientProtocol=1.4&token=eUpLNitKcmR1d2JhTTRvcHNVZmEwcG1EKzYvMElZbmg4aE5yam9xM3k0dz0_IjAsNGJmOWNhODUtNDU2NS00NWExLWFjMTgtNzgyN2FhZDA2Njg1LGxvY2FsaG9zdCI1&State=1&connectionToken=hDXe9xIZtmrapjl1LRwtK9B%2BfYMoeuHka8ctBLaPa0YnjiN9iiFa%2BvFMBHIGpGH0h8qPEDgGZSRGwjMw3Wm1DJi6cUPtZjLca6%2FR2576SGksLAj3lnPN1JWIlxMsn8%2Bf&connectionData=%5B%7B%22name%22%3A%22c%22%7D%2C%7B%22name%22%3A%22voip%22%7D%5D, where * is my domain.

It is reproduced in Mozilla Firefox (version 30.0) for LongPolling or Websocket transports. How I can fix this problem? Or is it bug of SignalR or Firefox?

2条回答
Evening l夕情丶
2楼-- · 2019-04-29 00:15

This bug has been recently filed against SignalR on GitHub. The basic idea is that downloading a file causes Firefox to trigger the window.onbeforeunload event which in turn causes SignalR to close any ongoing connections.

For now, the workaround is to attach a handler to the client's disconnected event that will call $.connection.start again after a short window.setTimeout.

You could also unbind SignalR's onbeforeunload handler: $(window).unbind("beforeunload"). The downside of doing this is that Firefox might not gracefully disconnect when the user leaves the page running SignalR. Without a graceful disconnect, SignalR will wait over 30 seconds before it times out the client and calls the OnDisconnected handler on the Hub or PersistentConnection.

查看更多
我命由我不由天
3楼-- · 2019-04-29 00:34

I have managed to use the workaraound explained by halter73 and I have solved the issue described by dudeNumber4 resetting the connectionid inside the disconnect event so that the server kept calling back the right users based on their connectionid without the need to address them by their user or group names.

$.connection.hub.disconnected(function () {
    setTimeout(function () {
        $.connection.hub.start().done(function () {
            $("#mySignalRConnectionIdHidden").val($.connection.hub.id);
        });
    }, 3000);  
});
查看更多
登录 后发表回答