Facebookのティッカー、meetup.comのホームページなど、ブラウザで継続的なリアルタイムの更新を表示するにはどうすればよいですか? Python、PHP、node.js、およびサーバー側でのパフォーマンスへの影響は何ですか? また、ページが akamai のような CDN によってキャッシュされている場合、どうすれば同じ更新を実現できるでしょうか?
4 に答える
2 つのオプションがあります (他のユーザーは上記で詳しく説明しています)。各オプションの背後にある概念的な考え方に慣れていない場合のために、それらについて 1 つか 2 つの行を示しておきます。これらの概念を非常に高いレベルで提示していることに注意してください。
あなたの3つのオプションは次のとおりです。
- ショートポーリング
- ウェブソケット
- コメット / ロングポーリング
ショートポーリング
ショート ポーリングは、クライアントが次の形式のサーバーにリクエストを継続的に送信することを強制することにより、クライアントとサーバー間の一方向通信を克服します。
Client: Do you have a message for me?
Server: No.
Client: (wait x seconds)
Client: Do you have a message for me?
Server: No.
Client: (wait x seconds)
Client: Do you have a message for me?
Server: Yes. Here it is!
Client: Yay!
Client: (update message)
クライアントに代わって一定のしつこいものはポーリングと呼ばれます。この構造を実装するには、クライアントからのこれらのポーリングリクエストを「聞く」ためにサーバーをセットアップする必要があります。また、サーバーはこれらのメッセージをどこかに保存する必要があるため、メッセージの準備ができたらサーバーが配信できるようにします。非常に高い単純なレベルでは、サーバーが必要とする必要があります。
- 一般的な Web リクエストを受け入れる
- ポーリング要求を受け入れる
- メッセージを取得するバックグラウンド ジョブを実行する
- これらのメッセージをどこかに保存して、ポーリング要求が届いたときにサーバーがチェックできるようにします。
また、適切なメッセージが適切な人に届くように、これらのポーリング要求をユーザーのある種のセッション ID に関連付ける必要があります。全体として、パラダイムは複雑で、私の意見では非効率的です。
ウェブソケット
Web ソケットは HTML5 の新機能です。それらの背後にある基本的な考え方は、クライアントがサーバーへの直接接続を維持でき、相互に情報をやり取りできるということです。したがって、通常の代わりに: クライアントが GET リクエストを送信する >> サーバーがコンテンツで応答する、Web ソケットを使用すると、継続的な対話を維持できます。
ただし、これを設定するには、次のものが必要です。
- WebSocket に準拠しているブラウザー (すべてが準拠しているわけではありません)。
- Web ソケットを処理できるサーバー (これを明確にする方法はわかりませんが、すべてのサーバーがこの種の配置用にセットアップされているわけではありません)。
セットアップはやや複雑ですが、長いポーリングよりは簡単です。
- クライアントはサーバーへの Web ソケット対応接続への接続を維持します
- サーバーは、Web ソケットを介してクライアントに結果をプッシュします
- クライアントは結果に従ってページを更新します
サーバーがクライアントに「もの」をプッシュする権限を与えられているため、このパターンはプッシュ通知と呼ばれます (確かに、これを経験した iPhone を所有している場合)。クライアントとサーバーにはさまざまなニュアンスがあるため、基本的に Web ソケットのすべての難しい部分を処理する Web サービスであるPusherのようなものをテストすることをお勧めします。これは、自分でパターンを設定する前に、パターンをテストして遊ぶための簡単な方法です。クライアント側とサーバー側の両方のライブラリがあります。
この情報が、問題を解決するためのベースラインとなることを願っています。他の回答には、各シナリオを解決する方法に関するより直接的な情報があります。
コメット / ロングポーリング
Web Sockets に対する代替の一見クロスブラウザー アプローチは、Long-Polling です ( Cometを参照)。この場合、クライアントはサーバーへの接続を確立し、ハングしたままにして、データがプッシュバックされるのを待ちます。この設定はやや複雑ですが、Short PollingとWeb Socketsの中間にあたるものです。
クライアント側の JavaScript ライブラリとして SockJS または Socket.io を使用してソケットのような接続を実装し、サーバー側で Tornado を使用して状態の変更をクライアントに公開することをお勧めします。コードはかなり単純です。
クライアント側のコードは、選択したライブラリによって異なります。SockJS または SocketIO。または、Websockets を直接使用したい場合は、非常に簡単です。
update_socket = new WebSocket("ws://my_server.com/listening_url");
update_socket.onmessage = function (evt) {
$("#my_div").html(evt);
};
サーバー側のコードも非常に単純です。
import tornado
class UpdateHandler(tornado.websocket.WebSocketHandler):
def open(self):
self.write_message('Hi client')
# listen for some events that are occurring
for message in function_that_generates_events():
self.write(message)
def on_message(self, message):
# Do something with incoming messages
def on_close(self):
# tidy up
app = tornado.web.Application(('r/listening_url',UpdateHandler))
app.listen(9000)
ポーリング、ロング ポーリング、またはプッシュ システムが必要な場合に使用できます。最も簡単なのは世論調査です。ただし、すべてのソリューションにはクライアント側のコーディングが必要です。
パフォーマンスへの影響は、ソリューションによって異なります。最も簡単に実装できるのは投票です。短い頻度のポーリングは、100 ミリ秒ごとに効果的にリクエストを実行し、リアルタイムをシミュレートします。ロング ポーリングは影響が少ないですが、多かれ少なかれ多くのリクエストがオープンのままになります。