ロングポーリングを使用してWebページの更新をトリガーする方法を見つけようとしています(単一のセクションではなくページ全体)。単一のセクションではなく、ページの一部だけを更新する方が適切ですが、最初のページの更新部分を取得して、そこから先に進むことをお勧めします。そうは言っても、どうすればこれを行うことができるかについて、誰かが私を正しい方向に向けることができるかどうか疑問に思っていましたか? 長いポーリングの例をオンラインで検索してきましたが、残念ながらこれに似たものはまだ見つかりませんでした。サーバー上の何らかの条件 (debian の apache) に基づいてロング ポーリングを使用してリモートで更新できる Web ページがほとんどあります。たとえば、サーバー時間に基づいて午前または午後を示す bash スクリプト ベースの CGI ページがあるとします。 、
1 に答える
さて、まずは。長いポーリング リクエストを実行する場合は、ブラウザで表示されるページごとにサーバーへのオープン接続が存在することに注意する必要があります。そのためには、サーバー インフラストラクチャが大量のメモリを消費することなくこれを処理でき、長いポーリング リクエストを処理するための空き接続が不足しないことが必要です。
私はあなたがphpを使用しているとは思いませんが、それは良い例です.phpモジュールを備えたapacheを使用している場合、一方ではapacheの構成による最大接続の制限があり、他方では接続ごとにphp全体多くのページビューがある場合、多くのメモリを使用するモジュールがロードされます。php-fpm を fcgi として使用する場合、利用可能なクライアントの最大数もあり、この数を特定の制限を超えて増やしたくありません。
したがって、これを処理するための適切なロジックを備えた優れたサーバー バックエンドがない場合は、一般に、公開 Web サイトに対してロング ポーリング リクエストを使用しないことをお勧めします。
要件に応じて、ページの更新を確認する間隔がわかっている場合は、次の解決策を考えることができます。
data-check-for-refresh-at
属性をdata-modified-at
html ノードに追加できます。
<html data-check-for-refresh-at='2013-02-04 12:00:00 GMT' data-modified-at='2013-01-01 12:00:00 GMT'>
これを JavaScript で解析し、この時点でリフレッシュ チェックを実行して、modified-at
そのリクエストで時刻を送信します。コンテンツが変更された場合は、新しいコンテンツを送信し、次にクライアントが更新を確認する必要があります。
クライアントがこのリフレッシュ時間にランダムなオフセットを追加する必要があることも重要です。そうしないと、おそらく自分で DDOS を実行します。すべてのクライアントが同時に更新要求を送信するためです。
編集(コメントに基づく)
最初に、実際のシステムでどのように行うべきかを簡単に説明します。
サーバーは、接続ごとに 1 つのスレッドまたはプロセスを使用するのではなく、イベント ドリブンのアプローチを使用する必要があります (ストリームの読み取りまたは書き込みの準備ができているかどうかを通知するコールバックを登録します)。次に、ロング ポーリング リクエストが到着すると、サーバーは、クライアントが通知を必要としている変更に関する情報を保存します。その後、接続はスリープ状態ですクライアントに通知する必要があるまで、その接続のために浪費される CPU サークルはもうありません。また、メモリ使用量も非常に低くなります。次に、URL が変更された場合、この URL の変更をリッスンするすべてのクライアントに通知する必要があることをサーバーに通知します。次に、サーバーは応答をクライアントに送信します (出版購読システム)。通知されるクライアントの数によっては、送信トラフィックのバランスをより良くするために、通知をキューに入れ、インテリジェントな方法で処理する必要があります。このアプローチでは、最大許容オープンポート/ファイル記述子の問題に遭遇する可能性が高くなり、CPU またはメモリの使用に問題が発生する可能性が高くなります。
もちろん、これは非常に単純化した説明ですが、実装方法を理解するには十分だと思います。
Quick&Dirty ソリューション
これは実際のコードよりも疑似コードであるため、これはコピー アンド ペーストでは機能しません。また、$notificationFile
長いポーリング リクエストが到着する前にサーバーがファイルを作成すると想定されます):
ロング ポーリング リクエストは、次のような php スクリプトを呼び出します。
set_time_limit(0);
/*
$urlToCheck and $modificationTimeToCheckAgainst should be initialized by the values send by client as parameter for the long polling request
$someTime should be the maximum time the long polling request should be keept alive
*/
$forceResponseTimeout = microtime(true) + $someTime;
$urlToCheck = "the/url/to/observe.html";
$modificationTimeToCheckAgainst = "2013-02-05 00:00:00"; //should be the time in seconds (not a real date)
$notificationFile = "./tmp/observer-file-".sha1($urlToCheck);
$responseStatus = "did-not-change";
while( microtime(true) < $forceResponseTimeout ) {
clearstatcache(); //need to clear cache otherwise we don't have the right modification date (also not the beast idea to keep cpu usage low)
if( filemtime(".update-check-file-".sha1($pathToCheck)) > $modificationTimeToCheckAgainst ) {
$responseStatus = "changed";
break;
}
usleep(100); //this is a bad idea because it creates a high cpu usage, even with the sleep
}
echo $responseStatus; //here some json response should be created, the client then gets the information if it should resend the long polling request or if it should do a refresh.
更新スクリプトは次のようになります。
$urlThatIsUpdated = "the/url/to/observe.html";
//doing the update of the file
$notificationFile = "./tmp/observer-file-".sha1($urlThatIsUpdated);
touch($notificationFile); //updates the modification time of the notification file, which should be recognized by the script above.