1. ホーム
  2. comet

[解決済み】facebookやgmailのリアルタイム通知はどのように行われますか?

2022-04-02 14:12:32

質問

私はこのトピックに関するいくつかの記事を読んで、答えはコメット、逆Ajax、httpストリーミング、サーバプッシュなどです。

Gmailの着信通知はどのように行われるのですか?

GMail Chatは、どのようにしてクライアントと対話することなくAJAXリクエストを行うことができるのですか?

非常に簡単な例を書くために従うことができるコードリファレンスがあれば知りたいのです。多くの投稿やウェブサイトは、技術について話しているだけです。完全なサンプルコードを見つけるのは困難です。また、Hidden IFrameやXMLHttpRequestなど、多くのメソッドを使用してコメットを実装することができるようです。私見では、XMLHttpRequestを使用するのがベターな選択だと思います。さまざまなメソッドの長所と短所をどう思いますか?Gmailはどちらを使用していますか?

サーバーサイドとクライアントサイドの両方で行う必要があることは承知しています。 PHPやJavascriptのサンプルコードはないのでしょうか?

どのように解決するのですか?

Facebookのやり方は、なかなか面白いです。

このような通知を行う一般的な方法は、サーバー上のスクリプトを(AJAXを使って)一定の間隔(おそらく数秒ごと)でポーリングし、何かが起こったかどうかをチェックすることです。しかし、これはかなりネットワークを消費しますし、何も起こっていないため、しばしば無意味なリクエストを行います。

Facebookのやり方は、コメット方式で、一定間隔でポーリングするのではなく、1つのポーリングが完了するとすぐに次のポーリングを発行するのです。 しかし、サーバー上のスクリプトへの各リクエストは非常に長いタイムアウトを持ち、サーバーは何かが起こったときにのみリクエストに応答します。 FacebookでFirebugのコンソールタブを表示すると、スクリプトへのリクエストに数分かかることもあり、この現象を確認できます。 この方法は、リクエストの数と送信する頻度を即座に削減することができるので、実に独創的です。この方法では、サーバーがイベントを「発射」するためのイベントフレームワークを効果的に使用することができます。

その裏側で、これらの投票から返される実際のコンテンツは、イベントのリストとそれらに関する情報のように見えるJSONレスポンスです。しかし、minifyされているので、少し読みにくいです。

実際の技術としては、リクエストのタイムアウトやその他多くのことをコントロールできるAJAXが適しています。 AJAXを行うには、(Stack overflowの決まり文句ですが)jQueryを使用することをお勧めします。 PHPの観点からは、PHPスクリプトでイベントログのデータベーステーブルをポーリングして、何かが起こったときだけクライアントにリターンすることができるのではないでしょうか?これを実装する方法はたくさんあると思います。

実装しています。

サーバーサイド。

コメットライブラリのPHPでの実装はいくつかあるようですが、正直なところ、非常にシンプルで、おそらく以下のような擬似コードになります。

while(!has_event_happened()) {
   sleep(5);
}

echo json_encode(get_events());

  • has_event_happened関数は、イベントテーブルか何かで何かが起こったかどうかをチェックするだけで、get_events関数はテーブルの新しい行のリストを返すのでしょうか。問題の文脈によりますが。

  • PHPの最大実行時間を変更することを忘れないでください。そうしないと、早くタイムアウトしてしまいます!

クライアント側です。

Cometインタラクションを行うためのjQueryプラグインを見てみましょう。

とはいえ、このプラグインはかなり複雑なものを追加しているようで、クライアント側では非常にシンプルで、おそらく(jQueryを使用して)次のようなものでしょう。

function doPoll() {
   $.get("events.php", {}, function(result) {
      $.each(result.events, function(event) { //iterate over the events
          //do something with your event
      });
      doPoll(); 
      //this effectively causes the poll to run again as
      //soon as the response comes back
   }, 'json'); 
}

$(document).ready(function() {
    $.ajaxSetup({
       timeout: 1000*60//set a global AJAX timeout of a minute
    });
    doPoll(); // do the first poll
});

全体としては、既存のアーキテクチャがどのように組み合わされているかに大きく依存します。