最近在測試的時候發現,用SignalR做的實時消息推送程序,部署在IIS上之后間隔一定時間(大概間隔在25-28小時之間)就會斷開連接。因為做了異常捕獲,但是每次斷開的那個時間點都沒有異常日志,所以猜測可能不是程序BUG造成的斷開。在網上查了下,估計是iis回收的問題。
“IIS為優化服務器性能,會自動對它認為休眠的應用程序(如長時間無人訪問)進行資源回收,資源回收時將會導致網站應用程序關閉。”
所以做了個實驗:手動回收一次應用程序池,果然連入Hub中的鏈接都斷開了。
為防止IISHost的SignalR程序因為iis回收機制導致鏈接中斷,最容易想到的辦法就是當IIS回收之后進行一次reconnect。
方法一:
在Global.asxs的Application_End事件中讓SignalRClient重連
protectedvoidApplication_End(objectsender,EventArgse)
{
//在應用程序關閉時運行的代碼
//解決應用池回收問題
System.Threading.Thread.Sleep(2000);
HitPage();
}
IIS回收時Application_End會被觸發,當站點程序關閉2秒后,執行HitPage()方法,該方法的作用是產生一個針對本站點的Http請求,IIS將會再次開啟WEB應用程序。
方法二:
定時發出http請求方式閑時回收,并指定iis程序池回收時間點。
首先在global里設置一個循環,間隔一定時間(如1個小時),觸發HitPage()事件,目的是為了讓iis以為本站點不是閑置的。
然后設置IIS的回收條件,將默認的間隔27小時自動回收一次,改成指定時間回收(比如凌晨4點)。

然后還需在站點中設置一個定時任務,那就是在4點中(即上一部設置的iis應用程序池回收時間點)重新connect一次signalRHub。
另外補充一句,方法二中可以使用timer,也可以用quartz來實現。