SignalR客户端在重新连接后不接收消息

时间:2017-01-11 14:40:10

标签: c# asp.net asp.net-mvc signalr

我正在使用带有javascript客户端的signalR,为Web应用程序后端的长期运行的PowerShell任务提供进度条。在任务启动后排序,它会导致应用程序池回收(这会在调用powershell时发生,我似乎无法解决此问题),signalR执行重新连接,这看起来很成功,但进度消息停止了通过。如果我调试路径,逐步执行代码,消息仍然来自powershell,并且广播被调用,但客户端没有收到任何内容。

启动:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.MapSignalR();
    }
}

集线器:

public class ProgressHub : Hub
{
    public void SendProgress(string progressMessage, int progressCount)
    {
        var hubContext = GlobalHost.ConnectionManager.GetHubContext<ProgressHub>();

        hubContext.Clients.All.AddProgress(progressMessage, progressCount);
    }
}

客户端:

var progress = $.connection.progressHub;
console.log(progress);

progress.client.addProgress = function (message, percentage) {

    $('#actionDetail').html(message);

    $("#progressBar").progressbar({
        value: percentage
    });             
};

$.connection.hub.logging = true;
$.connection.hub.start().done(function () {

    var connectionId = $.connection.hub.id;
    console.log(connectionId);
});

客户端日志:

[10:07:40 GMT+0000 (GMT Standard Time)] SignalR: serverSentEvents transport starting.
jquery?v=WM6erXjzG36po83czfGO2Wf5wbUN0yj0TfE47rwndb41:1 
[10:07:40 GMT+0000 (GMT Standard Time)] SignalR: Attempting to connect to SSE endpoint 'http://2012r2-en-09:7750/signalr/connect?transport=serverSentEvents&clientP…BoA%3D%3D&connectionData=%5B%7B%22name%22%3A%22progresshub%22%7D%5D&tid=10'.
jquery?v=WM6erXjzG36po83czfGO2Wf5wbUN0yj0TfE47rwndb41:1 
[10:07:40 GMT+0000 (GMT Standard Time)] SignalR: EventSource connected.
jquery?v=WM6erXjzG36po83czfGO2Wf5wbUN0yj0TfE47rwndb41:1 
[10:07:40 GMT+0000 (GMT Standard Time)] SignalR: serverSentEvents transport connected. Initiating start request.
jquery?v=WM6erXjzG36po83czfGO2Wf5wbUN0yj0TfE47rwndb41:1 
[10:07:40 GMT+0000 (GMT Standard Time)] SignalR: The start request succeeded. Transitioning to the connected state.
jquery?v=WM6erXjzG36po83czfGO2Wf5wbUN0yj0TfE47rwndb41:1 
[10:07:40 GMT+0000 (GMT Standard Time)] SignalR: Now monitoring keep alive with a warning timeout of 13333.333333333332, keep alive timeout of 20000 and disconnecting timeout of 30000
VM145:1 718e2f95-4950-4350-8dff-4b7cb9f1158a
jquery?v=WM6erXjzG36po83czfGO2Wf5wbUN0yj0TfE47rwndb41:1 
[10:07:46 GMT+0000 (GMT Standard Time)] SignalR: EventSource readyState: 0.
jquery?v=WM6erXjzG36po83czfGO2Wf5wbUN0yj0TfE47rwndb41:1 
[10:07:46 GMT+0000 (GMT Standard Time)] SignalR: EventSource reconnecting due to the server connection ending.
jquery?v=WM6erXjzG36po83czfGO2Wf5wbUN0yj0TfE47rwndb41:1 
[10:07:48 GMT+0000 (GMT Standard Time)] SignalR: EventSource calling close().
jquery?v=WM6erXjzG36po83czfGO2Wf5wbUN0yj0TfE47rwndb41:1 
[10:07:48 GMT+0000 (GMT Standard Time)] SignalR: serverSentEvents reconnecting.
jquery?v=WM6erXjzG36po83czfGO2Wf5wbUN0yj0TfE47rwndb41:1 
[10:07:48 GMT+0000 (GMT Standard Time)] SignalR: Attempting to connect to SSE endpoint 'http://2012r2-en-09:7750/signalr/reconnect?transport=serverSentEvents&messa…SBoA%3D%3D&connectionData=%5B%7B%22name%22%3A%22progresshub%22%7D%5D&tid=7'.
jquery?v=WM6erXjzG36po83czfGO2Wf5wbUN0yj0TfE47rwndb41:1 
[10:07:50 GMT+0000 (GMT Standard Time)] SignalR: EventSource connected.
VM145:1 718e2f95-4950-4350-8dff-4b7cb9f1158a
5jquery?v=WM6erXjzG36po83czfGO2Wf5wbUN0yj0TfE47rwndb41:1 
[10:07:59 GMT+0000 (GMT Standard Time)] SignalR: Triggering client hub event 'AddProgress' on hub 'ProgressHub'.
jquery?v=WM6erXjzG36po83czfGO2Wf5wbUN0yj0TfE47rwndb41:1 
[10:08:06 GMT+0000 (GMT Standard Time)] SignalR: EventSource readyState: 0.
jquery?v=WM6erXjzG36po83czfGO2Wf5wbUN0yj0TfE47rwndb41:1 
[10:08:06 GMT+0000 (GMT Standard Time)] SignalR: EventSource reconnecting due to the server connection ending.
jquery?v=WM6erXjzG36po83czfGO2Wf5wbUN0yj0TfE47rwndb41:1 
[10:08:08 GMT+0000 (GMT Standard Time)] SignalR: EventSource calling close().
jquery?v=WM6erXjzG36po83czfGO2Wf5wbUN0yj0TfE47rwndb41:1 
[10:08:08 GMT+0000 (GMT Standard Time)] SignalR: serverSentEvents reconnecting.
jquery?v=WM6erXjzG36po83czfGO2Wf5wbUN0yj0TfE47rwndb41:1 
[10:08:08 GMT+0000 (GMT Standard Time)] SignalR: Attempting to connect to SSE endpoint 'http://2012r2-en-09:7750/signalr/reconnect?transport=serverSentEvents&messa…SBoA%3D%3D&connectionData=%5B%7B%22name%22%3A%22progresshub%22%7D%5D&tid=9'.
jquery?v=WM6erXjzG36po83czfGO2Wf5wbUN0yj0TfE47rwndb41:1 
[10:08:10 GMT+0000 (GMT Standard Time)] SignalR: EventSource connected.
VM145:1 718e2f95-4950-4350-8dff-4b7cb9f1158a

