Websocket は優れており、頻繁に言及されていますが、Android デバイスと 16% のブラウザーは Websocket をサポートしていません ( CanIUse.com )。多くのサーバー インストールでは、共有 LAMP セットアップを含め、websocket もサポートされていません。共有ホストを使用している場合、または幅広いサポートが必要な場合は、websockets は有効なオプションではない可能性があります。
ロング ポーリングは、WebSocket の唯一の有効な代替手段です。より幅広いサポートがあります (ほとんどすべてのサーバーとクライアントで動作するはずです) が、多くの同時接続を適切に処理できないサーバー (Apache など) では重大な欠点があります。もう 1 つの欠点は、接続しているユーザーの数に関係なく、多くの定期的なデータベース クエリ (おそらく 1 秒あたり数回) を実行する必要があることです。shm_attach()
PHP のように共有メモリを使用すると、この負担を軽減できます。サーバー スクリプトは新しいメッセージを監視するため、見つかったメッセージは開いている接続を介してすぐに送信されます。クライアントはメッセージを受信し、新しいリクエストで長い接続を再開します。
Websocket を使用できない場合は、ロング ポーリングとショート ポーリングのハイブリッドを使用できます (以下を参照)。非常に長いポーリングを使用する必要はなく、多くのリソースを消費します。約 10 秒または 15 秒の一定の接続の後、それを閉じて、繰り返される通常の GET 要求である昔ながらの短いポーリングに切り替える必要があります。
この jQuery コードはテストされていませんが、次のように理解できます。
function longpoll(lastid) {
/* Start recursive long polling. The server script must stay
connected for the 15 seconds that the client waits for a response.
This can be done with a `while()` loop in PHP. */
console.log("Long polling started...");
if (typeof lastid == 'undefined') {
lastid = 0;
}
//long polling...
setTimeout(function () {
$.ajax({
url: "stream.php?long=1&lastid=" + lastid, success: function (payload) {
if (payload.status == "result") {
//result isn't an error. lastid is used as bookmark.
console.log("Long poll Msg: " + payload.lastid + ": " + payload.msg);
longpoll(lastid); //Call the next poll recursively
} else if (payload.status == "error") {
console.log("Long poll error.");
} else {
console.log("Long poll no results.");
}
/* Now, we haven't had a message in 15 seconds. Rather than
reconnect by calling poll() again, just start short polling
by repeatedly doing an normal AJAX GET request */
shortpoll(lastid); //start short polling after 15 seconds
}, dataType: "json"
});
}, 15000); //keep connection open for 15 seconds
};
function shortpoll(lastid) {
console.log("Short polling started.");
//short polling...
var delay = 500; //start with half-second intervals
setInterval(function () {
console.log("setinterval started.");
$.ajax({
url: "stream.php?long=0&lastid=" + lastid, success: function (payload) {
if (payload.status == "result") {
console.log(payload.lastid + ": " + payload.msg);
longpoll(lastid); //Call the next poll recursively
} else if (payload.status == "error") {
console.log("Short poll error.");
} else {
console.log("Short poll. No result.");
}
}, dataType: "json"
});
delay = Math.min(delay + 10, 20000) //increment but don't go over 20 seconds
}, delay);
}
短いポーリングでは、代わりに反復ポーリング (要求) を使用して、同時接続数を減らします。いつものように、ショート ポーリングの欠点は、新しいメッセージを取得する際の遅延です。ただし、これは実際の生活に似ているため、大したことではありません。(過去 1 週間に誰かがあなたに電話をかけなかった場合、その人は今後 5 分間あなたに電話する可能性は低いので、5 分ごとに電話をチェックするのはばかげています。)