2014-05-18 147 views
1

每當我的應用程序被重置時,signalR會斷開連接但不會重新連接。SignalR斷開連接並且不會重新連接

我有一個長時間運行的服務器任務,在每個任務完成時向客戶端發送更新。

​​

上述代碼時停止應用程序被複位發送更新(ⅰ可以模擬通過觸摸的web.config這個問題)。

我想重新連接到客戶端的方式。目前用戶必須重新加載頁面以便再次獲取更新。

這裏是我的樞紐定義

public class ForceHub : Hub 
{ 
    public void MessageSent(string text) 
    { 
     GetContext().Clients.All.sent(text); 
    } 

    public void UpdateStatus(string msg) 
    { 
     GetContext().Clients.All.status(msg); 
    } 

    IHubContext GetContext() 
    { 
     return GlobalHost.ConnectionManager.GetHubContext<ForceHub>(); 
    } 
    public override Task OnConnected() 
    { 
     try { 
      IoC.Resolve<ILogger>().Info("SignalR Connected -----------"); 
     }catch (Exception){} 

     return base.OnConnected(); 
    } 

    public override Task OnDisconnected() 
    { 
     try { 
      IoC.Resolve<ILogger>().Info("SignalR Disconnected -----------"); 
     } 
     catch (Exception) { } 
     return base.OnDisconnected(); 
    } 

    public override Task OnReconnected() 
    { 
     try { 
      IoC.Resolve<ILogger>().Info("SignalR Re-Connected -----------"); 
     } 
     catch (Exception) { } 
     return base.OnReconnected(); 
    } 
} 

我可以看到連接重新接活動啓動後觸發,但是觸摸web.config文件之後,我看不到任何這些事件觸發。

我試圖在客戶端上趕上這一點,但這一事件不會tirggered:

$.connection.hub.disconnected(function() { 
    console.error('signalR disconnected, retrying connection'); 
    logError('Signal lost.'); 
    setTimeout(function() { connection.start(); }, 1000); 
}); 

更新

我也鉤入狀態改變事件,該事件被觸發,但再下面的連接嘗試不起作用。

 $.connection.hub.stateChanged(function (state) { 
      console.debug('signalR state changed', state); 
      if (state.newState == 1) { 
       console.debug('restarting'); 
       setTimeout(function() { $.connection.hub.start(); }, 1000); 
      } 
     }); 

此事件被觸發兩次:newState是2,然後1

+0

它看起來像一個有趣的案例,我想攝製它,但我不能。我沒有嘗試長時間運行的任務,但有一個簡單的附加頁面,其代碼在用GET命中時向所有客戶端發送消息。這模擬了一個「帶外」工作,即使在應用程序重置後,它也能正常工作,客戶端得到正常通知。我會說SignalR不會失去連接(這就是爲什麼你沒有看到事件)......也許問題在別的地方? – Wasp

+0

@Wasp是否嘗試修改web.config? –

+0

當然,我是這樣做的請求之間我的「工作」頁面 – Wasp

回答

0

我可能有一個線索...觸摸的Web.config產生程序池回收,這意味着一個新的工作進程爲新的請求創建,而現有的過程將持續一段時間,直到剩餘的請求結束或達到超時。在超時期限內未結束的請求被終止。

Signalr客戶端重新連接到新的過程,而長期運行的任務是在舊的進程中運行,所以當在長時間運行的任務,你做

GlobalHost.ConnectionManager.GetHubContext<ForceHub>(); 

你實際上得到的「老」樞紐而基準客戶端連接到「新」集線器。 這就是爲什麼由Wasp執行測試的原因:他發出了一個新的請求,在新創建的工作進程中處理的信號中心上發佈。

您可以嘗試配置信號背板(https://www.asp.net/signalr/overview/performance/scaleout-in-signalr),使用Sql Server(https://www.asp.net/signalr/overview/performance/scaleout-with-sql-server)配置它非常容易。背板應該能夠連接兩個工作進程,並希望您能夠在客戶端獲得通知。

如果出現這種問題,即使沒有底板,由新請求生成的通知也可以正常工作。請注意,背板的真正目的是擴展信號發生器,即在它們之間連接一個WebServers場。

另外請記住,在IIS內部運行長時間運行的任務非常難以實現,因爲IIS會定期執行appPool回收操作並對請求執行超時限制。我建議你閱讀以下文章:http://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx 「如果你認爲自己可以寫一個背景任務,那很可能你會錯誤的。我不是在質疑你的技能,我只是說它很微妙。另外,你爲什麼要這樣嗎?」

希望這有助於

+0

這聽起來正確:)多年來沒有觸及該代碼。我同意IIS中長時間運行的任務並不理想。我能夠將執行時間降低到1-30分鐘,這個時間仍然很長,但在過去幾年中一直可以管理。謝謝! –

相關問題