2015-09-19 58 views
0

我正在使用websocket的PHP應用程序,我試圖從本質上設置一個計時器。當用戶到達一個頁面時,有30秒的等待時間間隔,並且在他們的屏幕上顯示一個javascript計時器。一旦倒計時完成(更不用說,用戶篡改時間),我寧願讓服務器在30秒內發送信號時發送信號,而不是依靠javascript發送信號。pcntl_fork干擾父進程

雖然fork中的進程正在進行(在這種情況下是休眠函數),但用戶可以通過websocket發送和接收消息。然而,當fork中的進程完成後,如果用戶試圖執行任何通過websocket進行交互的操作,則它們將斷開連接,我無法弄清楚原因。

這是因爲

//the user will be disconnected if they try to perform any actions after the sleep is finished 
if(pcntl_fork()){ 
    sleep(30); 
    $this->broadcast_message('done'); 
} 
debug('after fork'); //this is displayed twice. Once as soon as it runs, and a second time when the sleep is done 

WebSocket的斷開,當我使用pcntl_fork 發生這樣簡單的事情。用戶不會立即斷開連接。如果用戶嘗試執行一些使用WebSocket連接的其他操作,則會斷開連接。

我知道這是導致此問題的pnctl_fork,因爲我可以睡眠然後不使用分叉而進行廣播,並且用戶沒有斷開連接,但它阻止了其他所有內容,並且用戶無法與頁面交互直到睡眠結束。

//this works fine. However, this holds everything up and nothing further can be done so it's useless 
sleep(30); 
$this->broadcast_message('done'); 

回答

0

我想出了問題。對於有同樣問題的任何人,兒童進程沒有正常結束。

$pid = pcntl_fork(); 
if($pid){ 
    sleep(30); 
    $this->broadcast_message('done'); 
    posix_kill($pid, SIGKILL); 
} 
-1

請勿在從Web服務器運行的腳本中使用pcntl_fork()。系統調用fork()將使PHP解釋器和託管它的Web服務器處於不一致狀態。

如果要在腳本中執行延遲任務,請使用事件循環。

+0

Downvoting,因爲WebSockets明確排除在Web請求中運行腳本。這個「答案」只是爲了迷惑人們,並沒有解決這個問題,至多應該被當作無用的評論。 – Ghedipunk