2013-05-22 70 views
2

對這個問題感興趣 - 如何正確停止一個帶有睡眠的while循環。 我實施了「長輪詢」的事實,以快速更新網站上的信息(警告,其他信息)。停止一段時間的循環php

腳本

的本質,我們將發送GET請求到PHP頁面中的腳本所在。

2.該腳本運行循環

3.在這個系列有條件和結束睡眠(1),該暫停循環的執行。

-如果循環運行多個秒 - 停止循環,分別執行,和腳本。

-如果您的網站有新信息,請說「警報」 - 將結果導出給用戶並停止循環。

問題 如果用戶關閉瀏覽器窗口,或者重新加載頁面 - 一個新的查詢上的腳本,這將再次啓動週期執行。但在這種情況下,先前執行的循環不會停止,直到它們至少有一個條件工作。如果用戶發送大量請求到頁面 - 服務器的內存開始啓動,並且結果全部掛起,直到所有都不會停止執行。

問題 如何停止循環和腳本作爲一個整體,當你運行頁面時會重載或客戶端? 雖然目前我做了以下。 當您運行我們生成的腳本時,會收到一個分配給該變量的隨機數,並且與會話相同。進一步向內陸地區做一個條件,其中變量必須是會話的值。如果錯誤 - 停止循環。 如果我們在新的腳本上運行腳本 - 會話的值發生變化,並因此停止前的所有性能。 我可以使用該選項嗎?多少安全?

UPDATE.PHP

// Initialize the user's session 
$session = Session::instance(); 

     $rand = rand(); 
     $session->set('user_update_key', $rand); 
     $key = $rand; 

     $limit = 20; 
     $seconds = 0; 

     set_time_limit($limit + 1); 

     while (TRUE) { 
      if (Session::instance()->get('user_update_key') == $key) { 

       if (there are updates. if there is - output) { 
        echo 'update information'; 
        flush(); 
        exit; 
       } 
       if ($seconds == $limit) { // complete the loop at the expiration of the time. 
        echo 'Close'; 
        flush(); 
        exit; 
       } 
       $seconds++; 
      } else { 
       unset($session, $rand, $key, $notice, $mysession, $last_notice, $limit, $notise_return, $seconds); 
       flush(); 
       exit; 
      } 
      session_write_close(); 
      sleep(1); 
      session_start(); 

}

+0

'while(TRUE)'< - 確定你不需要這個,是嗎? –

+0

您可以繼續使用;用於終止循環內循環的關鍵字。 – Ali

+0

你真的需要session_write_close();/session_start(); ?更新過程如何啓動,是否可以簡單地設置30秒的超時時間? – Adder

回答

0

你而條件是unchangable,而實際上並非如此。 函數睡眠()會,如果成功的返回0,因此,如果您重寫睡眠(的返回值的改變,你的同時,條件反應),那麼可能它的工作是設計,請參閱: http://php.net/manual/en/function.sleep.php

一個線程和其他功能對於瞭解您正在使用的操作系統是非常重要的。我有Ubuntu,它的反應與文檔中提到的不同。

function interruptedSleep(){ 
    $cond = true; 
    while($cond){ 
    $i = sleep(10); 
    if($i == 0){ 
    $cond = false; 
    } 
    } 
} 

當你關閉瀏覽器中斷睡眠會睡眠函數返回0,while循環被中止,並計劃將在一段時間後直接continu。它不會拋出異常。

+0

你能舉一個例子嗎? – qulery

+0

按照你說的設置。所有時間顯示爲false。 :( 在這種情況下,頁面打開。 – qulery

1

請注意,PHP和Apache通常不適用於長輪詢。我不知道你使用nginx時的情況,但是幾個月前我不得不在Apache上做一些長期輪詢的工作。在我們開始生產之前,一切都很好。事實證明,Apache的侷限性阻止了你維持持久的連接。

服務器掛起並拒絕接受任何新的請求,允許約20個用戶登錄並打開3-4張網頁。還有瀏覽器限制,阻止您維護到一個主機的太多http連接。儘管有解決方法 - 使用子域名。

我試圖弄清楚如何解決id,在StackOverflow上問了十幾個問題,一切都以使用node.js + socket.io結尾,這是輕量級的,可輕鬆處理數千個併發連接。

我知道這篇文章沒有回答你的原始問題,但是在我開發了一些不起作用的東西之後,我希望你可能會發現這些信息很有用。

+1

感謝您的回答! – qulery

0

爲什麼不使用cronjob定期在後臺運行進程,然後將AJAX放置在拉動數據庫檢查警報的網頁上。否則,你會遇到性能問題。

+0

您的意思是,這將創建爲每個用戶cronjob,在後臺運行ajax請求已爲他打了很長時間? – qulery

+0

這意味着你只有一個在後臺運行的cronjob只能發送郵件,你仍然可以將它作爲一個PHP腳本,從數據庫中抓取所有需要發送的記錄,然後發送它們。在網站/應用程序端,ajax每隔X秒運行一次,以檢查數據庫是否存在需要顯示的警報,如果有警報彈出或執行您想要的操作。 – NCoder

+0

您可以立即通知使用此技術? – qulery