[解決済み] 基本的な「ロングポーリング」の実装方法を教えてください。
質問
Long Pollingがどのように機能するかについての情報はたくさんあります。 これ および この を含む)、ただし シンプル をコードで実装する例です。
私が見つけることができるのは コメット これは、Dojo JS フレームワークと、かなり複雑なサーバーシステムに依存しています。
基本的に、リクエストを処理するために Apache をどのように使用し、新しいメッセージについてサーバを "long-poll" する簡単なスクリプト(例えば PHP で)をどのように書けばよいのでしょうか?
この例は、拡張性、安全性、完全性は必要ありません。
解決するには?
最初に考えていたより簡単です。基本的には、送信したいデータが利用可能になるまで(例えば、新しいメッセージが到着するまで)、何もしないページがあります。
以下は本当に基本的な例で、2~10秒後に簡単な文字列を送信します。3分の1の確率で404のエラーが返ってきます。
msgsrv.php
<?php
if(rand(1,3) == 1){
/* Fake an error */
header("HTTP/1.0 404 Not Found");
die();
}
/* Send a string after a random number of seconds (2-10) */
sleep(rand(2,10));
echo("Hi! Have a random number: " . rand(1,10));
?>
注意: 実際のサイトでは、Apacheのような通常のウェブサーバでこれを実行すると、すぐにすべてのquot;ワーカスレッド"を使い果たしてしまい、他のリクエストに応答できなくなります。これを回避する方法はありますが、Pythonのようなものでquot;long-pollサーバーを書くことをお勧めします。 ねじれた これは、1つのリクエストにつき1つのスレッドに依存しないものです。 コメットD はポピュラーなものであり(数ヶ国語で利用可能)、また トルネード はこのようなタスクのために特別に作られた新しいフレームワークです(FriendFeedのロングポーリングコードのために作られました)...しかし、単純な例としては、Apacheは十分すぎるほどです このスクリプトはどんな言語でも簡単に書くことができます(Apache/PHPを選んだのは、これらが非常に一般的であり、たまたまローカルで動作していたからです)
そして、Javascriptで上記のファイルをリクエストします(
msg_srv.php
を実行し、応答を待ちます。 応答があったら、そのデータに基づいて行動する。次に、ファイルを要求し、再び待ち、データに対応する(そして繰り返す)。
以下は、そのようなページの例である。ページが読み込まれると、最初のリクエストとして
msgsrv.php
ファイルです。成功した場合、そのメッセージを
#messages
1秒後に再度waitForMsg関数を呼び出し、待ちを発生させます。
1秒間の
setTimeout()
は本当に基本的なレートリミッターで、これなしでも問題なく動作しますが、もし
msgsrv.php
常に
を即座に返します(例えば構文エラーなど) - ブラウザが殺到して、すぐにフリーズしてしまうこともあります。これは、ファイルが有効な JSON 応答を含んでいるかどうかをチェックしたり、リクエスト数/分/秒を記録して、適切に一時停止したりする方がよいでしょう。
ページがエラーになった場合、そのエラーを
#messages
15秒待ってから再試行します (各メッセージの後に1秒待つ方法と同じです)。
この方法の良いところは、非常に回復力が高いということです。クライアントのインターネット接続が切れた場合、タイムアウトしてから再接続を試みます。これはロングポーリングの動作に固有のもので、複雑なエラー処理は必要ありません
とにかく
long_poller.htm
のコードで、jQueryフレームワークを使用しています。
<html>
<head>
<title>BargePoller</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<style type="text/css" media="screen">
body{ background:#000;color:#fff;font-size:.9em; }
.msg{ background:#aaa;padding:.2em; border-bottom:1px #000 solid}
.old{ background-color:#246499;}
.new{ background-color:#3B9957;}
.error{ background-color:#992E36;}
</style>
<script type="text/javascript" charset="utf-8">
function addmsg(type, msg){
/* Simple helper to add a div.
type is the name of a CSS class (old/new/error).
msg is the contents of the div */
$("#messages").append(
"<div class='msg "+ type +"'>"+ msg +"</div>"
);
}
function waitForMsg(){
/* This requests the url "msgsrv.php"
When it complete (or errors)*/
$.ajax({
type: "GET",
url: "msgsrv.php",
async: true, /* If set to non-async, browser shows page as "Loading.."*/
cache: false,
timeout:50000, /* Timeout in ms */
success: function(data){ /* called when request to barge.php completes */
addmsg("new", data); /* Add response to a .msg div (with the "new" class)*/
setTimeout(
waitForMsg, /* Request next message */
1000 /* ..after 1 seconds */
);
},
error: function(XMLHttpRequest, textStatus, errorThrown){
addmsg("error", textStatus + " (" + errorThrown + ")");
setTimeout(
waitForMsg, /* Try again after.. */
15000); /* milliseconds (15seconds) */
}
});
};
$(document).ready(function(){
waitForMsg(); /* Start the inital request */
});
</script>
</head>
<body>
<div id="messages">
<div class="msg old">
BargePoll message requester!
</div>
</div>
</body>
</html>
関連
-
[解決済み】mysqli_select_db()は、パラメータ1がmysqliであることを期待し、文字列が与えられる。
-
[解決済み] PHPでSQLインジェクションを防ぐにはどうしたらいいですか?
-
[解決済み] ある文字列が特定の単語を含んでいるかどうかを確認するにはどうすればよいですか?
-
[解決済み] YouTube APIからYouTubeビデオのサムネイルを取得する方法を教えてください。
-
[解決済み] java.net.URLConnectionを使用してHTTPリクエストを発生させ処理する方法
-
[解決済み] HTTP POSTリクエストでは、どのようにパラメータが送信されるのですか?
-
[解決済み] Long-Polling、Websocket、Server-Sent Events (SSE)、Cometとは何ですか?
-
[解決済み】全てのブラウザで、Webページのキャッシュを制御するには?
-
[解決済み】facebookやgmailのリアルタイム通知はどのように行われますか?
-
[解決済み] ブラウザがファイルのダウンロードを受信したことを検出する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】XAMPPポート80をPID 4の「Unable to open process」が使用中 [重複] XAMPPポート80をPID 4の「Unable to open process」が使用中。]
-
[解決済み】SQLSTATE[42000]: 構文エラーまたはアクセス違反が発生しました。1064 SQL 構文にエラーがあります - PHP - PDO [重複]。
-
[解決済み】++と*+の意味は何ですか?
-
[解決済み】「初期通信パケットの読み込み」でMySQLサーバーに接続できなくなり、システムエラーになる。0
-
[解決済み】foreach()に与えられた引数が無効です。)
-
[解決済み】Laravel 5.2 Storage::makeDirectory($dir) でディレクトリが作成されない。
-
[解決済み】Netbeans 7.4 for PHPで「スーパーグローバルな$_POST配列に直接アクセスしないでください」という警告が発生する。
-
[解決済み] Uncaught SyntaxError: JSON の位置 1 に予期しないトークン o があります。
-
[解決済み] オートロードとは何ですか; spl_autoload、__autoload、spl_autoload_register はどのように使うのですか?
-
[解決済み] SSLエラー SSL3_GET_SERVER_CERTIFICATE:証明書の検証に失敗しました。