ajax長輪詢阻塞其他請求?

為了到底消息及時推送,選擇使用ajax長輪詢,按照網上各種資料講的,在頁面載入的時候就發起一個ajax請求,然後再伺服器端hold住,sleep(1):每隔1秒就查詢一下數據表裡面的計數值是否大於之前的值(初始值為0),如果大於之前的值說明有新消息就返回計數值提示有多少條信息,然後發起新的請求。否則當運行超過60秒也返回一條信息,還是發起新的請求。但是這樣會面臨這樣的問題,如果你在掛起這條請求的同時,又需要發起其他的請求,那麼這些請求就被依次阻塞了,必須要等掛起的請求結束才可以進行被阻塞的請求,這樣顯然不是我想要的結果。我也看了webqq,它好像是採用了iframe但是我真心的不知道到底改怎麼用iframe解決請求的阻塞的問題,請大家不吝賜教。若能避免使用「推拉模式」、「反向ajax」之類的大概念則更好。


阻塞的問題我遇到過,通過排查和查閱資料得到原因如下:

原因:為了安全考慮(避免單個用戶並發請求導致的session數據錯亂),PHP採用排它鎖來互斥的訪問session數據(不管你是用session文件還是memcache存session),也就是說開啟了session後,單個用戶只能串列的訪問這個站點,並發的請求只有一個會被立刻響應,其它都會被阻塞。

解決辦法:

  1. 不用session

  2. [推薦]及時用
    session_write_close() 函數保存session(此函數會釋放session數據的排它鎖)
  3. [不推薦]自己模擬session。不調用session_start(此函數會鎖住session數據)通過cookie獲得session_id,然後獲取session數據。通過session_decode/encode編解碼session數據保存等

再說一下樓主的實時推送需求,這個我也做過:

不要用ajax,因為比較耗費伺服器資源,實時性也得不到很好的保證。

我用的是WebSocket(HTML5/Flash)+PHP Socket 伺服器(workerman 一個高性能的PHP Socket 伺服器框架)

這個方案實時性高,並且消耗資源非常低,多瀏覽器支持。

DEMO:

發送消息的後台頁面:Web消息推送器

實時接收消息的頁面:Web消息接受頁面

代碼地址:walkor/web-msg-sender · GitHub

還有個PHP+WebSocket聊天室也是類似的原理:workerman-chat

安裝使用就兩步(workerman不依賴apache、nginx、php-fpm等容器就可以直接運行。不支持Win):

1、下載代碼

2、運行./bin/workermand start

一切ok

發消息後台:http://ip:3333

接受消息頁面:http://ip:3333/web-msg-sender.html


這個是由於session被佔用導致的,讓長輪循不再操作session。用session_write_close()的函數可以解決你的問題。


為何不用comet


如何解決,我將php邏輯代碼全部去除了,只在介面的for循環十次里sleep(1),但還是存在ajax等待循環ajax執行完成在執行

答案:session_write_close


會有人願意在各種"不行","不要",近乎被侮辱的情況下幫你解決這麼具體的技術問題嗎?


好像是ajax請求同一個域名,一次限制只能發送2個請求,用iframe可以跨子域發請求,突破這個限制,具體可以參考 http://blog.zhaojie.me/2007/02/break-the-browsers-restrictions-6.html


推薦閱讀:

你見過哪些公眾平台被添加自動回復很好玩?為什麼?
社交網站適合用什麼開源框架?
社交網路盈利之道|非微商
網站用英文名妥不妥?

TAG:Web開發 | PHP | Ajax | 社交產品 | comet |