1

DB からユーザーを取得し、XMPP メッセージを準備し、各ユーザーをループして XMPP メッセージを送信し、メッセージが送信されたことをログに記録するスクリプトがあります。1000 人以上のユーザーを簡単に実行できます。これは、モバイル デバイスから呼び出されるサーバー側の API スクリプトです。モバイル デバイスは、JSON の成功応答の受信を待機しています。ユーザー エクスペリエンスは迅速であるべきです。モバイル ユーザーが応答を数秒以上待たされることは望ましくありません。

問題は、スクリプトがすべてのユーザーをループするのにかなりの時間がかかることです。そのため、私の最初の解決策は 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();

それは機能していません。スクリプトが終了するまで何も出力されません。

......だから、いくつかの検索を行い、これを思いつきました:

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 ジョブを実行することしかできません.... ;(

4

2 に答える 2

1

php.iniでoutput_bufferingが有効になっていますか? http://php.net/manual/en/outcontrol.configuration.php

独自のファイルでのxmppメッセージの作成をリファクタリングしてから、ajax呼び出しを使用してそれぞれを送信します。そうすれば、各メッセージが成功するのを待つ必要はありません。

于 2013-02-27T18:05:04.410 に答える
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();

これにより、ループの最初の反復からの出力が繰り返し強制され、最終的に開始されます。

于 2013-03-02T22:10:23.177 に答える