動的に生成されたコンテンツを含む Web ページがあるとします。つまり、現在接続されているブラウザーの数を含む div です。サーバーでカウントが変更された場合、接続されているすべてのブラウザーでカウントをリロードして、誰もが増分/減分を確認できるようにします。
これを達成するための最良の方法は何ですか?
キーワード: ajax、ブロードキャスト、ブラウザ、div、jquery
動的に生成されたコンテンツを含む Web ページがあるとします。つまり、現在接続されているブラウザーの数を含む div です。サーバーでカウントが変更された場合、接続されているすべてのブラウザーでカウントをリロードして、誰もが増分/減分を確認できるようにします。
これを達成するための最良の方法は何ですか?
キーワード: ajax、ブロードキャスト、ブラウザ、div、jquery
COMETはあなたが探しているものかもしれないと 思います. Web Socketsは理想的ですが、ブラウザーが採用されていないため、現時点では実用的ではありません。
HTTP プロトコルは、設計上ステートレスです。これを実現する唯一の方法は、AJAX を介してクライアント側のポーリングを実装することです。
ajaxロングポーリングを使用してサーバープッシュを行う方法は次のとおりです。ブラウザは、サーバー側の自己ポーリングを開始する ajax リクエストを作成します。ajax リクエストは開いたままになり、ファイルが変更されるまで応答を待ちます。応答を受け取るとすぐに、新しいロング ポーリング リクエストを作成します。
jQueryと php を使用すると、現在接続されているクライアントの数を示す html の div をライブ更新する例を実装すると、次のようになります。
index.html:
<html>
<head>
<title>Comet Test</title>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="longpolling.js"></script>
</head>
<body>
Number of connected users: <div id="total">0</div>
</body>
</html>
longpolling.js:
$(document).ready(function() { connectToServer(1); });
function connectToServer( incp ) {
$.get("LongPolling.php",
{ inc: incp },
function(resp) {
$('#total').html(resp);
connectToServer(0);
}
);
}
LongPolling.php:
<?php
# (over)write file with contents, locking the file while doing so.
# just barf and die if there's an error.
function update($file, $contents)
{
$f = fopen($file, 'w');
if(!$f) { echo "ERROR1"; exit; } # couldn't open file for writing.
if(!flock($f, LOCK_EX)) { echo "ERROR2"; exit; } # couldn't get lock.
fwrite($f, $contents);
fclose($f); # this also releases the lock.
return $contents;
}
# fetch the contents of the given file.
# if the file doesn't exist, create it with contents "0"
function fetch($file)
{
if(file_exists($file)) {
if(!is_readable($file)) { echo "ERROR3"; exit; }
$x = file_get_contents($file);
} else {
$x = 0;
update($file, $x);
}
return $x;
}
$fc = 'connx.txt'; # file that stores the number of connections.
if ( $_REQUEST['inc'] == 1 ) { # someone just connected.
echo update($fc, fetch($fc)+1);
} else { # someone is reconnecting (also happens immediately after connect).
$last = filemtime($fc);
do { # wait until some other instance causes $fc to change...
sleep(1);
clearstatcache(); # otherwise filemtime() results are cached!
} while(filemtime($fc) == $last);
echo fetch($fc);
}
?>
注: これは切断を追跡しないため、ページビューの総数をライブで追跡するようなものです。ブラウザの切断を追跡する方法、つまりクライアントの切断時のサーバー側のアクションについては、ブラウザを閉じるときにサーバー側の機能を実行するを参照してください。
2014 年 12 月の時点で、HTTP 経由でこれを実行できるようにする Server Sent Events (SSE) と呼ばれる W3C 提案の推奨事項があります: http://www.w3.org/TR/eventsource
コメットと呼ばれる技術群の標準化だそうです。(ダレルが彼の答えでリンクしたもの)
Sinatra の 2013 年の完全な例は、http: //html5hacks.com/blog/2013/04/21/push-notifications-to-the-browser-with-server-sent-events/にあります。
2010 HTML5 Rocks の記事もあります。
IE11 の注目すべき例外を除いて、現在のほとんどのブラウザーはこの API をサポートしています: http://caniuse.com/#feat=eventsource
リバース AJAX が必要です。DWR Web ページ ( http://directwebremoting.org/dwr/reverse-ajax/index.html ) で簡単に説明されています。おそらく、ajax 呼び出しに使用しているライブラリで 3 つのフレーバーのいずれかを使用できます。
ネットワーク サーバーとして機能する Java アプレットを作成することは可能です。アプレットが正常に開始されると、そのポートと IP 番号をリモート サーバーに報告できます。
その後、サーバーはいつでも好きなときにクライアント サーバーにメッセージを送信できます。その後、Java アプレットはメッセージを JavaScript に渡したり、その他の処理を実行したりできます。
ただし、この方法には Java プラグインのサポートが必要ですが、これは普遍的ではありません。