2012-08-17 68 views
3

我正在構建一些webapp並實現了長輪詢(並在我的數據庫中有一個命令隊列),所以我的服務器可以將命令異步發送到我的cleint等等。命令被編碼爲json並通過ajax調用客戶端到服務器,並通過長時間輪詢服務器到客戶端的方式。每個會話不能有多個線程

一切都工作得很好,直到我包含我的「身份驗證模塊」在ajax.php文件。該模塊包裝會話內容並調用session_start()。

問題是,我的長輪詢例程可能會等待21秒才能回到客戶端。在此期間,服務器將不會運行同一會話中的任何內容。它是在長輪詢ajax調用返回後立即執行的。

我知道可能一次只限制每個會話一個線程,並且請求排隊。

現在問題是:解決這個問題的最佳方法是什麼?是否有一個設置允許每個會話有幾個線程(在我的情況下,3個會很好)。或者我應該發送告訴客戶端他的SessionID是什麼(我的數據庫中有一些會話表,用於跟蹤哪個用戶連接到哪個會話)。客戶端隨後可以將它與任何ajax調用一起發送,以便認證模塊可以被繞過。

在後面的選項,我害怕它打開了一堆安全問題,因爲最終的會話欺騙。我需要發送一個「隨機字符串」到每個環節,以確保你不能欺騙太容易了,但即便如此,它並不完美......

感謝您的awnsers :)

薩科Gauthier

+0

剛一個主意。會話文件可能被鎖定,並且單獨的「線程」無法訪問它們。您是否嘗試過在不需要時明確地關閉會話?我看到你說你有一張桌子,會話ID與會話相關聯,是桌上的整個會話? (如果這樣的話忽略我的文件鎖定理論) – Leigh 2012-08-17 14:21:24

+0

沒有表格被使用,所以我可以發送消息給「給定用戶的所有會話」等。我真的不太多存儲在會話變量,只是用戶id,會話ID(從我的分貝的),如果它是有效的。 蔭想看看我能「session_write_close」確實如你mentionned睡覺($計數器)「明確關閉會話時,沒有必要 – NGauthier 2012-08-17 14:26:44

+0

哇,改變‘;’由」 session_write_close();睡眠($計數器);在session_start();」解決了這個問題,似乎這是上阻塞!‘會議文件的ressource’...ü天才哈哈,張貼了一份問題和虐待選擇作爲awnser – NGauthier 2012-08-17 14:28:44

回答

4

這是一個衆所周知的問題/事實PHP鎖定會話文件的使用期限,以防止競爭條件。

如果您看一下PHP源代碼(ext/session/mod_files.c),您可以看到ps_files_open函數鎖定了會話文件,並且ps_files_close解鎖了它。

如果您在長時間運行的腳本的開頭正確調用session_start(),並且不顯式關閉會話文件,它將被鎖定,直到腳本終止,在腳本關閉期間PHP將釋放所有文件鎖定。

雖然不使用會話,但應該調用session_write_close將會話數據刷新到磁盤,然後釋放鎖定,以便其他「線程」可以讀取數據。

我相信你可以想象如果文件沒有被鎖定會發生什麼。

T1: Open Session 
T2: Open Session 
... 
T2: Write Data 
T1: Write Data 

通過線2寫入的數據將被完全覆蓋通過線程1,並在同一時間,任何數據線1想寫出來,沒有提供給線程2

+0

再次感謝:) – NGauthier 2012-08-17 15:04:06

+0

會話文件可能被阻止!只有當你需要寫信給他們? – 2014-01-23 18:16:50