diff --git a/index.bs b/index.bs index d87916a..e82d4c0 100644 --- a/index.bs +++ b/index.bs @@ -238,70 +238,87 @@ interface WebSocket : EventTarget { }; -Each {{WebSocket}} object has an associated url -(a [=URL record=]). +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 "{{BinaryType/blob}}". + +Each {{WebSocket}} object has an associated ready state, which is a +number representing the state of the connection. Initially it must be {{WebSocket/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 {{WebSocket/close()}} method has been invoked. +: CLOSED (numeric value 3) +:: The connection has been closed or could not be opened.
- : |socket| = new {{WebSocket/constructor(url, protocols)|WebSocket}}(|url| [, |protocols| ] ) + : |socket| = new {{WebSocket/constructor(url, protocols)|WebSocket}}(|url| [, |protocols| ]) :: Creates a new {{WebSocket}} object, immediately establishing the associated WebSocket - connection. + 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. + |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]] + |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| ) + : |socket|.send(|data|) :: Transmits |data| using the WebSocket connection. |data| can be a string, a {{Blob}}, an - {{ArrayBuffer}}, or an {{ArrayBufferView}}. + {{ArrayBuffer}}, or an {{ArrayBufferView}}. - : |socket| . close( [ |code| ] [, |reason| ] ) + : |socket|.close([ |code| ] [, |reason| ]) :: Closes the WebSocket connection, optionally using |code| as [=the WebSocket connection - close code=] and |reason| as the [=the WebSocket connection close reason=]. + close code=] and |reason| as the [=the WebSocket connection close reason=]. - : |socket| . url + : |socket|.url :: Returns the URL that was used to establish the WebSocket connection. - : |socket| . readyState - :: Returns the state of the {{WebSocket}} object's connection. It can have the values described - below. + : |socket|.readyState + :: Returns the state of the WebSocket connection. It can have the values described above. - : |socket| . bufferedAmount + : |socket|.bufferedAmount :: Returns the number of bytes of application data (UTF-8 text and binary data) that have been - queued using {{WebSocket/send()}} but not yet been transmitted to the network. + queued using {{WebSocket/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 {{WebSocket/send()}} method. (The number does not reset to zero once the connection - closes.) + If the WebSocket connection is closed, this attribute's value will only increase with each call + to the {{WebSocket/send()}} method. (The number does not reset to zero once the connection + closes.) - : |socket| . extensions + : |socket|.extensions :: Returns the extensions selected by the server, if any. - : |socket| . protocol + : |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. + 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: - : |socket| . binaryType [ = value ] - :: Returns a string that indicates how binary data from the {{WebSocket}} object is exposed to - scripts: + : "{{BinaryType/blob}}" + :: Binary data is returned in {{Blob}} form. + : "{{BinaryType/arraybuffer}}" + :: Binary data is returned in {{ArrayBuffer}} form. - : "{{BinaryType/blob}}" - :: Binary data is returned in {{Blob}} form. - : "{{BinaryType/arraybuffer}}" - :: Binary data is returned in {{ArrayBuffer}} form. + The default is "{{BinaryType/blob}}". - Can be set, to change how binary data is returned. The default is "{{BinaryType/blob}}" + : |socket|.binaryType = value + :: Changes how binary data is returned.
- The new WebSocket(|url|, |protocols|) constructor steps are: @@ -330,23 +347,11 @@ Each {{WebSocket}} object has an associated serialized. - -The readyState attribute represents the state of the -connection. 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 {{WebSocket/close()}} method has been invoked. -: CLOSED (numeric value 3) -:: The connection has been closed or could not be opened. +The url getter steps are to return [=this=]'s +[=WebSocket/internal-url|url=], [=URL serializer|serialized=]. -When the object is created its {{WebSocket/readyState}} must be set to {{WebSocket/CONNECTING}} (0). +The readyState getter steps are to return [=this=]'s +[=WebSocket/ready state=]. The extensions attribute must initially return the empty string. After [=the WebSocket connection is established=], its value might change, as defined @@ -356,9 +361,7 @@ The protocol attribute must initially return 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: + The close(|code|, |reason|) method steps are: 1. 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}}. @@ -367,51 +370,50 @@ string. After [=the WebSocket connection is established=], its value might chang 1. If |reasonBytes| is longer than 123 bytes, then throw a "{{SyntaxError}}" {{DOMException}}. 1. Run the first matching steps from the following list:
- : If the {{WebSocket/readyState}} attribute is in the {{WebSocket/CLOSING}} (2) or - {{WebSocket/CLOSED}} (3) state + : If [=this=]'s [=WebSocket/ready state=] is {{WebSocket/CLOSING}} (2) or {{WebSocket/CLOSED}} (3) :: Do nothing.

