PHP的session阻塞机制带来的单页面多ajax请求阻塞的解决

4 篇文章 0 订阅

遇到一个有意思的问题:

比如在一个页面中,有两个不同的ajax请求,分别在两个函数中调用去请求,前一个ajax是长轮询的请求。后一个ajax是每隔几秒执行一次,负责读取前一个ajax执行的日志,并把读到的日志内容显示在当前页面的某一个div中。

问题很简单,但意外发生了。

前面的ajax请求开始执行后,日志内容也正常不断的生成。但后一个ajax定时去取日志却总也取不到,看到的现象是没反应。直到第一个ajax请求执行结束,日志内容才一下子全部被读出,显示在div中,这显示不是想要的结果,想要的是在第一个ajax请求在执行过程中,就拿到执行日志并显示。

这个奇怪了,怎么会取不到呢?注释掉第二个方法中的Ajax的请求代码,直接写死一句话,然后刷新后再执行前一个Ajax请求后,观察到第二个注释后ajax请求后的函数正常工作,写死的的那句话也每几秒一次写入到结果div中。说明定时执行是正常工作的,但如果有Ajax请求就无法正常工作,那问题到底出在哪里?

打开firebug,观察发现,当前一个ajax请求在进行时,后面的定时请求也在不断生成,但是一直是等待状态,非要等到前一个ajax请求执行结束,后面的ajax请求才能成功请求!说明前一个ajax执行导致了阻塞影响到了后面的所有请求!


查阅相关PHP阻塞的资料,发现有人遇到过类似问题,是由于php的session阻塞机制导致的!

只要执行了session_start方法,就会创建session,我们知道,每个客户端在请求的时候,session是存储在文件中的。而且同一个客户端只会共用一个相同的session。一个请求占有了Session后,实际上是以读写方式打开了session文件。为了防止冲突,后面的请求只能等待。

在本例中,第一个长时间执行的ajax占有了session后,加了读写锁,后面的请求无法获得相同session文件的读写锁,故只能等待前一个请求释放session。

搞清楚了问题原因,解决就好解决了。

1)如果可以不用session_start,则不使用。有时候执行这个句往往是出于习惯或原来代码就这么写的,为什么不知道,呵呵。

2)无法避免使用session_start的,那也没关系,写完session内容后,及时关闭。关闭方法很简单。

        session_write_close();

本例是第二种情况,这两个ajax请求都不需要读写session,于是执行在最前面加上了session_write_close();后问题解决。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
回答: 当一个页面上同时开启多个ajax请求向后台请求数据时,如果没有特殊处理,这些请求会被堵塞,变成一个一个地完成。这是因为这些请求属于同一个会话,而同一个会话中的请求会受到Session锁的影响,导致请求阻塞。\[1\]为了避免这种情况,可以在控制器上加上特性\[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)\],这样可以将Session设置为只读,避免同一会话中的Session锁导致请求阻塞。\[2\]另外,需要注意的是,HttpSessionState来自于HttpModule的SessionStateModule,在每次请求处理过程中,会检查当前请求的处理程序是否实现了接口IRequiresSessionState,如果实现的话,会为这个请求分配HttpSessionState。同时,SessionStateModule还负责SessionID的生成、Cookieless会话管理、从外部状态提供程序中检索会话数据以及将数据绑定到请求的调用上下文。如果页面请求设置了读取器锁定,同一会话中同时处理的其他请求将无法更新会话状态,但至少可以进行读取。如果页面请求设置了写入锁定,那么所有其他页面都会被阻止,无论他们是要读取还是写入内容。在AJAX程序设计中,需要注意这种情况的发生。\[3\] #### 引用[.reference_title] - *1* *2* *3* [同一页面多个ajax请求后台堵塞问题](https://blog.csdn.net/leftfist/article/details/82805674)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值