This section is non-normative.
为使得 Web 应用能够维持与服务器端进程的双向通信,
本规范引入了 WebSocket
接口。
该接口不允许对底层网络的直接访问。 例如,没有自定义服务器代理消息的话,该接口实现不了 IRC 客户端。
WebSocket
interfaceenum BinaryType { "blob", "arraybuffer" };
[Exposed=(Window,Worker)]
interface WebSocket : EventTarget {
constructor(USVString url, optional (DOMString or sequence<DOMString>) protocols = []);
readonly attribute USVString url;
// ready state
const unsigned short CONNECTING = 0;
const unsigned short OPEN = 1;
const unsigned short CLOSING = 2;
const unsigned short CLOSED = 3;
readonly attribute unsigned short readyState;
readonly attribute unsigned long long bufferedAmount;
// networking
attribute EventHandler onopen;
attribute EventHandler onerror;
attribute EventHandler onclose;
readonly attribute DOMString extensions;
readonly attribute DOMString protocol;
undefined close(optional [Clamp] unsigned short code, optional USVString reason);
// messaging
attribute EventHandler onmessage;
attribute BinaryType binaryType;
undefined send(USVString data);
undefined send(Blob data);
undefined send(ArrayBuffer data);
undefined send(ArrayBufferView data);
};
Each WebSocket
object has an associated url (a URL record).
WebSocket
(url [, protocols ] )Creates a new WebSocket
object, immediately establishing the associated
WebSocket connection.
url is a string giving the URL over which the connection is
established. Only "ws
" or "wss
" schemes are
allowed; others will cause a "SyntaxError
"
DOMException
. URLs with fragments
will also cause such an exception.
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]
send
( data )Transmits data using the WebSocket connection. data can be a string, a
Blob
, an ArrayBuffer
, or an ArrayBufferView
.
close
( [ code ] [, reason ] )Closes the WebSocket connection, optionally using code as the the WebSocket connection close code and reason as the the WebSocket connection close reason.
url
Returns the URL that was used to establish the WebSocket connection.
readyState
Returns the state of the WebSocket
object's connection. It can have the values
described below.
bufferedAmount
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.
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.)
extensions
Returns the extensions selected by the server, if any.
protocol
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.
binaryType
[ = value ]Returns a string that indicates how binary data from the WebSocket
object is
exposed to scripts:
blob
"Binary data is returned in Blob
form.
arraybuffer
"Binary data is returned in ArrayBuffer
form.
Can be set, to change how binary data is returned. The default is "blob
".
The WebSocket(url,
protocols)
constructor, when invoked, must run these steps:
Let urlRecord be the result of applying the URL parser to url.
If urlRecord is failure, then throw a "SyntaxError
"
DOMException
.
If urlRecord's scheme is not "ws
" or "wss
", then throw a
"SyntaxError
" DOMException
.
If urlRecord's fragment is non-null,
then throw a "SyntaxError
" DOMException
.
If protocols is a string, set protocols to a sequence consisting of just that string.
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]
Run this step in parallel:
Establish a WebSocket connection given urlRecord, protocols, and the entry settings object. [FETCH]
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.
The url
attribute's getter must return this
WebSocket
object's url, serialized.
The readyState
attribute represents
the state of the connection. It can have the following values:
CONNECTING
(numeric value 0)OPEN
(numeric value 1)CLOSING
(numeric value 2)close()
method has been invoked.CLOSED
(numeric value 3)When the object is created its readyState
must be
set to CONNECTING
(0).
The extensions
attribute must
initially return the empty string. After the WebSocket
connection is established, its value might change, as defined below.
The protocol
attribute must initially
return the empty string. After the WebSocket connection
is established, its value might change, as defined below.
The close(code,
reason)
method, when invoked, must run these steps:
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 is present, then run these substeps:
Let reasonBytes be the result of encoding reason.
If reasonBytes is longer than 123 bytes, then throw a
"SyntaxError
" DOMException
.
Run the first matching steps from the following list:
readyState
attribute is in the CLOSING
(2) or CLOSED
(3) stateDo nothing.
The connection is already closing or is already closed. If it has not already,
a close
event will eventually fire as described below.
Fail the WebSocket connection and set the readyState
attribute's value to CLOSING
(2). [WSP]
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.
Start the WebSocket closing
handshake and set the readyState
attribute's value to CLOSING
(2). [WSP]
If neither code nor reason is present, the WebSocket Close message must not have a body.
WebSocket Protocol erroneously states that the status code is required for the start the WebSocket closing handshake algorithm.
If code is present, then the status code to use in the WebSocket Close message must be the integer given by close. [WSP]
If reason is also present, then reasonBytes must be provided in the Close message after the status code. [WSP]
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.
Set the readyState
attribute's value to CLOSING
(2).
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.
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.
The bufferedAmount
attribute must
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.
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);
};
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.
When a WebSocket
object is created, its binaryType
IDL attribute must be set to the string
"blob
". On getting, it must return the last
value it was set to. On setting, the user agent must set the IDL attribute to the new value.
User agents can use the
binaryType
attribute as a hint for
how to handle incoming binary data: if the attribute is set to "blob
", it is safe to spool it to disk, and if it is set to
"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.
The send(data)
method transmits
data using the connection. If the readyState
attribute is CONNECTING
, it must throw an
"InvalidStateError
" DOMException
. Otherwise, the user agent
must run the appropriate set of steps from the following list:
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]
Blob
objectIf 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]
ArrayBuffer
objectIf 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]
ArrayBufferView
type definitionIf 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]
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:
Event handler | Event handler event type |
---|---|
onopen | open
|
onmessage | message
|
onerror | error
|
onclose | close
|
When the WebSocket connection is established, the user agent must queue a task to run these steps:
Change the readyState
attribute's value to
OPEN
(1).
Change the extensions
attribute's value to
the extensions in use, if it is not the null
value. [WSP]
Change the protocol
attribute's value to the
subprotocol in use, if it is not the null value.
[WSP]
Fire an event named open
at the WebSocket
object.
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.
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]
If the readyState
attribute's value is not
OPEN
(1), then return.
Let dataForEvent be determined by switching on type and binaryType
:
DOMString
containing databinaryType
is "blob
"Blob
object, created in the relevant Realm of the WebSocket
object,
that represents data as its raw data [FILEAPI]binaryType
is "arraybuffer
"ArrayBuffer
object, created in the relevant Realm of the WebSocket
object,
whose contents are dataFire 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.
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 binaryType
attribute was set to "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 binaryType
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.
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();
}
};
The protocol here is a trivial one, with the server just sending "on" or "off" messages.
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.) [WSP]
When the WebSocket connection is closed, possibly cleanly, the user agent must queue a task to run the following substeps:
Change the readyState
attribute's value to
CLOSED
(3).
If the user agent was required to fail the WebSocket
connection, or if the the WebSocket connection was
closed after being flagged as full, fire an event named error
at the
WebSocket
object. [WSP]
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]
User agents must not convey any failure information to scripts in a way that would allow a script to distinguish the following situations:
In all of these cases, the 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.
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).
The task source for all tasks queued in this section is the WebSocket task source.
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.
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.
CloseEvent
interfaceWebSocket
objects use the CloseEvent
interface for their close
events:
[Exposed=(Window,Worker)]
interface CloseEvent : Event {
constructor(DOMString type, optional CloseEventInit eventInitDict = {});
readonly attribute boolean wasClean;
readonly attribute unsigned short code;
readonly attribute USVString reason;
};
dictionary CloseEventInit : EventInit {
boolean wasClean = false;
unsigned short code = 0;
USVString reason = "";
};
wasClean
Returns true if the connection closed cleanly; false otherwise.
code
Returns the WebSocket connection close code provided by the server.
reason
Returns the WebSocket connection close reason provided by the server.
The wasClean
attribute must return the
value it was initialized to. It represents whether the connection closed cleanly or not.
The code
attribute must return the value
it was initialized to. It represents the WebSocket connection close code provided by the
server.
The reason
attribute must return the
value it was initialized to. It represents the WebSocket connection close reason provided by the
server.
A WebSocket
object whose readyState
attribute's value was set to CONNECTING
(0) as of
the last time the event loop reached step 1 must not be garbage collected if there
are any event listeners registered for open
events, message
events, error
events, or
close
events.
A WebSocket
object whose readyState
attribute's value was set to OPEN
(1) as of the last time
the event loop reached step 1 must not be garbage collected if there are any event
listeners registered for message
events, error
, or close
events.
A WebSocket
object whose readyState
attribute's value was set to CLOSING
(2) as of the
last time the event loop reached step 1 must not be garbage collected if there are
any event listeners registered for error
or close
events.
A WebSocket
object with an
established connection that has data queued to be transmitted to the network must not be
garbage collected. [WSP]
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]
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:
Start the WebSocket closing handshake, with the status code to use in the WebSocket Close message being 1001. [WSP]
Do nothing.