The connection is already closing or is already closed. If it has not already, a {{close!!event}} event will eventually fire as described below. : If the WebSocket connection is not yet [=established=] [[!WSP]] - :: [=Fail the WebSocket connection=] and set the {{WebSocket/readyState}} attribute's value to - {{WebSocket/CLOSING}} (2). [[!WSP]] + :: [=Fail the WebSocket connection=] and set [=this=]'s [=WebSocket/ready state=] to + {{WebSocket/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}} event as described below. +

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}} event as described + below. : If the WebSocket closing handshake has not yet been started [[!WSP]] - :: [=Start the WebSocket closing handshake=] and set the {{WebSocket/readyState}} attribute's - value to {{WebSocket/CLOSING}} (2). [[!WSP]] + :: [=Start the WebSocket closing handshake=] and set [=this=]'s [=WebSocket/ready state=] to + {{WebSocket/CLOSING}} (2). [[!WSP]] - If neither |code| nor |reason| is present, the WebSocket Close message must not have a body. + If neither |code| nor |reason| is 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. - +

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 code to use in the WebSocket Close message - must be the integer given by |code|. [[!WSP]] + If |code| is present, then the status code to use in the WebSocket Close + message must be the integer given by |code|. [[!WSP]] - If |reason| is also present, then |reasonBytes| must be provided in the Close message after the - status code. [[!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}} event as - described below. +

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}} event as + described below. : Otherwise - :: Set the {{WebSocket/readyState}} attribute's value to {{WebSocket/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}} event will fire, as described below. + :: Set [=this=]'s [=WebSocket/ready state=] to {{WebSocket/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}} event will fire, as described below.

