最近在测试的时候发现,用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来实现。