web-dev-qa-db-ja.com

WebSocket.oncloseは、ユーザーナビゲーションまたは更新によってトリガーされますか?

パート1:予想される動作?

呼び出されているoncloseハンドラに関して、FirefoxとChromeの間でブラウザの動作に一貫性がないことがわかります。

Chromeは、ユーザーページのナビゲーション/更新が原因である場合、oncloseをトリガーしません。ただし、Firefoxはoncloseをトリガーします。

ここではFirefoxが正しく動作しているようです:

WebSocket接続がおそらくきれいに閉じられている場合、ユーザーエージェントは、CloseEventインターフェイスを使用するイベントを作成する必要があります。イベント名closeは、バブルせず、キャンセル不可能で、デフォルトアクションがなく、wasClean属性がtrueに設定されています。接続が完全に閉じられ、それ以外の場合はfalse、そのcode属性がWebSocket接続終了コードに設定され、reason属性がWebSocket接続終了理由に設定されている場合。タスクをキューに入れ、最初にreadyState属性の値をCLOSED(3)に変更してから、WebSocketオブジェクトでイベントを送出します。

ソース: http://www.w3.org/TR/2011/WD-websockets-20110419/#closeWebSocket

それでも一部の 卑劣なコード/予期しない動作を引き起こす可能性がありますが

誰かが予想される動作を確認できますか?

パート2:自動再接続を実装する方法?

ユーザーのために自動再接続するライブラリがある場合、再接続を試行する必要があるかどうかはどのようにしてわかりますか? _CloseEvent.wasClean_ プロパティを確認しますか? 「クリーン」とは、WebSocket.close()へのAPI呼び出しまたはサーバーが閉じるフレームを送信することによって閉じることが想定されていたということを想定しなければなりませんか?ネットワークエラーが原因でクローズが発生した場合、wasCleanfalseになると思いますか?

プッシャーJavaScriptライブラリでは、(クローズ->待機->接続)と仮定して、クローズ状態でない限り、クローズによって再接続がトリガーされると想定しました-開発者が接続をクローズすることを選択しました。 socket.ioクライアントライブラリも同じように想定しているようです。

これに基づいて、どちらのライブラリも_CloseEvent.wasClean_プロパティをチェックしないため、ユーザーのナビゲーション/更新によって引き起こされるFirefoxのoncloseイベントが不要な再接続をトリガーします。

例とビデオ

以下は、不整合を示すために使用できる例です。 http://jsbin.com/awonod/7

これが問題を説明している私のビデオです: http://www.screenr.com/vHn8 (遅いです、いくつかのミスを無視してください:))

注意すべき1つの点は、Escapeキーを押すとWebSocket接続が閉じられる可能性があることです。ただし、よく見たり自分で試したりすると、ページが更新される直前にcloseイベントがログに記録されます。

33
leggetter

予期しない動作は、FirefoxとChrome=がWebsocketのクローズを処理する方法によるものです。ページが更新されると、両方のブラウザが接続を閉じますが、Firefoxはoncloseコードを実行します。 while chromeは接続を閉じ、直接スキップして新しいページを再ロードします。そのため、この奇妙な動作を確認します。
見知らぬ人でも、私の観察によると、chromeでwebsocket.close()を呼び出すと、すぐに接続が閉じられ、onclose関数が呼び出されますが、Firefoxが閉じるのを待機しています。サーバーからのメッセージ。

サーバーからクローズメッセージを受信した場合、wasCleanプロパティはtrueになります

ライブラリがwasCleanプロパティをチェックせずに自動再接続している場合、ページが更新されるときに接続を再確立しようとするため、問題が発生する可能性があります。このためにライブラリを使用せずに手動で行うことを検討する必要があります。それほど難しくはありません。oncleanプロパティがtrueであることを確認するifステートメントを使用して、onclose関数でconnectを呼び出すだけです。または、さらに安全にするには、onbeforeunloadに変数を設定して、新しい接続を防止します。

お役に立てれば!

5
Optox