从日志中,您可以看到在初始连接之后,执行了重新连接,在此之后,消息仍然继续通过。它是在第二个应用程序池被回收之后停止的。

有类似的问题,例如:SignalR client is reconnected after Owin restart, but message is not published但是,尝试解决方案提到他甚至在重新连接之前就停止了所有消息。

2 个答案:

答案 0 :(得分:0)

  1. 请求任务后,应将task-id返回给客户端。
  2. 将任务ID存储在客户端(本地存储或cookie)中的某个位置,并且在重新连接时,您必须订阅该任务ID的进度。

ps:即使用户意外重新加载页面,您也将需要此功能。

答案 1 :(得分:0)

当 SignalR 断开连接并通过完全重新创建 signalR 集线器对象在客户端解决问题时,我们遇到了同样的问题:

// SignalR disconnected callback:
$.connection.hub.disconnected(() => {
    setTimeout(() => {
        // Reset the SignalR hub and recreate the hub proxies:
        $.signalR.hub = null;
        $.signalR.hub = $.hubConnection('/signalr', { useDefaultPath: false });
        $.extend($.signalR, $.signalR.hub.createHubProxies());

        // Re-subscribe to your events:
        $.connection.myHub.client.onMessage = message => {
            console.log(`onMessage[MyHub]: ${message}`);
        };
        
        // SignalR restart:
        $.connection.hub.start();
    }, 5000);
});

我们在日志中看到,我们的 onMessage 函数在断开连接(并且应该重新连接)后没有被触发,因此重新创建集线器连接并在再次连接之前调用 createHubProxies() 有效。我们通过使触发 disconnected() 函数的连接超时(在服务器代码中的某处添加断点)在本地对此进行了测试。