web-dev-qa-db-ja.com

WebSocketを正しく閉じる(HTML5、Javascript)

HTML5 WebSocketで遊んでいます。どうすれば接続を正常に閉じることができますか?たとえば、ユーザーがページを更新した場合、または単にブラウザを閉じた場合はどうなりますか?

ユーザーがwebsocket.close()を呼び出さずにページを更新すると、奇妙な動作が発生します。更新後に戻ると、websocket.oncloseイベントが発生します。

117
Andy Hin

protocol spec v76(現在サポートされているブラウザが実装しているバージョン):

接続をきれいに閉じるために、0xFFバイトとそれに続く0x00バイトだけで構成されるフレームが1つのピアから送信され、他のピアが接続を閉じるように要求します。

サーバーを作成している場合は、サーバーがクライアント接続を閉じたときに必ずクローズフレームを送信する必要があります。通常のTCPソケットクローズメソッドは、遅い場合があり、アプリケーションが接続が開いていなくても接続が開いていると判断することがあります。

ページを閉じるか、リロードするときに、ブラウザが実際にこれを行う必要があります。ただし、beforeunloadイベントをキャプチャすることで、クローズフレームが送信されることを確認できます。

window.onbeforeunload = function() {
    websocket.onclose = function () {}; // disable onclose handler first
    websocket.close();
};

ページが更新された後、どのようにoncloseイベントを取得できるのかわかりません。ページがリロードされると、websocketオブジェクト(oncloseハンドラーを含む)は存在しなくなります。ページの読み込み中にすぐにページでWebSocket接続を確立しようとすると、古い接続が切断された直後(またはブラウザーの準備ができていない)にサーバーが新しい接続を拒否する問題が発生する可能性があります接続しようとしているポイントで接続を確立します)、新しいwebsocketオブジェクトのoncloseイベントを取得しています。

96
kanaka

非常に簡単です、あなたはそれを閉じます:)

var myWebSocket = new WebSocket("ws://example.org"); 
myWebSocket.send("Hello Web Sockets!"); 
myWebSocket.close();

次のサイト も確認しましたか? Operaの紹介記事 も確認しました

35
karlcow

それは、今日使用されているWebSocketの2つの主要なプロトコルバージョンがあるということです。 [0x00][message][0xFF]プロトコルを使用する古いバージョン、およびHybiでフォーマットされたパケットを使用する新しいバージョンがあります。

古いプロトコルバージョンはOperaおよびiPod/iPad/iPhoneで使用されるため、WebSocketsサーバーで後方互換性を実装することが実際に重要です。古いプロトコルを使用しているこれらのブラウザーでは、ページを更新したり、ページから移動したり、ブラウザーを閉じたりすると、ブラウザーがすべて自動的に接続を閉じることがわかりました。すばらしいです!!

ただし、新しいプロトコルバージョン(例:Firefox、Chrome、最終的にIE10)を使用するブラウザーでは、ブラウザーを閉じるだけで、ブラウザーは自動的に接続を閉じます。つまり、ページを更新するか、ページから移動すると、ブラウザは自動的に接続を閉じません。ただし、ブラウザが行うことは、最初のバイト(プロトタイプID)が0x88(より近いデータフレームと呼ばれる)であるhybiパケットをサーバーに送信することです。サーバーがこのパケットを受信すると、必要に応じて、接続自体を強制的に閉じることができます。

34
theoobe

theoobeで述べたように、一部のブラウザーはwebsocketを自動的に閉じません。 「ブラウザウィンドウを閉じる」イベントをクライアント側で処理しようとしないでください。現在、主要なデスクトップおよびモバイルブラウザのサポートを検討している場合(たとえば、onbeforeunloadは機能しません)、信頼できる方法はありません。 Mobile Safariで)。私はこの問題をサーバー側で処理する良い経験がありました。例えば。 Java EEを使用する場合、 javax.websocket.Endpoint をご覧ください。ブラウザに応じて、OnCloseメソッドまたはOnErrorメソッドがブラウザウィンドウを閉じる/リロードする場合に呼び出されます。

3
artkoenig

Webソケットのcloseメソッドを使用して、要件に応じて任意の関数を作成できます。

var connection = new WebSocket('ws://127.0.0.1:1337');
    connection.onclose = () => {
            console.log('Web Socket Connection Closed');
        };
2