以下のシナリオやその他のケースで、サーバーは HTML5 で Web ソケット接続を閉じることをどのように認識しますか。
- ブラウザが突然閉じた
- Browser Refresh (新しいソケット接続の作成、または既存の接続を使用します)
- システムの突然の電源オフ
クライアントがサーバーに通知できずに終了した場合、TCP 実装の基本的な特性によって動作が定義されます。
アプリケーション (およびホスト システム自体) がこの切断された接続を介してデータを送信しようとしない限り、ホストは何かがおかしいことに気付きません。したがって、サーバーの観点からは、接続が長時間「開いた」ままになり、リソースが割り当てられる可能性があります。
ただし、データをリモート エンドに送信しようとすると、リモート エンドは取得を確認せず、TCP 再送信が行われます。これには、特定の回数の繰り返しと使用されるタイムアウトが含まれます。正確なパラメーターは、実装 (使用中のオペレーティング システム) によって異なります。再送信が最終的に失敗すると、TCP 接続が閉じられ、サーバー側でリソースが解放されます。だからあなたはできる
Web ソケットが開いている状態でユーザーがブラウザのタブを閉じた場合、サーバーはこれがすぐに閉じられたことを認識しません。ただし、Jan-Philip が言うように、操作を書き込もうとすると失敗し、エラーを使用すると接続の現在の状態がわかります。
たとえば、nodejs に ws lib を使用している場合、閉じた websocket にデータを送信しようとすると、[エラー: 開かれていません] のような例外がスローされます。接続が存在しないことがわかっているため、必要なクリーンアップを実行できます。
あなたの質問の最も簡単な部分は、ブラウザの更新部分です。IE、FF、および Chrome は、開いている接続を閉じて、新しい接続を開きます。他のブラウザーでも同じことができると思います。
ポイント 1 と 3 私は推測することしかできません: クライアントがまだ tcp 接続をきれいに閉じることができる場合、サーバーは接続が閉じられたことをすぐに認識します。tomcat を使用している場合は、MessageInbound インスタンスの onClose メソッドが呼び出されます。
クライアントが tcp 接続をきれいに閉じることができなかった場合、サーバーは何らかのタイムアウトを待ちます。サーバーがソケットに何かを書き込もうとすると、サーバーは間違いなくすぐにタイムアウトします。これを行うには、ハートビート メカニズムを実装できます。Websockets には自動ハートビートのオプションがあるようですが、すべてのブラウザーとサーバーがそれをサポートしているようには見えません。