关于启用sessionState外部存储,导致IHttpAsyncHandler长连接阻塞线程的问题

最近在做asp.net长连接,用于消息的及时推送,方案如下:

1. 前端页面用jquery.ajax请求长连接页面comet.ashx

     当后台成功返回时继续递归请求comet.ashx,不过这里要注意,如果是后台异常,最好休眠1分钟再尝试重新连接,否则就会疯狂访问已经异常的comet.ashx

2. 后端长连接页面, comet.ashx 继承自IHttpAsyncHandler(异步处理),IRequiresSessionState(需要获取登陆状态);

     当有消息时,立即返回消息;如果1分钟都没有新消息,则返回空消息,以防前端异常退出,导致资源不能释放;

3. web.config配置session存储器为StateServer,<sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" timeout="60"/>


以上3步做好后,F5运行,结果包含以上几个页面以外,其他页面全部都打不开,浏览器一直显示加载中。。。

很明显,线程全部被阻塞了,网上查资料未果,折腾了2天

从网上下了一个类似的应用叫 aspComet:https://github.com/nmosafi/aspcomet,是asp.net长链接的经典应用,发现这个应用根本没有阻塞问题

于是判断是配置文件问题,于是通过不断删除web.config的结点,终于发现在删除了session配置<sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" timeout="60"/>节点这后,网站正常了


之前一直对asp.net的session机制不太了解,只知道用默认的配置,session很容易丢失。后来听说配置为外部存储之后,可以解决丢失问题,于是就配置成了StateSever,果然如此,后来也就没再深入了解session的用法。

而这次长连接的坑,让我重新了解了session的用法。《 会话状态Session》这篇文章写得很详细。

其实这个坑的原理很简单,因为asp.net或者mvc默认情况下,页面都是启用读写锁

而comet.ashx继承了IRequiresSessionState,也是启用了session读写锁,当会话开始的时候,comet.ashx便得到一个读写锁,但这个线程一直不结束,这个锁便无法释放,从而导致其他页面无法得到session锁,也就一直阻塞。


解决方法很有几种:

1,不启用外部session存储器,显示这种做法不合适,特别是对session有比较高的需求时

2,comet.ashx删除IRequiresSessionState接口,这样comet.ashx无法读写session

3,comet.ashx删除IRequiresSessionState接口,改为继承IReadOnlySessionState接口,这样可以保证comet.ashx可以读取session,但不能修改session


其实这个坑不仅仅存在长连接。只要启用了session外部存储,就会导致同一会话的并发阻塞问题。

可以做以下试验

1. 做两个页面:test1.aspx、test2.aspx

2. test1.aspx直接 Response.Write("test1");

3. test2.aspx,    Response.Write("test2");Thread.Sleep(60000);//模拟长时间处理的程序

4. 在同一浏览器,先打开test2.aspx,再打开test1.aspx,会发现test1.aspx会阻塞60秒才显示出来

这是因为test2.aspx处理时间较长,阻塞了test1.aspx


注意:以上的坑都是基于同一会话的,通俗地讲就是针对当前浏览器打开的页面。而不同浏览器打开相当于不同的会话,不同会话的sessionid是不一样的,而session读写锁是针对同一sessionid的。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值