44

ポーリングへのフォールバックを使用して WebSocket を実装しようとしています。WebSocket 接続が成功しreadyStateた場合は 1 になりますが、失敗した場合readyStateは 3 であり、ポーリングを開始する必要があります。

私はこのようなことを試しました:

var socket = new WebSocket(url);
socket.onmessage = onmsg;
while (socket.readyState == 0)
{
}
if (socket.readyState != 1)
{
    // fall back to polling
    setInterval(poll, interval);
}

socket.readyState非同期で更新して、すぐに読めるようにすることを期待していました。ただし、これを実行すると、ブラウザーがフリーズします (あきらめる前に約 30 分開いたままにしました)。

おそらくonreadyStateChangedイベントがあると思いましたが、MDN リファレンスには見当たりませんでした。

これをどのように実装すればよいですか?どうやら空のループは機能せず、このためのイベントはありません。

4

9 に答える 9

38

ここに、より詳細な説明があります。すべてのブラウザーが最新の RFC に対応しているわけではないため、最初に特定のブラウザー API を確認してください。に相談できます

準備完了状態を常にチェックするためにループを実行する必要はありません。必要のない余分なオーバーヘッドです。より良いアプローチは、readystate の変更に関連するすべてのイベントを理解し、それらを適切に関連付けることです。それらは次のとおりです。

oncloseWebSocket 接続の readyState が CLOSED に変化したときに呼び出されるイベント リスナー。リスナーは「close」という名前の CloseEvent を受け取ります。

onerrorエラー発生時に呼び出されるイベントリスナー。これは「エラー」という名前の単純なイベントです。

onmessageサーバーからメッセージを受信したときに呼び出されるイベント リスナー。リスナーは、「メッセージ」という名前の MessageEvent を受け取ります。

onopenWebSocket 接続の readyState が OPEN に変化したときに呼び出されるイベント リスナー。これは、接続がデータを送受信する準備ができていることを示します。イベントは「open」という名前のシンプルなものです。

JS は完全にイベント ドリブンであるため、これらのイベントをすべて接続し、readystate を確認するだけで、WS からポーリングに適宜切り替えることができます。

Mozilla リファレンスを参照することをお勧めします。RFC ドキュメントよりも読みやすく、API の概要とそのしくみ (リンク) がよくわかります。

失敗した場合は再試行のためのコールバックを実行し、再接続が成功した場合のコールバックが発生するまでポーリングすることを忘れないでください。

于 2012-11-27T18:20:45.410 に答える
7

http://dev.w3.org/html5/websockets/を見てください

「イベント ハンドラー」を検索し、テーブルを見つけます。

onopen -> 開く
onmessage -> メッセージ
onerror -> エラー
onclose -> 閉じる

function update(e){ /*Do Something*/};
var ws = new WebSocket("ws://localhost:9999/");

ws.onmessage = update;
于 2013-05-15T12:07:36.543 に答える
0

ハンドラーを定義したのと同じように、onmessageハンドラーを定義することもできますonerror。これは、接続が失敗したときに呼び出されます。

var socket = new WebSocket(url);
socket.onmessage = onmsg;
socket.onerror = function(error) {
    // connection failed - try polling
}
于 2012-11-24T23:57:21.670 に答える
0

while ループがスレッドをロックしている可能性があります。使用してみてください:

setTimeout(function(){
    if(socket.readyState === 0) {
        //do nothing
    } else if (socket.readyState !=1) {
        //fallback
        setInterval(poll, interval);
    }
}, 50);
于 2012-11-24T22:51:31.970 に答える
0

私のユースケースでは、接続が失敗した場合に画面にエラーを表示したいと考えていました。

let $connectionError = document.getElementById("connection-error");

setTimeout( () => {
  if (ws.readyState !== 1) {
    $connectionError.classList.add( "show" );
  }
}, 100 );  // ms

Safari (9.1.2) ではerrorイベントが発生しないことに注意してください。それ以外の場合は、これをエラー ハンドラーに配置します。

于 2016-08-03T08:40:01.330 に答える