Hatena::ブログ(Diary)

kazuhoのメモ置き場

2014-02-21

WebSocketsでの送信処理に関する注意点(CLOSINGステートとcloseイベントに関する疑問)

WebSocketsの接続状態には、CONNECTING / OPEN / CLOSING / CLOSEDのステートが定められている。

一方、CLOSING状態への遷移に対応するイベントは存在せず、CLOSE状態へ遷移した際にcloseイベントが発生するとされている。

つまり、「closeイベントが来るまでは送信できるぜー」ってなコードを書いてると、正常系なのにsend()で例外発生する可能性がある。

なので、面倒だけど、

if (ws.readyState == 1) {
    ws.send(...);
}

のようなガードを入れる必要がある*1。もしくは、ws.readyState == CLOSING 状態になったらcloseイベントのハンドラを呼び出すようなラッパーを書く必要がある。

と、以上の結論に至ったんですが、あってますでしょうか? >識者


以下、規格からの引用。

CONNECTING (numeric value 0)

  The connection has not yet been established.

OPEN (numeric value 1)

  The WebSocket connection is established and communication is possible.

CLOSING (numeric value 2)

  The connection is going through the closing handshake, or the close() method has been invoked.

CLOSED (numeric value 3)

  The connection has been closed or could not be opened.

When the WebSocket closing handshake is started, the user agent must queue a task to change the readyState attribute's value to CLOSING (2). (If the close() method was called, the readyState attribute's value will already be set to CLOSING (2) when this task runs.)

When the WebSocket connection is closed, possibly cleanly, the user agent must queue a task to run the following substeps:

  1. Change the readyState attribute's value to CLOSED (3).

  (略)

  3. Create an event that uses the CloseEvent interface, with the event type close, ...

*1:全二重なプロトコルなので、else節は不要で問題ないはず