1

チャット機能を備えた Web サイトを構築しており、オンライン ユーザーとオフライン ユーザーを追跡する必要があります。オンラインユーザーを追跡するために、このテーブルを使用しています

ユーザー ID | タイムスタンプ

すべてのオンライン ユーザーのタイムスタンプを 20 秒ごとに更新します。そのため、現在のタイムスタンプとテーブルのタイムスタンプを比較するだけで、誰がオフラインであるかを知ることができます。

問題は次のとおりです。ユーザーのオンライン ステータスを更新するためにロング ポーリングを使用しました。つまり、ユーザーがログインしたときに、次のようなスクリプトへの ajax 呼び出しを実行します。

<?php
set_time_limit(0);

while(1){
  updateUserTimestamp();
  sleep(20);
}
?>

上記のコードは問題なく動作していますが、問題は、ユーザーがブラウザを閉じた後もゴースト プロセスのように実行され続け、タイムスタンプを更新してリソースを消費し続けることです。クライアントがブラウザを閉じたときに停止させたいのです。

助けてください。

4

5 に答える 5

4

次の解決策を試してください ( connection_aborted() 関数のドキュメントを参照してください)。

<?php
set_time_limit(0);

while(!connection_aborted()){
    updateUserTimestamp();
    sleep(20);
}

または、クライアントが接続を閉じたときにスクリプトを中止するように設定することもできます。詳細については、ドキュメントをignore_user_abort参照してください。

しかし、多くの同時リクエストがある可能性がある場合は、次のいずれかを行うことをお勧めします

  1. 頻繁な AJAX リクエストを優先してロング ポーリングの使用をやめる、または
  2. 追加のリクエストで多くのリソースを使用しない Node.js のようなサーバー サイド ソリューションを採用します。
于 2011-09-01T09:23:00.890 に答える
1

しかし、問題は、ユーザーがブラウザーを閉じた後も、ゴースト プロセスのように実行され続け、タイムスタンプを更新してリソースを消費し続けることです。クライアントがブラウザーを閉じたときに停止したいのです。

それがまさにあなたがこれをしたくない理由です。このスクリプトを削除し、updateUserTimestamp()頻繁に呼び出されるグローバル スクリプト、理想的にはユーザー ステータスが変更されるスクリプトに移動する必要があります (ユーザー ステータスが変更されない場合は、更新する必要もないため)。

于 2011-09-01T09:22:06.523 に答える
0

あなたのコードは、ユーザーがまだ接続されているかアクティブであるという証拠なしでステータスを更新し続けます。ユーザーが単に自分のコンピューターをシャットダウンした場合、たとえ接続が閉じられたことを検出できたとしても、コンピューターは永久に実行されます。(オフになっているコンピュータは接続を閉じることができませんよね?)

更新をトリガーする 20 秒ごとにユーザーに何かを行わせる必要があります。それが何であるかを決めることができ、それは何でもかまいません。ただし、ユーザーがアクティブであると見なすには、ユーザーが行う何かが必要です。彼が永遠にアクティブであると見なすことはできません。これは、コードが行うことです。

于 2011-09-01T09:42:54.460 に答える
0

これを実行しているサーバーは何ですか?ユーザーがブラウザーを閉じると、AJAX 要求も強制終了され、TCP 接続が閉じられ、サーバーはこれに注意して、実行中の PHP プロセス/スレッドを強制終了する必要があるため、これは発生しないはずです。

window.onunloadすべてのアクティブな AJAX リクエストを強制終了するクライアント側イベントを追加してみて、違いが生じるかどうかを確認してください。

于 2011-09-01T09:21:45.553 に答える
-1

プロセスが決して終了しないようにするには、20 秒間待機した後にスクリプトを終了させ、クライアントに新しい接続を開くように強制します。ロング ポーリングの利点は維持されますが、ゴースト プロセスはなくなります。

于 2011-09-01T09:28:38.580 に答える