@@ -423,9 +425,9 @@ do it. -->
-The bufferedAmount attribute must return the number of bytes of -application data (UTF-8 text and binary data) that have been queued using {{WebSocket/send()}} but -that, as of the last time the [=event loop=] reached step 1, had not yet +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 {{WebSocket/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, @@ -455,68 +457,77 @@ of the value of the attribute over time.
-When a {{WebSocket}} object is created, its binaryType IDL -attribute must be set to the string "{{BinaryType/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 "{{BinaryType/blob}}", it is safe to spool it to -disk, and if it is set to "{{BinaryType/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 -{{WebSocket/readyState}} attribute is {{WebSocket/CONNECTING}}, it must throw an -"{{InvalidStateError}}" {{DOMException}}. Otherwise, the user agent must run the appropriate set of -steps from the following list: - -: If the argument 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 {{WebSocket/bufferedAmount}} attribute by the number of bytes needed to express the argument as - UTF-8. [[!UNICODE]] [[!ENCODING]] [[!WSP]] - - -: If the argument 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 {{WebSocket/bufferedAmount}} - attribute by the size of the {{Blob}} object's raw data, in bytes. [[!WSP]] [[!FILEAPI]] - -: If the argument is an {{ArrayBuffer}} 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 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 {{WebSocket/bufferedAmount}} attribute by the length of the {{ArrayBuffer}} in bytes. - [[!WSP]] - -: If the argument is an object that matches the {{ArrayBufferView}} type definition -:: 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 {{WebSocket/bufferedAmount}} attribute - by the length of |data|'s buffer in bytes. [[!WSP]] +The binaryType getter steps are to return [=this=]'s +[=WebSocket/binary type=]. + +The {{WebSocket/binaryType}} setter steps are to set [=this=]'s [=WebSocket/binary type=] to +[=the given value=]. + +

User agents can use the [=WebSocket/binary type=] as a hint for how to handle +incoming binary data: if it is "{{BinaryType/blob}}", it is safe to spool it to disk, and if it is +"{{BinaryType/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 steps are: + + 1. If [=this=]'s [=WebSocket/ready state=] is {{WebSocket/CONNECTING}}, then throw an + "{{InvalidStateError}}" {{DOMException}}. + + 2. 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 {{WebSocket/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 {{WebSocket/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 {{WebSocket/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 + {{WebSocket/bufferedAmount}} attribute by the length of |data|'s buffer in bytes. [[!WSP]] +

@@ -542,8 +553,7 @@ steps:
- 1. Change the {{WebSocket/readyState}} attribute's value to {{WebSocket/OPEN}} - (1). + 1. Change the [=WebSocket/ready state=] to {{WebSocket/OPEN}} (1). 1. Change the {{WebSocket/extensions}} attribute's value to the [=extensions in use=], if it is not the null value. [[!WSP]] 1. Change the {{WebSocket/protocol}} attribute's value to the [=subprotocol in @@ -563,20 +573,19 @@ being established and the script setting up an event listener for the {{open 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]] - 1. If the {{WebSocket/readyState}} attribute's value is not {{WebSocket/OPEN}} (1), then - return. - 1. Let |dataForEvent| be determined by switching on |type| and {{WebSocket/binaryType}}: + 1. If [=WebSocket/ready state=] ]is not {{WebSocket/OPEN}} (1), then return. + 1. Let |dataForEvent| be determined by switching on |type| and [=WebSocket/binary type=]:
: |type| indicates that the data is Text :: a new {{DOMString}} containing |data| - : |type| indicates that the data is Binary and {{WebSocket/binaryType}} is + : |type| indicates that the data is Binary and [=WebSocket/binary type=] is "blob" :: a new {{Blob}} object, created in the [=relevant Realm=] of the {{WebSocket}} object, that represents |data| as its raw data [[!FILEAPI]] - : |type| indicates that the data is Binary and {{WebSocket/binaryType}} is + : |type| indicates that the data is Binary and [=WebSocket/binary type=] is "arraybuffer" :: a new {{ArrayBuffer}} object, created in the [=relevant Realm=] of the {{WebSocket}} object, whose contents are |data| @@ -588,10 +597,10 @@ When [=a WebSocket message has been received=] with type |type| and data |data|, {{MessageEvent/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 {{WebSocket/binaryType}} attribute was set to "{{BinaryType/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 {{WebSocket/binaryType}} to +before they run the task, picking tasks from other [=task queues=] while they prepare the buffers +if not. For example, if the [=WebSocket/binary type=] is "{{BinaryType/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 [=WebSocket/binary type=] to "{{BinaryType/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. @@ -618,10 +627,10 @@ The protocol here is a trivial one, with the server just sending "on" or "off" m


-When [=the websocket closing handshake is started=], the user agent must [=queue a task=] to change -the {{WebSocket/readyState}} attribute's value to {{WebSocket/CLOSING}} (2). (If the -{{WebSocket/close()}} method was called, the {{WebSocket/readyState}} attribute's value will already -be set to {{WebSocket/CLOSING}} (2) when this task runs.) [[!WSP]] +When [=the WebSocket closing handshake is started=], the user agent must [=queue a task=] to change +the [=WebSocket/ready state=] to {{WebSocket/CLOSING}} (2). (If the {{WebSocket/close()}} method +was called, the [=WebSocket/ready state=] will already be set to {{WebSocket/CLOSING}} (2) when +this task runs.) [[!WSP]]
@@ -629,8 +638,7 @@ be set to {{WebSocket/CLOSING}} (2) when this task runs.) [[!WSP]] agent must [=queue a task=] to run the following substeps:
- - 1. Change the {{WebSocket/readyState}} attribute's value to {{WebSocket/CLOSED}} (3). + 1. Change the [=WebSocket/ready state=] to {{WebSocket/CLOSED}} (3). 1. 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!!event}} at the {{WebSocket}} object. [[!WSP]] @@ -639,7 +647,6 @@ be set to {{WebSocket/CLOSING}} (2) when this task runs.) [[!WSP]] and false otherwise, the {{CloseEvent/code}} attribute initialized to [=the WebSocket connection close code=], and the {{CloseEvent/reason}} attribute initialized to the result of applying [=UTF-8 decode without BOM=] to [=the WebSocket connection close reason=]. [[!WSP]] -
@@ -738,20 +745,20 @@ to. It represents the WebSocket connection close reason provided by the server. # Garbage collection # {#garbage-collection} -A {{WebSocket}} object whose {{WebSocket/readyState}} attribute's value was set to -{{WebSocket/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!!event}} -events, {{message!!event}} events, {{error!!event}} events, or {{close!!event}} events. +A {{WebSocket}} object whose [=WebSocket/ready state=] was set to {{WebSocket/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!!event}} events, +{{message!!event}} events, {{error!!event}} events, or {{close!!event}} events. -A {{WebSocket}} object whose {{WebSocket/readyState}} attribute's value was set to -{{WebSocket/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!!event}} -events, {{error!!event}}, or {{close!!event}} events. +A {{WebSocket}} object whose [=WebSocket/ready state=] was set to {{WebSocket/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!!event}} events, {{error!!event}}, or +{{close!!event}} events. -A {{WebSocket}} object whose {{WebSocket/readyState}} attribute's value was set to -{{WebSocket/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!!event}} -or {{close!!event}} events. +A {{WebSocket}} object whose [=WebSocket/ready state=] was set to {{WebSocket/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!!event}} or {{close!!event}} +events. A {{WebSocket}} object with an established connection that has data queued to be transmitted to the network must not be garbage collected.