ajax 異步長鏈接遭遇堵塞,「排序執行請求」的問題解決

今天開發一個網頁聊天程序,利用AJAX保持着一個長鏈接監聽新的聊天信息,以後又調用了另一個AJAX來發言,因而就發生了一個AJAX線程被阻塞的問題。php

在未監聽到新的聊天信息的以前,發言用的AJAX就沒法發出。服務器

問題描述:網絡

上圖中session

第一個連接是長鏈接(監聽新聊天信息使用的)AJAX鏈接,每次鏈接時間爲30秒;app

第二個連接是發言用的AJAX鏈接,請求後實時返回結果。異步

遇到的問題就是第一個連接發出後,在第一個連接沒有執行完畢(也就是沒有返回結果前),這段時間內若是執行第二個連接,須要排隊,等第一個執行完,纔會執行。函數

這裏就鬱悶了,覺得是JS的緣由:「JS是否是AJAX只能單線程發送?」測試

由於上述問題,以及推測的答案,百度、谷歌了一下午,看了好多技術文章,直接崩潰,沒法解決。this

難道要使用「輪詢」方式解決這個問題?可是這樣會形成不少網絡資源浪費,由於3秒定時請求一次,而後打開多個網頁的狀況下,基本就是幾百毫秒就請求一次了。spa

什麼是「輪詢」?

就是使用JS定時循環執行函數,每隔幾秒向服務器請求一次,看有沒有新消息,若是有就獲取過來。


 

解決方法:

晚上吃完飯,回來繼續百度

1、百度搜索:「異步長鏈接遇阻塞」,發現一篇文章《異步長鏈接遇阻塞,探索,以及解決 》:http://blog.csdn.net/guoerwei/article/details/6535389

看完此文後得出一些線索:

問題不是出在JS上,問題在於PHP程序上! 由於session的出現,致使了沒法正常工做。直接將session先刪掉,發現長鏈接已經不堵塞了。

緣由是長鏈接死循環的時候,session文件被一直打開着,處於被鎖定的狀態,這時來發送消息,會由於session而阻塞……

2、至此,問題解決,那麼上面咱們的解決辦法是,直接刪掉session,可是項目作到如今,已經有不少的session了,刪掉測試下,確定的沒問題,可是想要直接不使用session,仍是有點麻煩,那麼是否能夠在不刪除session的狀況下解決這個問題呢?

接着百度搜索「php如何解決session封閉問題」,發現一篇文章《PHP中Session引發的腳本阻塞問題解決辦法》http://www.jb51.net/article/48805.htm

從裏面獲得一個函數

 

session_write_close();

 

結合了PHP的Session機制,找到了阻塞的緣由。因爲PHP的Session信息是寫入文件的,1個客戶端佔有1個session文件。所以,當 session_start被調用的時候,該文件是被鎖住的,並且是以讀寫模式鎖住的(由於程序中可能要修改session的值),這樣,第2次調用 session_start的時候就被阻塞了。

查了下PHP的Bug列表,發現有人提出了這個問題:

Description:
------------
Calling session_start() appears to wait until other scripts have exited

that are using the same session. My guess is the 1st request locks the
session file for exclusive use, and the second request blocks until it
can open it.

PHP官方的回覆是:

Thank you for taking the time to write to us, but this is not a bug.This is expected, the session file is locked to avoid corruption.

 

本文爲做者原創:

相關文章
相關標籤/搜索