3

JavaScript EventSource オブジェクトを使用して、HTML5 でプッシュを使い始めました。私はPHPでの実用的なソリューションに完全に満足していました:

$time = 0;
while(true) {
    if(connection_status() != CONNECTION_NORMAL) {
        mysql_close()
        break;
    }
    $result = mysql_query("SELECT `id` FROM `table` WHERE UNIX_TIMESTAMP(`lastUpdate`) > '".$time."'");
    while($row = mysql_fetch_array($result)) {
        echo "data:".$row["id"].PHP_EOL;
        echo PHP_EOL;
        ob_flush();
        flush();
    }
    $time = time();
    sleep(1);
}

しかし突然、MySQL エラー「接続が多すぎます」で WebApp に到達できなくなりました。

JavaScript でイベント ソースを閉じた後、MySQL 接続が閉じないことが判明しました。

window.onload = function() {
    sse = new EventSource("push.php");
    sse.onmessage = function(event) {
        console.log(event.data.split(":")[1]);
    }
}
window.onbeforeunload = function() {
    sse.close();
}

したがって、PHP スクリプトの実行は停止しないと思います。die();クライアント接続が切断される前に関数 ( など) を呼び出す方法はありますか? .close();EventSourceを呼び出した後、スクリプトが終了しないのはなぜですか?!

手伝ってくれてありがとう!—</p>

4

6 に答える 6

6

まず、コードを巨大なwhile(true)ループでラップすると、スクリプトは決して終了しません。スクリプトが「実行するコードを使い果たした」場合、DB との接続は閉じられますが、デッドロックを作成したため、これは発生しません。
それはEventSource問題ではありません。それは単に本来の目的を果たしているだけです。それは正直に、本当に、そして悲しいことにあなたのせいです.

つまり、ユーザーがサイトに接続すると、EventSourceオブジェクトがインスタンス化されます。サーバーへの接続が確立され、戻り値のpush.php要求が要求されます。サーバーは要求どおりに実行し、スクリプトを実行しますが、これもデッドロックに他なりません。エラーがないため、php.ini で実行が許可されている限り、実行を続けることができます。この.close()メソッドは出力のストリームをキャンセルします (むしろキャンセルする必要があります) が、スクリプトは無限ループを実行しているか、スリープ状態であるかのどちらかで非常に忙しいです。クライアントが切断されたためにスクリプトが停止すると仮定することは、クライアントがサーバーの動作に干渉する可能性があると仮定するようなものです。セキュリティ的には、これは起こりうる最悪の事態です。さて、あなたの実際の質問に答えるために:問題の原因は何ですか、それを修正するにはどうすればよいですか?
答え:ヘッダー

この小さな PHP の例を見てください。スクリプトはサーバー側 (無限ループによって) ではなく、正しいヘッダーを設定することによって維持されます。

補足として:できるだけ早く捨ててください。 mysql_*(最終的に)非推奨になり、使用するPDOか、代わりに使用してmysqli_*ください。それほど難しいことではありません。

于 2012-10-16T16:20:45.700 に答える
0

これをループに追加してみてください。

if(connection_status() != CONNECTION_NORMAL)
{
    break;
}

ただし、クライアントが切断されるとphpは停止するはずです。

于 2012-10-16T15:57:15.997 に答える
0

1.1。

window.onbeforeunload = function() {
    sse.close();
}

これは必須ではありません。EventSourceはページのアンロード時に閉じられます。

  1. PHPで切断されたクライアントを検出する方法が見つからない場合でも、N秒後に実行を停止するだけで、EventSourceが自動的に再接続します。

このページのhttp://www.php.net/manual/ru/function.connection-aborted.php コメントによると、とにかくconnection_statusの前に「フラッシュ」を使用する必要があります。検出できないため、N秒後に接続を切断する必要があります。 「悪い」切断。

3. echo "retry:1000 \ n"; //これを使用して、EventSourceに再接続遅延をミリ秒単位で通知します

于 2012-10-19T08:07:51.943 に答える