2013-02-27 50 views
1

我有一個腳本,用於從數據庫中提取用戶,準備XMPP消息,循環遍歷每個用戶併發送XMPP消息,然後記錄消息發送的日誌。輕鬆運行1000個用戶。這是從移動設備調用的服務器端API腳本。移動設備正在等待收到成功的JSON響應。用戶體驗應該很快,我不希望移動用戶等待超過幾秒鐘的響應。PHP,Apache。在腳本完成之前對瀏覽器的輸出響應

問題是其考慮的時間相當數量的腳本遍歷所有用戶,所以我最初的解決方案是使用使用ob_flush() - 注意,這些僅僅是測試腳本,看看是否計劃方法的工作原理:

ob_start(); 

$profiles_ar = array(
    "reach" => 30, 
); 

$return_ar = array(
    "success" => $profiles_ar['reach'], 
); 

echo json_encode($return_ar); 

$buffer = str_repeat(" ", 4096);     // Note apparently the buffer must be "filled" with 4096 characters (bytes?) for ob_flush() to work before sleep() occurs. 

echo $buffer; 

ob_flush(); 

flush(); 

for($i=0;$i < $profiles_ar['reach']; $i++) 
{ 
    sleep(1); 
} 

echo "finshed: ".$i; 

ob_flush(); 

flush(); 

這是行不通的,直到腳本完成後纔會得到輸出 - 我錯過了OB技術的東西嗎?

......所以做了一些搜索和本想出了:

register_shutdown_function('process_after'); 

$profiles_ar = array(
    "reach" => 10, 
); 

$return_ar = array(
    "success" => $profiles_ar['reach'], 
); 

echo json_encode($return_ar); 


echo $buffer; 

exit; 

function process_after() 
{ 
    global $profiles_ar; 

    for($i=0;$i < $profiles_ar['reach']; $i++) 
    { 
     sleep(1); 
    } 

    echo "finshed: ".$i; 
} 

這一個在Mac,但沒有在服務器上....

任何人有任何想法?如果我無法在主要處理工作之前得到這種輸出響應JSON的技術,那麼我唯一的希望就是在DB中建立隊列並運行cron作業........;(

回答

1

是在php.ini output_buffering啓用? http://php.net/manual/en/outcontrol.configuration.php

我會重構XMPP消息的創建在它自己的文件,然後使用AJAX調用發送每一個。你是不是在每封郵件等待這樣才能成功。

+0

經檢查發現其沒有價值,會看到什麼樣的設置它。 FYI AJAX方法不會有什麼好處,因爲這個過程必須是100%的服務器端。 – Nick 2013-02-27 19:23:06

+0

你可以讓ajax調用服務器端,用ajax調用創建一個html文件,並通過file_get_contents()加載它 – 2013-02-28 17:34:27

+0

服務器端Ajax調用如何幫助保持這個PHP腳本去輸出到應用程序?林不知道我跟隨你的想法使用Ajax? – Nick 2013-02-28 20:32:04

1

解決方法是補充:

echo " "; 
    ob_flush(); flush; 

內循環....

ob_start(); 

$profiles_ar = array(
    "reach" => 10, 
); 

$return_ar = array(
    "success" => $profiles_ar['reach'], 
); 

echo json_encode($return_ar); 

for($i = 0; $i < 5000; $i++) 
{ 
    echo " "; 
    ob_flush(); flush; 
} 

echo $buffer; 

ob_flush(); 

flush(); 

ob_end_flush(); 

for($i=0;$i < $profiles_ar['reach']; $i++) 
{ 
    sleep(1); 
} 

echo "finshed: ".$i; 

ob_flush(); 

flush(); 

ob_end_flush(); 

這迫使反覆從循環的第一次迭代的輸出,並最終踢英寸

相關問題