1. 序論
この節は規範的ではない。This section is non-normative.
[
web アプリがサーバ側プロセスとの双方向通信を保守する
]ことを可能化するため、
この仕様は, WebSocket
インタフェースを導入する。
To enable web applications to maintain bidirectional communications with server-side processes, this specification introduces the WebSocket interface.
注記: このインタフェースは、 下層のネットワークへの生のアクセスを許容するものではない。 例えば,カスタムサーバを介したメッセージのプロキシ法を利用しない限り、 このインタフェースを IRC クライアントの実装に利用することはできない。 This interface does not allow for raw access to the underlying network. For example, this interface could not be used to implement an IRC client without proxying messages through a custom server.
【この訳に特有な表記規約】
この訳において(主にアルゴリズム内で)利用される各種記号( ε, ← , IF, THROW, 等々)の意味や定義の詳細は、共通な慣用表現, アルゴリズムに共通して利用される表記を参照されたし。
以下に挙げる用語は、 WebSocket プロトコル仕様 [WSP] にて定義される (この訳では、 日本語訳へのリンクを “参照” として与える — これらは、 原文では, URL Fragment Text Directives に定義される素片指令を伴う URL として与えられている) :
- 状態°コード(参照) ( HTTP 応答の状態°コードではないことに注意)
- WebSocket 接続は確立済み(参照)
- WebSocket 接続を失敗させる(参照)
- WebSocket closing ハンドシェイクを開始する(参照)
- WebSocket closing ハンドシェイクは開始済み(参照)
- WebSocket メッセージを送信する(参照)
- WebSocket メッセージを受信した(参照)
- WebSocket 接続を close する(参照)
- WebSocket 接続は close 済み(参照)
- clean に close された(参照)
- WebSocket 接続 close コード(参照)
- WebSocket 接続 close 事由(参照)
- 下位プロトコル(参照)
- 下位プロトコル名(参照)
- 利用中にある下位プロトコル(参照)
- 利用中にある拡張(参照)
- Close フレーム(参照)
- Ping フレーム(参照)
- Pong フレーム(参照)
- opcode (参照)
- ペイロードデータ(参照)
2. WebSocket プロトコルの改め
注記:
この節は、[
WebSocket プロトコルの opening ハンドシェイクに課されるクライアント要件
]の一部を[
Fetch にて定義されるアルゴリズムに統合する
]ために置換する。
Fetch に関係するプロトコル
— CSP , クッキー, HSTS など —
は、
この仕方で,一箇所に集約して取り扱われるようになる。
RFC がこの文言で更新されるのが理想だが、
それは決して容易にはならない。
以下に定義される WebSocket
API は、
この文言を利用する。
[WSP] [FETCH]
This section replaces part of the WebSocket protocol opening handshake client requirement to integrate it with algorithms defined in Fetch. This way CSP, cookies, HSTS, and other Fetch-related protocols are handled in a single location. Ideally the RFC would be updated with this language, but it is never that easy. The WebSocket API, defined below, uses this language. [WSP] [FETCH]
これは、[ WebSocket Protocol の “WebSocket 接続を確立する” アルゴリズム ]を[ 新たなものに置換して, Fetch に統合する ]ような仕方で働く — “WebSocket 接続を確立する” は、 3 つのアルゴリズム[ 接続を設定しておく, ハンドシェイク要請を作成して伝送する, ハンドシェイク応答を検証する ]からなる。 その重ね方は、 Fetch による[ 先ずハンドシェイクを作成して,次に接続を設定しておいてから、 ハンドシェイクを伝送して,最後に応答を検証する ]のとは異なる。 この改めを読むときは、 そのことを念頭に置くこと。 The way this works is by replacing The WebSocket Protocol’s "establish a WebSocket connection" algorithm with a new one that integrates with Fetch. "Establish a WebSocket connection" consists of three algorithms: setting up a connection, creating and transmiting a handshake request, and validating the handshake response. That layering is different from Fetch, which first creates a handshake, then sets up a connection and transmits the handshake, and finally validates the response. Keep that in mind while reading these alterations.
2.1. 接続
WebSocket 接続を得る アルゴリズムは、 所与の ( URL ) に対し: To obtain a WebSocket connection, given a url, run these steps:
- ホスト :← URL のホスト Let host be url’s host.
- ポート :← URL のポート Let port be url’s port.
- リソース名 :← U+002F (/) Let resource name be U+002F (/),\
- リソース名 に次の結果を付加する :URL のパスを U+002F (/) で連結する followed by the strings in url’s path (including empty strings), if any, separated from each other by U+002F (/).
- IF[ URL のクエリ ≠ 空文字列 ] :リソース名 に次を順に付加する :U+003F (?), URL のクエリ If url’s query is non-empty, append U+003F (?), followed by url’s query, to resource name.
-
セキュアか :← IS[
URL のスキーム ≠ "
http
" ] Let secure be false, if url’s scheme is "http"; otherwise true. - [ WebSocket Protocol § クライアントに課される要件 の前半の手続きを成す段 2 〜 5 ]に言明されている要件に従って,WebSocket 接続を確立する [WSP] — 次を与える下で :( ホスト, ポート, リソース名, セキュアか ) Follow the requirements stated in step 2 to 5, inclusive, of the first set of steps in section 4.1 of The WebSocket Protocol to establish a WebSocket connection, passing host, port, resource name and secure. [WSP]
- RETURN[ 接続は確立されたなら それ / 他の場合は 失敗 ] If that established a connection, return it, and return failure otherwise.
注記: WebSocket 接続は、 異なるプロパティを運ぶ少し異なる構成なので,共有できないが、 “普通の” 接続にごく近いものである。 Although structured a little differently, carrying different properties, and therefore not shareable, a WebSocket connection is very close to identical to an "ordinary" connection.
2.2. opening ハンドシェイク
WebSocket 接続を確立する アルゴリズムは、 所与の ( URL , プロトコル群, クライアント ) に対し: To establish a WebSocket connection, given a url, protocols, and client, run these steps:
- 要請 URL :← URL の複製 Let requestURL be a copy of url,\
-
要請 URL のスキーム ← URL のスキームに応じて :"
ws
" ならば "http
" / 他の場合は "https
" with its scheme set to "http", if url’s scheme is "ws"; otherwise to "https".注記: このスキームの変更は、 fetch 処理にきちんと統合するために本質的になる。 例えば HSTS は、 こうしないと働かなくなる。 これは、 旧来の遺物である — WebSocket を別個なスキームにする本当の理由はない。 [HSTS] This change of scheme is essential to integrate well with fetching. E.g., HSTS would not work without it. There is no real reason for WebSocket to have distinct schemes, it’s a legacy artefact. [HSTS]
-
要請 :← 新たな要請
— その
:URL ← 要請 URL ,
クライアント ← クライアント,
service worker モード ← "
none
", リファラ ← "no-referrer
", モード ← "websocket
", 資格情報モード ← "include
", キャッシュモード ← "no-store
", リダイレクトモード ← "error
" Let request be a new request, whose URL is requestURL, client is client, service-workers mode is "none", referrer is "no-referrer", mode is "websocket", credentials mode is "include", cache mode is "no-store" , and redirect mode is "error". -
要請 のヘッダリストにヘッダを付加する(
(
`
, `Upgrade
`websocket
` ) ) Append (`Upgrade`, `websocket`) to request’s header list. -
要請 のヘッダリストにヘッダを付加する(
(
`
, `Connection
`Upgrade
` ) ) Append (`Connection`, `Upgrade`) to request’s header list. -
key 値 :← 同型に符号化する( forgiving-base64 符号化する( ランダムに選定された 16 バイトの値 ) ) Let keyValue be a nonce consisting of a randomly selected 16-byte value that has been forgiving-base64-encoded and isomorphic encoded.
例えば,ランダムに選定された値がバイト列[ 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 ]ならば、 key 値 は,それを forgiving-base64 符号化した結果 "
AQIDBAUGBwgJCgsMDQ4PEC==
" を同型に符号化した結果 `AQIDBAUGBwgJCgsMDQ4PEC==
` になる。 If the randomly selected value was the byte sequence 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10, keyValue would be forgiving-base64-encoded to "AQIDBAUGBwgJCgsMDQ4PEC==" and isomorphic encoded to `AQIDBAUGBwgJCgsMDQ4PEC==`. -
要請 のヘッダリストにヘッダを付加する(
(
`
, key 値 ) ) Append (`Sec-WebSocket-Key`, keyValue) to request’s header list.Sec-WebSocket-Key
` -
要請 のヘッダリストにヘッダを付加する(
(
`
, `Sec-WebSocket-Version
`13
` ) ) Append (`Sec-WebSocket-Version`, `13`) to request’s header list. - ]
プロトコル群 を成す
各( プロトコル )
に対し
:要請 のヘッダリスト内でヘッダを結合する(
(
`
, プロトコル ) ) For each protocol in protocols, combine (`Sec-WebSocket-Protocol`, protocol) in request’s header list.Sec-WebSocket-Protocol
` -
permessageDeflate :← UA 定義な "
permessage-deflate
" 拡張ヘッダ値 [WSP] Let permessageDeflate be a user-agent defined "permessage-deflate" extension header value. [WSP]`permessage-deflate; client_max_window_bits
` -
要請 のヘッダリストにヘッダを付加する(
(
`
, permessageDeflate ) ) Append (`Sec-WebSocket-Extensions`, permessageDeflate) to request’s header list.Sec-WebSocket-Extensions
` -
要請 を fetch する — 次を与える下で: Fetch request\
- 並列キューを利用するか ← true with useParallelQueue set to true,\
-
応答の処理 ← 所与の ( 応答 ) に対し,次を走らす手続き: and processResponse given response being these steps:
- IF[ 応答 はネットワークエラーである ]∨[ 応答 の状態° ≠ 101 ] :WebSocket 接続を失敗させる If response is a network error or its status is not 101, fail the WebSocket connection.
-
IF[ プロトコル群 は空でない ]∧[ ヘッダリストから値を抽出する( 応答 のヘッダリスト,
`
) ∈ { null , 失敗, 空バイト列 } ] :WebSocket 接続を失敗させる If protocols is not the empty list and extracting header list values given `Sec-WebSocket-Protocol` and response’s header list results in null, failure, or the empty byte sequence, then fail the WebSocket connection.Sec-WebSocket-Protocol
`注記: これは、[ WebSocket Protocol にて定義される,このヘッダに対する検査 ]と異なる。 そこでは、[ クライアントから要請されていない下位プロトコルがある場合 ]しか受け持ってなかった。 ここでは、[ クライアントから要請された下位プロトコルがサーバから承認されていない場合 ]も受け持つ。 This is different from the check on this header defined by The WebSocket Protocol. That only covers a subprotocol not requested by the client. This covers a subprotocol requested by the client, but not acknowledged by the server.
- [ WebSocket Protocol § クライアントに課される要件 の後半の手続きを成す段 2 〜 6 ]に言明されている要件に従って, 応答 を検証する — これは、 WebSocket 接続を[ 失敗させるか確立させる ]ことになる。 Follow the requirements stated step 2 to step 6, inclusive, of the last set of steps in section 4.1 of The WebSocket Protocol to validate response. This either results in fail the WebSocket connection or the WebSocket connection is established.
↑↑Fail the WebSocket connection and the WebSocket connection is established are defined by The WebSocket Protocol. [WSP]
警告: リダイレクトに追従しない理由は、 web ブラウザ文脈に深刻なセキュリティ問題を導入するからである。 そのため、 このハンドシェイクは,一般に制約される。 例えば、 あるホストが,あるパスに WebSocket サーバを立てていたとする。 当のホストが,別のパスにも open な HTTP リダイレクト器 【参考】 を立てた時点で、 WebSocket URL を与え得るような どのスクリプトも — 当の URL のホスト名が的確であることを検査したとしても — インターネット上の任意のホストと通信する(したがって秘匿情報を共有し得る)よう騙すことが可能になる。 The reason redirects are not followed and this handshake is generally restricted is because it could introduce serious security problems in a web browser context. For example, consider a host with a WebSocket server at one path and an open HTTP redirector at another. Suddenly, any script that can be given a particular WebSocket URL can be tricked into communicating to (and potentially sharing secrets with) any host on the internet, even if the script checks that the URL has the right hostname.
3. WebSocket
インタフェース
3.1. インタフェース定義
WebSocket
クラス用の Web IDL 定義は、
次で与えられる:
The Web IDL definition for the WebSocket class is given as follows:
enumBinaryType
{ "blob
", "arraybuffer
" }; [Exposed=(Window,Worker)] interfaceWebSocket
:EventTarget
{ constructor(USVString url, optional (DOMString or sequence<DOMString>) protocols = []); readonly attribute USVStringurl
; // ready state const unsigned shortCONNECTING
= 0; const unsigned shortOPEN
= 1; const unsigned shortCLOSING
= 2; const unsigned shortCLOSED
= 3; readonly attribute unsigned shortreadyState
; readonly attribute unsigned long longbufferedAmount
; // networking attributeEventHandler
onopen
; attributeEventHandler
onerror
; attributeEventHandler
onclose
; readonly attribute DOMStringextensions
; readonly attribute DOMStringprotocol
; undefinedclose
(optional [Clamp] unsigned short code, optional USVString reason); // messaging attributeEventHandler
onmessage
; attributeBinaryType
binaryType
; undefinedsend
((BufferSource
orBlob
or USVString) data); };
各 WebSocket
オブジェクトには、
次に挙げるものが結び付けられる:
↓
- URL Each WebSocket object has an associated url,\
- URL レコード。 【構築時に設定される。】 which is a URL record.
- バイナリ種別 ( binary type ) Each WebSocket object has an associated binary type,\
-
BinaryType
値 — 初期時は "blob
" になるものとする。 which is a BinaryType. Initially it must be "blob". - 準備状態 ( ready state ) Each WebSocket object has an associated ready state,\
-
当の接続の状態を表現している数値
— 初期時は
CONNECTING
になるものとする。 which is a number representing the state of the connection. Initially it must be CONNECTING (0).\ -
次に挙げる値をとり得る: It can have the following values:
-
CONNECTING
(数値 0 ) :WebSocket 接続は確立済みでない。 CONNECTING (numeric value 0) • The connection has not yet been established. -
OPEN
(数値 1 ) :WebSocket 接続は確立済みであり,通信は可能である。 OPEN (numeric value 1) • The WebSocket connection is established and communication is possible. -
CLOSING
(数値 2 ) :接続はハンドシェイクの close 中にあるか, またはclose()
メソッドが呼び出されている。 CLOSING (numeric value 2) • The connection is going through the closing handshake, or the close() method has been invoked. -
CLOSED
(数値 3 ) :接続はすでに close されたか, または open できなかった。 CLOSED (numeric value 3) • The connection has been closed or could not be opened.
-
- socket =
new WebSocket(url [, protocols ])
-
新たな
WebSocket
オブジェクトを作成した上で、 それに結び付けられる WebSocket 接続を即時に確立する。 Creates a new WebSocket object, immediately establishing the associated WebSocket connection. -
url は文字列をとり、
それが与える URL レコードに向けて,接続が確立される。
許容されるスキームは[
"
ws
", "wss
", "http
", "https
" ]いずれかに限られ、 他に対してはSyntaxError
が投出される。 URL に素片が伴われる場合も常にそれが投出される。 url is a string giving the URL over which the connection is established. Only "ws", "wss", "http", and "https" schemes are allowed; others will cause a "SyntaxError" DOMException. URLs with fragments will always cause such an exception. -
省略可能な protocols は、[
文字列, または文字列たちが成す配列
]をとり,[
省略時は空な配列 /
文字列ならば,その文字列のみからなる配列
]と等価になる。
配列内の各 文字列は下位プロトコル名を表す。
接続が確立されるのは、
サーバが,これらの下位プロトコルの一つを応答に選定して返したときに限られることになる。
どの下位プロトコル名も、[
[WSP] に定義される
`
フィールド ]の値を成す各プロトコル要素に課される要件に合致する必要がある。 protocols is either a string or an array of strings. If it is a string, it is equivalent to an array consisting of just that string; if it is omitted, it is equivalent to the empty array. Each string in the array is a subprotocol name. The connection will only be established if the server reports that it has selected one of these subprotocols. The subprotocol names have to match the requirements for elements that comprise the value of `Sec-WebSocket-Protocol` fields as defined by The WebSocket protocol. [WSP]Sec-WebSocket-Protocol
` - socket.
send(data)
-
WebSocket 接続を利用して data を伝送する。
data は[
文字列,
Blob
,ArrayBuffer
,ArrayBufferView
]のいずれかをとり得る。 Transmits data using the WebSocket connection. data can be a string, a Blob, an ArrayBuffer, or an ArrayBufferView. - socket.
close([ code ] [, reason ])
- WebSocket 接続を close する。 code は WebSocket 接続 close コードとして, reason は WebSocket 接続 close 事由として利用される(いずれも省略可)。 Closes the WebSocket connection, optionally using code as the WebSocket connection close code and reason as the WebSocket connection close reason.
- socket.
url
- WebSocket 接続を確立するときに利用された URL を返す。 Returns the URL that was used to establish the WebSocket connection.
- socket.
readyState
-
当の WebSocket 接続の状態を返す。 上に述べた値をとり得る。 Returns the state of the WebSocket connection. It can have the values described above.
- socket.
bufferedAmount
-
send()
を利用してキューされたが, まだ ネットワークに伝送されていない,アプリデータ(UTF-8 テキスト/バイナリデータ)を成すバイト数を返す。 Returns the number of bytes of application data (UTF-8 text and binary data) that have been queued using send() but not yet been transmitted to the network. -
WebSocket 接続が close された場合、
この属性の値は,
send()
メソッドが call される度に増えることになる (この数値は、接続が close されても, 0 に設定し直されることはない)。 If the WebSocket connection is closed, this attribute’s value will only increase with each call to the send() method. (The number does not reset to zero once the connection closes.) - socket.
extensions
- サーバにより選定された拡張があれば,それを返す。 Returns the extensions selected by the server, if any.
- socket.
protocol
- サーバにより選定された下位プロトコルがあれば,それを返す。 これは、 下位プロトコルの折衝を遂行するために, 構築子の(配列形にされた) 2 個目の引数と併用され得る。 Returns the subprotocol selected by the server, if any. It can be used in conjunction with the array form of the constructor’s second argument to perform subprotocol negotiation.
- socket.
binaryType
-
ソケットからのバイナリデータがスクリプトにどう公開されるかを指示する文字列を返す: Returns a string that indicates how binary data from socket is exposed to scripts:
- "
blob
" -
バイナリデータは
Blob
形で返された。 Binary data is returned in Blob form. - "
arraybuffer
" -
バイナリデータは
ArrayBuffer
形で返された。 Binary data is returned in ArrayBuffer form.
既定では "
blob
" になる。 The default is "blob". - "
- socket.
binaryType
= value - バイナリデータがどう返されるかを変更する。 Changes how binary data is returned.
new WebSocket(url, protocols)
構築子手続きは:
The new WebSocket(url, protocols) constructor steps are:
- 基底 URL :← これ°に関連する設定群オブジェクトの API 用基底 URL Let baseURL be this's relevant settings object's API base URL.
- URL レコード :← URL 構文解析する( url, 基底 URL ) Let urlRecord be the result of applying the URL parser to url with baseURL.
-
IF[
URL レコード = 失敗
]
:THROW
SyntaxError
If urlRecord is failure, then throw a "SyntaxError" DOMException. -
IF[
URL レコード のスキーム = "
http
" ] :URL レコード のスキーム ← "ws
" If urlRecord’s scheme is "http", then set urlRecord’s scheme to "ws". -
ELSE IF[
URL レコード のスキーム = "
https
" ] :URL レコード のスキーム ← "wss
" Otherwise, if urlRecord’s scheme is "https", set urlRecord’s scheme to "wss". -
IF[
URL レコード のスキーム ∉ { "
ws
", "wss
" } ] :THROWSyntaxError
If urlRecord’s scheme is not "ws" or "wss", then throw a "SyntaxError" DOMException. -
IF[
URL レコード の素片 ≠ null
]
:THROW
SyntaxError
If urlRecord’s fragment is non-null, then throw a "SyntaxError" DOMException. - プロトコル群 :← protocols に応じて :文字列であるならば « protocols » 他の場合は protocols If protocols is a string, set protocols to a sequence consisting of just that string.
-
IF[
プロトコル群 内に重複する値がある
]∨[
プロトコル群 内の値に[[
[WSP] に定義される
`
フィールド ]の値を成す各プロトコル要素に課される要件 ]を満たさないものがある ] :THROWSec-WebSocket-Protocol
`SyntaxError
If any of the values in protocols occur more than once or otherwise fail to match the requirements for elements that comprise the value of `Sec-WebSocket-Protocol` fields as defined by The WebSocket protocol, then throw a "SyntaxError" DOMException. [WSP] - これ°の URL ← URL レコード Set this's url to urlRecord.
- クライアント :← これ°に関連する設定群オブジェクト Let client be this's relevant settings object.
-
この段は並列的に走らす :WebSocket 接続を確立する( URL レコード, プロトコル群, クライアント ) [FETCH] Run this step in parallel: • Establish a WebSocket connection given urlRecord, protocols, and client. [FETCH]
注記: WebSocket 接続を確立するのに失敗した場合 :それにより,WebSocket 接続を失敗させるアルゴリズムが誘発され :それにより,WebSocket 接続を close するアルゴリズムが呼び出され :それにより,WebSocket 接続は close 済みになり :それに伴い,後述のように
close
イベントが発火されることになる。 If the establish a WebSocket connection algorithm fails, it triggers the fail the WebSocket connection algorithm, which then invokes the close the WebSocket connection algorithm, which then establishes that the WebSocket connection is closed, which fires the close event as described below.
url
取得子手続きは
:RETURN URL を直列化する( これ°の URL )
The url getter steps are to return this's url, serialized.
extensions
属性は、
初期時には空文字列を返すものとする。
その値は、
WebSocket 接続が確立された後に,
§ プロトコルからのフィードバック
にて定義されるとおり変更され得る。
The extensions attribute must initially return the empty string. After the WebSocket connection is established, its value might change, as defined below.
protocol
属性は、
初期時には空文字列を返すものとする。
その値は、
WebSocket 接続が確立された後に,
§ プロトコルからのフィードバック
にて定義されるとおり変更され得る。
The protocol attribute must initially return the empty string. After the WebSocket connection is established, its value might change, as defined below.
close(code, reason)
メソッド手続きは:
The close(code, reason) method steps are:
-
IF[
code ≠ ε
]∧[
code ∉ { 1000, 3000 ~ 4999 }
]
:THROW
InvalidAccessError
If code is present, but is neither an integer equal to 1000 nor an integer in the range 3000 to 4999, inclusive, throw an "InvalidAccessError" DOMException. -
IF[ reason ≠ ε ]: If reason is present, then run these substeps:
- 事由バイト列 ← UTF-8 符号化する( reason ) Let reasonBytes be the result of encoding reason.
-
IF[
事由バイト列 を成すバイト数 > 123
]
:THROW
SyntaxError
If reasonBytes is longer than 123 bytes, then throw a "SyntaxError" DOMException.
-
IF[ これ°の準備状態 ∈ {
CLOSING
,CLOSED
} ] :RETURN Run the first matching steps from the following list:If this's ready state is CLOSING (2) or CLOSED (3) • Do nothing.注記: 接続は、 close しつつあるか, すでに close 済みである。 close 済みでない場合、 最終的には,後述のように
close
イベントが発火されることになる。 The connection is already closing or is already closed. If it has not already, a close event will eventually fire as described below. -
ELSE IF[ WebSocket 接続は確立済みでない [WSP] ] :WebSocket 接続を失敗させる; これ°の準備状態 ←
CLOSING
If the WebSocket connection is not yet established [WSP] • Fail the WebSocket connection and set this's ready state to CLOSING (2). [WSP]注記: WebSocket 接続を失敗させるアルゴリズムは :WebSocket 接続を close するアルゴリズムを呼び出す :それにより,WebSocket 接続は close 済みになる :それに伴い,後述のように
close
イベントが発火されることになる。 The fail the WebSocket connection algorithm invokes the close the WebSocket connection algorithm, which then establishes that the WebSocket connection is closed, which fires the close event as described below. -
ELSE IF[ WebSocket closing ハンドシェイクは開始済みでない ]: If the WebSocket closing handshake has not yet been started [WSP]
-
WebSocket closing ハンドシェイクを開始する: Start the WebSocket closing handshake\ ↓and set this's ready state to CLOSING (2). [WSP]
-
[ code = ε ]∧[ reason = ε ]ならば :Close メッセージは,ボディを持たないものとする。 If neither code nor reason is present, the WebSocket Close message must not have a body.
注記: [WSP] は、[ WebSocket closing ハンドシェイクを開始するアルゴリズムに状態°コードが要求される ]ものと,誤って言明している。 The WebSocket Protocol erroneously states that the status code is required for the start the WebSocket closing handshake algorithm.
- [ code ≠ ε ]ならば :Close メッセージに利用する状態°コードは、 code に与えられた整数にするものとする。 If code is present, then the status code to use in the WebSocket Close message must be the integer given by code. [WSP]
- [ code ≠ ε ]∧[ reason ≠ ε ]ならば :Close メッセージには,状態°コードに加えて reason も供するものとする。 If reason is also present, then reasonBytes must be provided in the Close message after the status code. [WSP]
-
注記: WebSocket closing ハンドシェイクを開始するアルゴリズムは :最終的には WebSocket 接続を close するアルゴリズムを呼び出すことになる :それにより,WebSocket 接続は close 済みになる :それに伴い,後述のように
close
イベントが発火されることになる。 The start the WebSocket closing handshake algorithm eventually invokes the close the WebSocket connection algorithm, which then establishes that the WebSocket connection is closed, which fires the close event as described below. -
-
ELSE :これ°の準備状態 ←
CLOSING
Otherwise • Set this's ready state to CLOSING (2).注記: WebSocket closing ハンドシェイクは開始済みであり :最終的には WebSocket 接続を close するアルゴリズムを呼び出すことになる :それにより,WebSocket 接続は close 済みになる :それに伴い,後述のように
close
イベントが発火されることになる。 The WebSocket closing handshake is started, and will eventually invoke the close the WebSocket connection algorithm, which will establish that the WebSocket connection is closed, and thus the close event will fire, as described below.
注記:
close()
メソッドは、[
WebSocket closing ハンドシェイクを開始する以前に送信したメッセージ
]を破棄するものではない
— 仮に,UA がそのようなメッセージをまだ送信中であったとしても、
ハンドシェイクが開始されるのは,そのメッセージを送信した後に限られることになる。
The close() method does not discard previously sent messages before starting the WebSocket closing handshake — even if, in practice, the user agent is still busy sending those messages, the handshake will only start after the messages are sent.
bufferedAmount
取得子手続きは、
アプリデータ(UTF-8 テキストデータ, またはバイナリデータ)
— send()
によりキューされたが、
イベントループがその最初の段に最後に達した時点では,ネットワークにまだ伝送されていないそれ —
のバイト数を返す。
(したがって、
これは,現在のタスクの実行中に伝送されたテキストを含む
— UA が[
スクリプト実行と並列的に,背後でテキストを伝送できるかどうか
]にかかわらず)。
これには、[
プロトコルから課されるフレーム法のオーバーヘッド/
OS やネットワークハードウェアによるバッファ処理
]は含まれない。
The bufferedAmount getter steps are to return the number of bytes of application data (UTF-8 text and binary data) that have been queued using send() but that, as of the last time the event loop reached step 1, had not yet been transmitted to the network. (This thus includes any text sent during the execution of the current task, regardless of whether the user agent is able to transmit text in the background in parallel with script execution.) This does not include framing overhead incurred by the protocol, or buffering done by the operating system or network hardware.
次の単純な例では、
bufferedAmount
属性を利用して,毎 50ms ごとに一回の頻度で
(あるいは,速すぎてネットワークが追いつかない場合は追いつける頻度で)
更新を送信する。
In this simple example, the bufferedAmount attribute is used to ensure that updates are sent either at the rate of one update every 50ms, if the network can handle that rate, or at whatever rate the network can handle, if that is too fast.
var socket = new WebSocket('ws://game.example.com:12010/updates'); socket.onopen = function () { setInterval(function() { if (socket.bufferedAmount == 0) { socket.send(getUpdateData()); } }, 50); };
bufferedAmount
属性を利用すれば、
ネットワークが追いつかない頻度でデータを送信しなくとも,
ネットワークを使い切れるようになる
(その属性の値を時間越しに監視することに,もっと気を付ける必要はあるが)。
The bufferedAmount attribute can also be used to saturate the network without sending the data at a higher rate than the network can handle, though this requires more careful monitoring of the value of the attribute over time.
binaryType
設定子手続きは
:これ°のバイナリ種別 ← 所与の値
The binaryType setter steps are to set this's binary type to the given value.注記:
UA は、
受信したバイナリデータを取り扱う方法用のヒントとして,バイナリ種別を利用できる:
これが "blob
" にされている場合、
データはディスクへ安全にスプールするに適するものになる。
"arraybuffer
" にされている場合、
より効率的にメモリー内に保つに適するものになる。
もちろん,UA には、
受信したデータをメモリー内に保つかどうか裁定するときに,より繊細な経験則を利用することが推奨される
— 例:データ量や[
直前における,スクリプトによるこの属性に対する変更の頻度
]を基準にするなど。
この後者の側面は、
特に重要になる
— UA が[
データを受信した後, かつ それ用のイベントを発火する前
]に,この属性が変更される可能性も少なからずあるので。
User agents can use the binary type as a hint for how to handle incoming binary data: if it is "blob", it is safe to spool it to disk, and if it is "arraybuffer", it is likely more efficient to keep the data in memory. Naturally, user agents are encouraged to use more subtle heuristics to decide whether to keep incoming data in memory or not, e.g. based on how big the data is or how common it is for a script to change the attribute at the last minute. This latter aspect is important in particular because it is quite possible for the attribute to be changed after the user agent has received the data but before the user agent has fired the event for it.
send(data)
そのメソッド手続きは:
The send(data) method steps are:
-
IF[
これ°の準備状態 =
CONNECTING
] :THROWInvalidStateError
If this's ready state is CONNECTING, then throw an "InvalidStateError" DOMException. -
IF[ WebSocket 接続は確立済みである ]∧[ WebSocket closing ハンドシェイクは開始済みでない 【すなわち,準備状態 =
OPEN
】 ] :data 引数の型に応じて,下の表に与えられる[ opcode , およびペイロードデータ ]から構成される WebSocket メッセージを送信する :バッファを要する所でバッファが満杯になっているなどの理由で,データを送信できない場合 :この接続の満杯かを true にした上で,WebSocket 接続を close する引数の型 opcode ペイロードデータ DOMString
テキストフレーム(数値 1 ) UTF-8 符号化する( data ) の結果。 [UNICODE] [ENCODING] Blob
バイナリフレーム(数値 2 ) data が表現する生データ。 [FILEAPI] ArrayBuffer
data が表現するバッファに格納されているデータ。 ArrayBufferView
data が参照している,下層の ArrayBuffer
オブジェクトが格納するバッファの中の一区分。【 ここの訳は、 原文の同じ文言の繰り返しを集約して再構成している。 】
Run the appropriate set of steps from the following list:If data is a string • If the WebSocket connection is established and the WebSocket closing handshake has not yet started, then the user agent must send a WebSocket Message comprised of the data argument using a text frame opcode; if the data cannot be sent, e.g. because it would need to be buffered but the buffer is full, the user agent must flag the WebSocket as full and then close the WebSocket connection. Any invocation of this method with a string argument that does not throw an exception must increase the bufferedAmount attribute by the number of bytes needed to express the argument as UTF-8. [UNICODE] [ENCODING] [WSP]If data is a Blob object • If the WebSocket connection is established, and the WebSocket closing handshake has not yet started, then the user agent must send a WebSocket Message comprised of data using a binary frame opcode; if the data cannot be sent, e.g. because it would need to be buffered but the buffer is full, the user agent must flag the WebSocket as full and then close the WebSocket connection. The data to be sent is the raw data represented by the Blob object. Any invocation of this method with a Blob argument that does not throw an exception must increase the bufferedAmount attribute by the size of the Blob object’s raw data, in bytes. [WSP] [FILEAPI]If data is an ArrayBuffer • If the WebSocket connection is established, and the WebSocket closing handshake has not yet started, then the user agent must send a WebSocket Message comprised of data using a binary frame opcode; if the data cannot be sent, e.g. because it would need to be buffered but the buffer is full, the user agent must flag the WebSocket as full and then close the WebSocket connection. The data to be sent is the data stored in the buffer described by the ArrayBuffer object. Any invocation of this method with an ArrayBuffer argument that does not throw an exception must increase the bufferedAmount attribute by the length of the ArrayBuffer in bytes. [WSP]If data is an ArrayBufferView • If the WebSocket connection is established, and the WebSocket closing handshake has not yet started, then the user agent must send a WebSocket Message comprised of data using a binary frame opcode; if the data cannot be sent, e.g. because it would need to be buffered but the buffer is full, the user agent must flag the WebSocket as full and then close the WebSocket connection. The data to be sent is the data stored in the section of the buffer described by the ArrayBuffer object that data references. Any invocation of this method with this kind of argument that does not throw an exception must increase the bufferedAmount attribute by the length of data’s buffer in bytes. [WSP] -
bufferedAmount
属性の値 += 前段によるペイロードデータに要するバイト数 ↑
WebSocket
インタフェースを実装するオブジェクトは、
次の表に挙げる[
イベントハンドラ, それに対応する イベントハンドライベント型
]をイベントハンドラ IDL 属性としてサポートするものとする:
The following are the event handlers (and their corresponding event handler event types) that must be supported, as event handler IDL attributes, by all objects implementing the WebSocket interface:
イベントハンドラ | イベントハンドライベント型 |
---|---|
onopen
| open
|
onmessage
| message
|
onerror
| error
|
onclose
| close
|
4. プロトコルからのフィードバック
UA は、 WebSocket 接続を確立したときは, 次の手続きを走らすタスクをキューするものとする: When the WebSocket connection is established, the user agent must queue a task to run these steps:
-
O :← 当の
WebSocket
オブジェクト ↓ -
O の準備状態 ←
OPEN
Change the ready state to OPEN (1). -
IF[
利用中にある拡張 ≠ null 値
]
:O の
extensions
属性値 ← 利用中にある拡張 Change the extensions attribute’s value to the extensions in use, if it is not the null value. [WSP] -
IF[
利用中にある下位プロトコル ≠ null 値
]
:O の
protocol
属性値 ← その値 [WSP] Change the protocol attribute’s value to the subprotocol in use, if it is not the null value. [WSP] -
イベントを発火する( O,
open
) Fire an event named open at the WebSocket object.
注記:
上のアルゴリズムは、
タスクとしてキューされるので,[
確立される WebSocket 接続,
open
イベント用にイベントリスナを設定しておくスクリプト
]との間で競争が生じることはない。
【 すなわち、 new WebSocket()
を呼び出した後に同期的に登録されたイベントリスナが,サーバからの初期メッセージを受け取り損ねることはない。】
Since the algorithm above is queued as a task, there is no race condition between the WebSocket connection being established and the script setting up an event listener for the open event.
UA は, WebSocket メッセージを受信したときは、 所与の ( 種別, データ ) に対し, 次の手続きを走らすタスクをキューするものとする: When a WebSocket message has been received with type type and data data, the user agent must queue a task to follow these steps: [WSP]
【 データ は、 当のメッセージ内に受信したペイロードデータを表す。 種別 ∈ { Text, Binary } は、 メッセージのフレーム種別から指示される データ の種別を表す。 】
-
O :← 当の
WebSocket
オブジェクト ↓ -
IF[
O の準備状態 ≠
OPEN
] :RETURN If ready state is not OPEN (1), then return. -
イベント用のデータ :← 種別 に応じて :Text ならば データ を内容とする,新たな
DOMString
/ Binary ならば O のバイナリ種別に応じて:-
"
blob
" :O に関連する realm 内の新たなBlob
オブジェクト [FILEAPI] — そのバイト列データとして データ を伴う -
"
arraybuffer
" :O に関連する realm 内の新たなArrayBuffer
オブジェクト — そのバッファ内容として データ を伴う
-
"
-
イベントを発火する( O,
message
,MessageEvent
) — 次のように初期化して :origin
属性 ← 生成元を直列化する( O の URL の生成元 ),data
属性 ← イベント用のデータ Fire an event named message at the WebSocket object, using MessageEvent, with the origin attribute initialized to the serialization of the WebSocket object’s url's origin, and the data attribute initialized to dataForEvent.
注記:
UA には、[
上でキューしたタスク タスク を効率的に遂行できるかどうか
]を[
タスク を走らす前に検査しておく
]ことが推奨される
— 効率的に遂行できないときは、
バッファを準備する間は,他のタスクキューからタスクを選び取る等。
例えば,[
データの到着時には、
バイナリ種別は "blob
" にされていて,
UA は すべてのデータをディスクへスプール済みであった
]が[
当のメッセージ用に タスク を走らす直前に,
スクリプトがバイナリ種別を "arraybuffer
" に切り替えた
]場合、
UA は
— ArrayBuffer
オブジェクトを作成している間にメインスレッドが停滞しないよう —
タスク を走らす前にデータを RAM に戻したいと求めるであろう。
User agents are encouraged to check if they can perform the above steps efficiently before they run the task, picking tasks from other task queues while they prepare the buffers if not. For example, if the binary type is "blob" when the data arrived, and the user agent spooled all the data to disk, but just before running the above task for this particular message the script switched binary type to "arraybuffer", the user agent would want to page the data back to RAM before running this task so as to avoid stalling the main thread while it created the ArrayBuffer object.
テキストフレームの場合に message
イベント用にハンドラを定義する例:
Here is an example of how to define a handler for the message event in the case of text frames:
mysocket.onmessage = function (event) { if (event.data == 'on') { turnLampOn(); } else if (event.data == 'off') { turnLampOff(); } };
ここでのプロトコルは、[ サーバが "on" または "off" メッセージを送信するだけの,単純なもの ]とする。 The protocol here is a trivial one, with the server just sending "on" or "off" messages.
UA は、 WebSocket closing ハンドシェイクを開始したときは, 次を走らすタスクをキューするものとする: When the WebSocket closing handshake is started, the user agent must\
( close()
メソッドが call されていた場合、
準備状態は,このタスクを走らす時点で,
すでに CLOSING
に設定されていることになる。)
(If the close() method was called, the ready state will already be set to CLOSING (2) when this task runs.) [WSP]
UA は、 WebSocket 接続が close されたときは (clean に close された場合も含む), 次の手続きを走らすタスクをキューするものとする: When the WebSocket connection is closed, possibly cleanly, the user agent must queue a task to run the following substeps:
-
O :← 当の
WebSocket
オブジェクト ↓ -
O の準備状態 ←
CLOSED
Change the ready state to CLOSED (3). -
IF[
UA は WebSocket 接続を失敗させる必要がある
]∨[
WebSocket 接続は その
満杯か
(初期時は false )が true にされた上で close された
]
:イベントを発火する( O,
error
) If the user agent was required to fail the WebSocket connection, or if the WebSocket connection was closed after being flagged as full, fire an event named error at the WebSocket object. [WSP] -
イベントを発火する( O,
close
,CloseEvent
) — 次のように初期化して :wasClean
属性 ← IS[ 接続は clean に close された ],code
属性 ← WebSocket 接続 close コード,reason
属性 ← BOM はそのままに UTF-8 復号する( WebSocket 接続 close 事由 ) Fire an event named close at the WebSocket object, using CloseEvent, with the wasClean attribute initialized to true if the connection closed cleanly and false otherwise, the code attribute initialized to the WebSocket connection close code, and the reason attribute initialized to the result of applying UTF-8 decode without BOM to the WebSocket connection close reason. [WSP]
警告: UA は、 次に挙げる状況を判別し得るような失敗情報は,スクリプトに伝達しないものとする: User agents must not convey any failure information to scripts in a way that would allow a script to distinguish the following situations:
- サーバのホスト名を解決できなかった。 A server whose host name could not be resolved.
- サーバへパケットを成功裡に route できなかった。 A server to which packets could not successfully be routed.
- 指定されたポートへの接続をサーバが拒否した。 A server that refused the connection on the specified port.
- サーバとの TLS ハンドシェイクを正しく遂行できなかった (例:サーバの証明書を検証できなかった)。 A server that failed to correctly perform a TLS handshake (e.g., the server certificate can’t be verified).
- サーバが opening ハンドシェイクを完了しなかった (例:サーバが WebSocket サーバではなかった)。 A server that did not complete the opening handshake (e.g. because it was not a WebSocket server).
- WebSocket サーバは正しい opening ハンドシェイクを送信したが、 それが指定するオプションにより,クライアントは接続を落とした (例:サーバはクライアントが提供しなかった下位プロトコルを指定してきた)。 A WebSocket server that sent a correct opening handshake, but that specified options that caused the client to drop the connection (e.g. the server specified a subprotocol that the client did not offer).
- WebSocket サーバは opening ハンドシェイクを成功裡に完了した後に突如,接続を close した。 A WebSocket server that abruptly closed the connection after successfully completing the opening handshake.
これらのどの事例でも、 WebSocket 接続 close コードは 1006 になる — [WSP] により要求されるとおり。 In all of these cases, the WebSocket connection close code would be 1006, as required by WebSocket Protocol. [WSP]
スクリプトがこれら各事例を判別できるようになると、[ 攻撃の準備として,利用者のローカルネットワークを探査する ]ことをスクリプトに許容することになる。 Allowing a script to distinguish these cases would allow a script to probe the user’s local network in preparation for an attack.
注記: 特に,このことは、 コード 1015 は,UA からは利用されないことを意味する (もちろん、 サーバが Close フレームに誤って利用した場合は除く)。 In particular, this means the code 1015 is not used by the user agent (unless the server erroneously uses it in its close frame, of course).
この節にてキューされる どのタスクも,そのタスクソースは WebSocket タスクソース とする。 The task source for all tasks queued in this section is the WebSocket task source.
5. Ping フレームと Pong フレーム
[WSP] は、[ 接続維持, 単方向の鼓動, ネットワーク状態探針, 待ち時間の計測, 等々 ]に利用できる[ Ping フレーム, Pong フレーム ]を定義する。 これらは、 現時点では API に公開されていない。 The WebSocket protocol defines Ping and Pong frames that can be used for keep-alive, heart-beats, network status probing, latency instrumentation, and so forth. These are not currently exposed in the API.
UA は、 欲されるなら[ Ping フレーム / 請求されていない Pong フレーム ]を送信してもよい — 例えば[ ローカルネットワーク NAT マッピングを保守する/ 接続を検出する/ 利用者に待ち時間を表示する ]などの試みの一環として。 UA は、 これらのフレームをサーバの援助用として利用しないものとする — サーバは、 必要に応じて適切な時機に pong を請求するものと見做されているので。 User agents may send ping and unsolicited pong frames as desired, for example in an attempt to maintain local network NAT mappings, to detect failed connections, or to display latency metrics to the user. User agents must not use pings or unsolicited pongs to aid the server; it is assumed that servers will solicit pongs whenever appropriate for the server’s needs.
6. CloseEvent
インタフェース
WebSocket
オブジェクトは、
その close
イベント用に CloseEvent
インタフェースを利用する:
WebSocket objects use the CloseEvent interface for their close events:
[Exposed=(Window,Worker)] interfaceCloseEvent
:Event
{ constructor(DOMString type, optionalCloseEventInit
eventInitDict = {}); readonly attribute booleanwasClean
; readonly attribute unsigned shortcode
; readonly attribute USVStringreason
; }; dictionaryCloseEventInit
:EventInit
{ boolean wasClean = false; unsigned short code = 0; USVString reason = ""; };
- event.
wasClean
- [ 接続は clean に close されたならば true / 他の場合は false ]を返す。 Returns true if the connection closed cleanly; false otherwise.
- event.
code
- サーバから供された WebSocket 接続 close コードを返す。 Returns the WebSocket connection close code provided by the server.
- event.
reason
- サーバから供された WebSocket 接続 close 事由を返す。 Returns the WebSocket connection close reason provided by the server.
wasClean
取得子手続きは、
初期化時の値を返す。
それは、[
接続が clean に close されたかどうか
]を表現する。
The wasClean attribute must return the value it was initialized to.\
It represents whether the connection closed cleanly or not.code
取得子手続きは、
初期化時の値を返す。
それは、[
サーバから供された WebSocket 接続 close コード
]を表現する。
The code attribute must return the value it was initialized to.\
It represents the WebSocket connection close code provided by the server.reason
取得子手続きは、
初期化時の値を返す。
それは、[
サーバから供された WebSocket 接続 close 事由
]を表現する。
The reason attribute must return the value it was initialized to.\
It represents the WebSocket connection close reason provided by the server.7. ガーベジ収集
次のいずれかに該当する WebSocket
オブジェクトは、
ガーベジ収集しないものとする:
↓
-
イベントループがその最初の段に最後に達した時点で、 準備状態が[ 次の表の 1 列目に挙げる値 ]にされていて,[ 同じ行の 2 列目に示されるイベント型に対し登録されているイベントリスナが在る ]もの。
準備状態 イベントハンドライベント型 CONNECTING
(0)open
,message
,error
,close
OPEN
(1)message
,error
,close
CLOSING
(2)error
,close
- WebSocket 接続は確立済みであり,ネットワーク伝送用にデータがキューされているもの。 A WebSocket object with an established connection that has data queued to be transmitted to the network must not be garbage collected. [WSP]
接続が open しているにもかかわらず, WebSocket
オブジェクトがガーベジ収集された場合、
UA は,WebSocket closing ハンドシェイクを開始するものとする。
このときの Close メッセージは、
状態°コードを伴わないものとする。
If a WebSocket object is garbage collected while its connection is still open, the user agent must start the WebSocket closing handshake, with no status code for the Close message. [WSP]
UA は, WebSocket
オブジェクトを
消滅させる
必要が生じたときは
(これは、 Document
オブジェクトが消え去るとき起こる)、
次を走らすものとする:
If a user agent is to make disappear a WebSocket object (this happens when a Document object goes away), the user agent must follow the first appropriate set of steps from the following list:
- IF[ WebSocket 接続は確立済みでない ] :WebSocket 接続を失敗させる If the WebSocket connection is not yet established [WSP] • Fail the WebSocket connection. [WSP]
- ELSE IF[ WebSocket closing ハンドシェイクは開始済みでない ] :WebSocket closing ハンドシェイクを開始する — Close メッセージに利用する状態°コードは 1001 とする If the WebSocket closing handshake has not yet been started [WSP] • Start the WebSocket closing handshake, with the status code to use in the WebSocket Close message being 1001. [WSP]Otherwise • Do nothing.
謝辞
2021年におけるこの標準の作成まで、 ここにあるテキストは, HTML と Fetch にて保守されていた。 これら各仕様のリポジトリに貢献して この仕様の開発に助力された,すべての方々に — とりわけ、これら各仕様の元の作者である Ian Hickson, Anne van Kesteren 各氏(同順)に。 Until the creation of this standard in 2021, the text here was maintained in the HTML Standard and Fetch Standard. Thanks to all of the contributors to those repositories who helped develop the specification, especially Ian Hickson and Anne van Kesteren as the respective original authors.
この標準が作成された後における,次に挙げる各氏による貢献に :devsnek, 平野裕( Yutaka Hirano ) Thanks to devsnek and 平野裕 (Yutaka Hirano) for their contributions after the creation of the WebSockets Standard.
この標準は、 Adam Rice ( Google, ricea@chromium.org ) により書かれた。 This standard is written by Adam Rice (Google, ricea@chromium.org).
知的財産権
Copyright © WHATWG (Apple, Google, Mozilla, Microsoft). This work is licensed under a Creative Commons Attribution 4.0 International License. To the extent portions of it are incorporated into source code, such portions in the source code are licensed under the BSD 3-Clause License instead.
This is the Living Standard. Those interested in the patent-review version should view the Living Standard Review Draft.