1. Introduction
This section is non-normative.
To
enable
web
applications
to
maintain
bidirectional
communications
with
server-side
processes,
this
specification
introduces
the
WebSocket
interface.
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.
2. WebSocket protocol alterations
WebSocket
API,
defined
below,
uses
this
language.
[WSP]
[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. Connections
To obtain a WebSocket connection , given a url , run these steps:
-
Let host be url ’s host .
-
Let port be url ’s port .
-
Let resource name be U+002F (/), followed by the strings in url ’s path (including empty strings), if any, separated from each other by U+002F (/).
-
If url ’s query is non-empty, append U+003F (?), followed by url ’s query , to resource name .
-
Let secure be false, if url ’s scheme is "
http
"; otherwise true. -
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]
-
If that established a connection, return it, and return failure otherwise.
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 handshake
To establish a WebSocket connection , given a url , protocols , and client , run these steps:
-
Let requestURL be a copy of url , with its scheme set to "
http
", if url ’s scheme is "ws
"; otherwise to "https
".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]
-
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
". -
Append (`
Upgrade
`, `websocket
`) to request ’s header list . -
Append (`
Connection
`, `Upgrade
`) to request ’s header list . -
Let keyValue be a nonce consisting of a randomly selected 16-byte value that has been forgiving-base64-encoded and isomorphic encoded .
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==
`. -
Append (`
Sec-WebSocket-Key
`, keyValue ) to request ’s header list . -
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 . -
Let permessageDeflate be a user-agent defined "
permessage-deflate
" extension header value . [WSP] -
Append (`
Sec-WebSocket-Extensions
`, permessageDeflate ) to request ’s header list . -
Fetch request with useParallelQueue set to true, and processResponse given response being these steps:
-
If response is a network error or its status is not 101, fail the WebSocket connection .
-
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 .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.
-
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]
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.
The
WebSocket
interface
3.1. Interface definition
The
Web
IDL
definition
for
the
WebSocket
class
is
given
as
follows:
enum {
BinaryType "blob" ,"arraybuffer" }; [Exposed =(Window ,Worker )]interface :
WebSocket EventTarget {constructor (USVString ,
url optional (DOMString or sequence <DOMString >)= []);
protocols readonly attribute USVString url ; // ready stateconst 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 ; // networkingattribute 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 ); // messaging
reason attribute EventHandler onmessage ;attribute BinaryType binaryType ;undefined send ((BufferSource or Blob or USVString )); };
data
Each
WebSocket
object
has
an
associated
url
,
which
is
a
URL
record
.
Each
WebSocket
object
has
an
associated
binary
type
,
which
is
a
BinaryType
.
Initially
it
must
be
"
blob
".
Each
WebSocket
object
has
an
associated
ready
state
,
which
is
a
number
representing
the
state
of
the
connection.
Initially
it
must
be
CONNECTING
(0).
It
can
have
the
following
values:
-
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.
-
socket = new
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
", "wss
", "http
", and "https
" schemes are allowed; others will cause a "SyntaxError
"DOMException
. URLs with fragments will always 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] -
socket . send ( data )
-
Transmits data using the WebSocket connection. data can be a string, a
Blob
, anArrayBuffer
, or anArrayBufferView
. -
socket . close ([ code ] [, reason ])
-
Closes the WebSocket connection, optionally using code as the WebSocket connection close code and reason as the WebSocket connection close reason .
-
socket . url
-
Returns the URL that was used to establish the WebSocket connection.
-
socket . readyState
-
Returns the state of the WebSocket connection. It can have the values described above.
-
socket . 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.) -
socket . extensions
-
Returns the extensions selected by the server, if any.
-
socket . 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.
-
socket . binaryType
-
Returns a string that indicates how binary data from socket is exposed to scripts:
-
"
blob
" -
Binary data is returned in
Blob
form. -
"
arraybuffer
" -
Binary data is returned in
ArrayBuffer
form.
The default is "
blob
". -
"
-
socket . binaryType = value
-
Changes how binary data is returned.
new
WebSocket(
url
,
protocols
)
constructor
steps
are:
-
Let baseURL be this 's relevant settings object 's API base URL .
-
Let urlRecord be the result of
applying thegetting a URLparserrecordtogiven urlwithand baseURL . -
If
urlRecord is failure, then throw a " SyntaxError " DOMException . If urlRecord ’s scheme is " http ", then set urlRecord ’s scheme to " ws ". Otherwise, if urlRecord ’s scheme is " https ", set urlRecord ’s scheme to " wss ". 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 . Ifprotocols 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] -
Let client be this 's relevant settings object .
-
Run this step in parallel :
-
Establish a WebSocket connection given urlRecord , protocols , and client . [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
getter
steps
are
to
return
this
's
url
,
serialized
.
The
readyState
getter
steps
are
to
return
this
's
ready
state
.
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.
close(
code
,
reason
)
method
steps
are:
-
If code is
present, but is neither an integer equal to 1000 nor an integer intherange 3000 to 4999, inclusive, throw an " InvalidAccessError " DOMException . If reason is present,special value "missing", thenrun these substeps: LetsetreasonBytescodebe the result of encoding reason .to null. -
If
reasonBytesreason islonger than 123 bytes, then throw a " SyntaxError " DOMException . Run the first matching steps from the following list: If this 's ready state is CLOSING (2) or CLOSED (3) Do nothing. The connection is already closing or is already closed. If it has not already, a close event will eventually fire as described below . If the WebSocket connection is not yet established [WSP] Fail the WebSocket connection and set this 's ready state to CLOSING (2). [WSP] The fail the WebSocket connection algorithm invokestheclose the WebSocket connection algorithm, whichspecial value "missing", thenestablishes that the WebSocket connection is closed , which fires the close event as described below . If the WebSocket closing handshake has not yet been started [WSP] Start the WebSocket closing handshake andsetthis 's ready state to CLOSING (2). [WSP] If neither code norreasonis present, the WebSocket Close message must not have a body. The 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 codetouse intheWebSocket Close message must be the integer given by code . [WSP]empty string. -
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 thatClose the WebSocketconnection is closed , which fires the closeevent as described below . Otherwise Setwith this's ready state 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, code , andthus the close event will fire, as described below .reason .
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
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.
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.
The
binaryType
getter
steps
are
to
return
this
's
binary
type
.
The
binaryType
setter
steps
are
to
set
this
's
binary
type
to
the
given
value
.
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
)
method
steps
are:
-
If this 's ready state is
CONNECTING
, then throw an "InvalidStateError
"DOMException
. -
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 aBlob
argument that does not throw an exception must increase thebufferedAmount
attribute by the size of theBlob
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 anArrayBuffer
argument that does not throw an exception must increase thebufferedAmount
attribute by the length of theArrayBuffer
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 thebufferedAmount
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
|
4.
3.2.
Feedback
from
the
protocol
When the WebSocket connection is established , the user agent must queue a task to run these steps:
-
Change the ready state 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 theWebSocket
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 ready state is not
OPEN
(1), then return. -
Let dataForEvent be determined by switching on type and binary type :
- type indicates that the data is Text
-
a new
DOMString
containing data -
type
indicates
that
the
data
is
Binary
and
binary
type
is
"blob"
-
a new
Blob
object, created in the relevant Realm of theWebSocket
object, that represents data as its raw data [FILEAPI] -
type
indicates
that
the
data
is
Binary
and
binary
type
is
"arraybuffer"
-
a new
ArrayBuffer
object, created in the relevant Realm of theWebSocket
object, whose contents are data
-
Fire an event named
message
at theWebSocket
object, usingMessageEvent
, with theorigin
attribute initialized to the serialization of theWebSocket
object’s url 's origin , and thedata
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
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.
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
ready
state
to
CLOSING
(2).
(If
the
close()
method
was
called,
the
ready
state
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 ready state to
CLOSED
(3). -
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 theWebSocket
object. [WSP] -
Fire an event named
close
at theWebSocket
object, usingCloseEvent
, with thewasClean
attribute initialized to true if the connection closed cleanly and false otherwise, thecode
attribute initialized to the WebSocket connection close code , and thereason
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:
-
A server whose host name could not be resolved.
-
A server to which packets could not successfully be routed.
-
A server that refused the connection on the specified port.
-
A server that failed to correctly perform a TLS handshake (e.g., the server certificate can’t be verified).
-
A server that did not complete the opening handshake (e.g. because it was not a WebSocket server).
-
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).
-
A WebSocket server that abruptly closed the connection after successfully completing the opening handshake.
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.
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 .
6.
3.3.
The
CloseEvent
interface
WebSocket
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 {; = 0; = "";boolean =
wasClean false ;unsigned short = 0;
code USVString = ""; };
reason
-
event
.
wasClean
-
Returns true if the connection closed cleanly; false otherwise.
-
event
.
code
-
Returns the WebSocket connection close code provided by the server.
-
event
.
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.
7.
3.4.
Garbage
collection
A
WebSocket
object
whose
ready
state
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
ready
state
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
ready
state
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:
- If the WebSocket connection is not yet established [WSP]
- 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
messageframe being 1001. [WSP] - Otherwise
-
Do nothing.
4.
The
WebSocketStream
interface
The
Web
IDL
definition
for
the
WebSocketStream
class
is
given
as
follows:
dictionary {
WebSocketOpenInfo ReadableStream ;
readable WritableStream ;
writable DOMString ;
extensions DOMString ; };
protocol dictionary { [
WebSocketCloseInfo EnforceRange ]unsigned short ;
closeCode USVString = ""; };
reason dictionary {
WebSocketStreamOptions sequence <USVString >;
protocols AbortSignal ; }; [
signal Exposed =(Window ,Worker )]interface {
WebSocketStream constructor (USVString ,
url optional WebSocketStreamOptions = {});
options readonly attribute USVString url ;readonly attribute Promise <WebSocketOpenInfo >opened ;readonly attribute Promise <WebSocketCloseInfo >closed ;undefined close (optional WebSocketCloseInfo = {}); };
closeInfo
Each
WebSocketStream
object
has
an
associated
url
,
which
is
a
URL
record
.
Each
WebSocketStream
object
has
an
associated
opened
promise
,
which
is
a
promise.
Each
WebSocketStream
object
has
an
associated
closed
promise
,
which
is
a
promise.
Each
WebSocketStream
object
has
an
associated
readable
stream
,
which
is
a
ReadableStream
.
Each
WebSocketStream
object
has
an
associated
writable
stream
,
which
is
a
WritableStream
.
Each
WebSocketStream
object
has
an
associated
was
ever
connected
,
which
is
a
boolean,
initially
false.
Each
WebSocketStream
object
has
an
associated
boolean
handshake
aborted
,
which
is
initially
false.
Each
WebSocketStream
object
has
an
associated
ready
state
,
which
is
a
number
representing
the
state
of
the
connection.
Initially
it
must
be
CONNECTING
(0).
It
has
the
same
semantics
as
WebSocket
's
ready
state
,
but
is
not
exposed
to
JavaScript.
socket = new
WebSocketStream
( url [, options ])Creates a new
WebSocketStream
object, immediately establishing the associated WebSocket connection.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 also cause such an exception.The options argument is an object whose properties can be set as follows:
protocols
An array of strings. If it is omitted, it is equivalent to an 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]signal
An
AbortSignal
that can be used to abort the handshake. After the handshake is complete, the signal does nothing.
socket .
url
Returns the URL that was used to establish the WebSocket connection.
socket .
opened
Returns a
Promise
which resolves when the handshake successfully completes, or rejects if the handshake fails. On success, it resolves to an object with the following properties:readable
A
ReadableStream
that can be used to read messages from the server. Each chunk read corresponds to one message. Text messages will be read as strings; binary messages will be read asUint8Array
objects.The original
WebSocket
API suppliedArrayBuffer
objects, but modern practice is to prefer theUint8Array
type for binary data, particularly when using streams. The underlyingArrayBuffer
object can be recovered by accessingchunk .buffer
.The stream can be closed by calling
cancel()
onreadable
. If the reason argument passed tocancel()
is aWebSocketError
object thencloseCode
will be used as the WebSocket connection close code andreason
will be used as the WebSocket connection close reason .If no messages are read, or if messages are read slower than they are sent, then backpressure will be applied and eventually the server will stop sending new messages.
writable
A
WritableStream
that can be used to send messages to the server. Each chunk written will be converted to one message. Strings will be sent as text messages;BufferSource
chunks will be sent as binary messages. Backpressure due to the network or server being unable to process data fast enough will automatically be observed by piping. When using a writable stream writer , waiting for thewriter.ready
promise will ensure that backpressure is obeyed.The WebSocket can be closed by calling
close()
onwritable
.The stream can also be closed by calling
abort()
onwritable
. If the reason passed toabort()
is aWebSocketError
, then it will be used to set the WebSocket connection close code and the WebSocket connection close reason as withcancel()
above.extensions
The extensions in use for the connection.
protocol
The subprotocol in use for the connection.
socket .
closed
A
Promise
which resolves when the connection is closed. If the connection did not close cleanly then the promise is rejected with aWebSocketError
. When the connection closes cleanly the promise is fulfilled with an object with propertiescloseCode
andreason
, giving the WebSocket connection close code and the WebSocket connection close reason that were supplied by the server.socket .
close()
socket .
close
({closeCode
,reason
})Close the connection, optionally supplying an object with
closeCode
andreason
properties to indicate the WebSocket connection close code and the WebSocket connection close reason that will be sent to the remote server. If the handshake is still in progress, then it will be aborted andcloseCode
andreason
will be ignored.
The
new
WebSocketStream(
url
,
options
)
constructor
steps
are:
Let baseURL be this 's relevant settings object 's API base URL .
Let urlRecord be the result of getting a URL record given url and baseURL .
Let protocols be options ["
protocols
"] if it exists , otherwise an empty sequence.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]Set this 's opened promise and closed promise to new promises.
Apply backpressure to the WebSocket.
This means that messages won’t be read until the application is ready for them.
If options ["
signal
"] exists ,Let signal be options ["
signal
"].If signal is aborted , then reject this 's opened promise and closed promise with signal ’s abort reason and return.
Add the following abort steps to signal :
If the WebSocket connection is not yet established : [WSP]
Set this 's ready state to
CLOSING
.Reject this 's opened promise and closed promise with signal ’s abort reason .
Set this 's handshake aborted to true.
Let client be this 's relevant settings object .
Run this step in parallel :
Establish a WebSocket connection given urlRecord , protocols , and client . [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. This establishes that the WebSocket connection is closed , which rejects the
opened
andclosed
promises.
The
url
getter
steps
are
to
return
this
's
url
,
serialized
.
The
opened
getter
steps
are
to
return
this
's
opened
promise
.
The
closed
getter
steps
are
to
return
this
's
closed
promise
.
close(
closeInfo
)
method
steps
are:
Let code be closeInfo ["
closeCode
"] if present, or null otherwise.Let reason be closeInfo ["
reason
"].Close the WebSocket with this , code , and reason .
4.1. Feedback to WebSocketStream from the protocol
When
the
WebSocket
connection
is
established
for
a
WebSocketStream
stream
,
the
user
agent
must
queue
a
global
task
on
the
WebSocket
task
source
given
stream
’s
relevant
global
object
to
run
these
steps:
Change stream ’s ready state to
OPEN
(1).Set stream ’s was ever connected to true.
Let extensions be the extensions in use .
Let protocol be the subprotocol in use .
Let pullAlgorithm be an action that pulls bytes from stream .
Let cancelAlgorithm be an action that cancels stream with reason , given reason .
Let readable be a new
ReadableStream
.Set up readable with pullAlgorithm and cancelAlgorithm .
Let writeAlgorithm be an action that writes chunk to stream , given chunk .
Let closeAlgorithm be an action that closes stream .
Let abortAlgorithm be an action that aborts stream with reason , given reason .
Let writable be a new
WritableStream
.Set up writable with writeAlgorithm , closeAlgorithm , and abortAlgorithm .
Set stream ’s readable stream to readable .
Set stream ’s writable stream to writable .
Resolve stream ’s opened promise with
WebSocketOpenInfo
«[ "extensions
" → extensions , "protocol
" → protocol , "readable
" → readable , "writable
" → writable ]».
When
a
WebSocket
message
has
been
received
for
a
WebSocketStream
stream
with
type
type
and
data
data
,
the
user
agent
must
queue
a
global
task
on
the
WebSocket
task
source
given
stream
’s
relevant
global
object
to
follow
these
steps:
[WSP]
If stream ’s ready state is not
OPEN
(1), then return.Let chunk be determined by switching on type :
- type indicates that the data is Text
a new
DOMString
containing data- type indicates that the data is Binary
a new
Uint8Array
object, created in the relevant Realm of theWebSocketStream
object, whose contents are data
Enqueue chunk into stream ’s readable stream .
Apply backpressure to the WebSocket.
Applying backpressure will result in no new WebSocket messages being handled until the backpressure is released. After an implementation-defined amount of data is buffered, the client will stop reading from the underlying network connection resulting in network-layer backpressure being applied.
When
the
WebSocket
closing
handshake
is
started
for
a
WebSocketStream
stream
,
the
user
agent
must
queue
a
global
task
on
the
WebSocket
task
source
given
stream
’s
relevant
global
object
to
change
stream
’s
ready
state
to
CLOSING
[WSP]
When
the
WebSocket
connection
is
closed
for
a
WebSocketStream
stream
,
possibly
cleanly
,
the
user
agent
must
queue
a
global
task
on
the
WebSocket
task
source
given
stream
’s
relevant
global
object
to
run
the
following
substeps:
Change stream ’s ready state to
CLOSED
(3).If stream ’s handshake aborted is true, then return.
If stream ’s was ever connected is false, then reject stream ’s opened promise with a new
WebSocketError
.Let code be the WebSocket connection close code .
Let reason be the result of applying UTF-8 decode without BOM to the WebSocket connection close reason .
If the connection was closed cleanly ,
Close stream ’s readable stream .
Error stream ’s writable stream with an "
InvalidStateError
"DOMException
indicating that a closedWebSocketStream
cannot be written to.Resolve stream ’s closed promise with
WebSocketCloseInfo
«[ "closeCode
" → code , "reason
" → reason ]».
Otherwise,
Let error be a new
WebSocketError
whose closeCode is code and reason is reason .Error stream ’s readable stream with error .
Error stream ’s writable stream with error .
Reject stream ’s closed promise with error .
4.2. Stream operations
To
pull
bytes
from
a
WebSocketStream
stream
,
if
stream
is
currently
applying
backpressure,
release
backpressure.
If any messages are queued, one will be handled immediately as a result.
To
cancel
a
WebSocketStream
stream
given
reason
,
close
using
reason
giving
stream
and
reason
.
To
write
chunk
to
a
WebSocketStream
stream
:
Let promise be a new promise created in stream ’s relevant realm .
Let data be null.
Let opcode be null.
If chunk is a
BufferSource
,Set data to a copy of the bytes given chunk .
Set opcode to a binary frame opcode.
Otherwise,
Let string be the result of converting chunk to an IDL
USVString
. If this throws an exception, return a promise rejected with the exception.Set data to the result of UTF-8 encoding string .
Set opcode to a text frame opcode.
In parallel,
Wait until there is sufficient buffer space in stream to send the message.
This means that backpressure will be applied when the user agent’s buffers are full.
If the closing handshake has not yet started , Send a WebSocket Message to stream comprised of data using opcode .
Queue a global task on the WebSocket task source given stream ’s relevant global object to resolve promise with undefined.
Return promise .
To
close
a
WebSocketStream
stream
,
close
the
WebSocket
with
stream
(
code
and
reason
are
not
set).
To
abort
a
WebSocketStream
stream
given
reason
,
close
using
reason
giving
stream
and
reason
.
To
close
using
reason
a
WebSocketStream
stream
given
reason
:
Let code be null.
Let reasonString be the empty string.
If reason implements
WebSocketError
,Close the WebSocket with stream , code , and reasonString . If this throws an exception, discard code and reasonString and close the WebSocket with stream .
A
WebSocketError
object
constructed
from
JavaScript
will
always
have
a
closeCode
and
reason
that
JavaScript
is
permitted
to
set.
However,
the
closed
promise
might
be
rejected
with
a
WebSocketError
whose
closeCode
has
a
value
coming
from
the
server
that
JavaScript
is
not
permitted
to
set
itself,
such
as
1001
"Going
Away".
4.3.
The
WebSocketError
interface
WebSocketError
is
a
subclass
of
DOMException
that
represents
the
information
associated
with
closing
a
WebSocket.
[Exposed =(Window ,Worker )]interface WebSocketError :DOMException {constructor (optional DOMString = "",
message optional WebSocketCloseInfo = {});
init readonly attribute unsigned short ?closeCode ;readonly attribute USVString reason ; };
Each
WebSocketError
object
has
an
associated
closeCode
,
which
is
a
number
or
null,
and
defaults
to
null.
Each
WebSocketError
object
has
an
associated
reason
,
which
is
a
string,
and
defaults
to
the
empty
string.
error = new
WebSocketError
([ message [, init ]])Creates a new
WebSocketError
object.message is a string which will be used to initialize the
message
attribute of the base class.The init argument is an object whose properties can be set as follows:
closeCode
A number, either 1000 or any integer in the range 3000 to 4999, inclusive. Any other number will result in an "
InvalidAccessError
"DOMException
. If a non-emptyreason
is set, defaults to 1000, since there is no way to send a non-empty reason without a close code.reason
A string. Must be 123 bytes or less when converted to UTF-8 . A longer string will result in a "
SyntaxError
"DOMException
being thrown. Defaults to the empty string.
error .
closeCode
Returns the the WebSocket connection close code .
error .
reason
Returns the the WebSocket connection close reason .
The
new
WebSocketError(
message
,
init
)
constructor
steps
are:
Let code be init ["
closeCode
"] if it exists , or null otherwise.Let reason be init ["
reason
"] if it exists , or the empty string otherwise.Validate close code and reason with code and reason .
If reason is non-empty, but code is null, then set code to 1000 ("Normal Closure").
The
closeCode
getter
steps
are
to
return
this
's
closeCode
.
The
reason
getter
steps
are
to
return
this
's
reason
.
5. Common algorithms
These
algorithms
are
shared
between
the
WebSocket
and
WebSocketStream
interfaces.
To get a URL record given a url and baseURL :
Let urlRecord be the result of applying the URL parser to url with baseURL .
If urlRecord is failure, then throw a "
SyntaxError
"DOMException
.If urlRecord ’s scheme is "
http
", then set urlRecord ’s scheme to "ws
".Otherwise, if urlRecord ’s scheme is "
https
", set urlRecord ’s scheme to "wss
".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
.Return urlRecord .
To validate close code and reason given a code and reason :
If code is not null, 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 not null, then:
Let reasonBytes be the result of UTF-8 encoding reason .
If reasonBytes is longer than 123 bytes, then throw a "
SyntaxError
"DOMException
.
To
close
the
WebSocket
for
a
WebSocket
or
WebSocketStream
object
,
given
optional
code
and
optional
reason
:
If code was not supplied, let code be null.
If reason was not supplied, let reason be the empty string.
Validate close code and reason with code and reason .
Run the first matching steps from the following list:
-
If
object
’s
ready
state
is
CLOSING
(2) orCLOSED
(3) Do nothing.
The connection is already closing or is already closed. If it has not already, a
close
event will eventually fire if object is aWebSocket
, or theclosed
promise will become settled if object is aWebSocketStream
.- If the WebSocket connection is not yet established [WSP]
Fail the WebSocket connection and set object ’s ready state 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 if object is aWebSocket
, or settles theclosed
promise if object is aWebSocketStream
.- If the WebSocket closing handshake has not yet been started [WSP]
Start the WebSocket closing handshake and set object ’s ready state to
CLOSING
(2). [WSP]If code is null and reason is the empty string, the WebSocket Close frame must not have a body.
The WebSocket Protocol erroneously states that the status code is required for the start the WebSocket closing handshake algorithm.
if reason is non-empty but code is null, then set code to 1000 ("Normal Closure").
If code is set, then the status code to use in the WebSocket Close frame must be the integer given by code . [WSP]
If reason is non-empty, then reason , encoded as UTF-8 , must be provided in the Close frame 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 if object is aWebSocket
, or settles theclosed
promise if object is aWebSocketStream
.- Otherwise
Set object ’s ready state 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 or theclosed
promise will resolve, depending on the type of object .
-
If
object
’s
ready
state
is
6. Ping and Pong frames
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.
Acknowledgments
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.
Thanks to devsnek and 平野裕 (Yutaka Hirano) for their contributions after the creation of the WebSockets Standard.
This standard is written by Adam Rice ( Google , ricea@chromium.org ).
Intellectual property rights
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 .