CINXE.COM

WebSockets Standard

<!doctype html><html lang="en"> <head> <meta charset="utf-8"> <meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport"> <meta content="#3c790a" name="theme-color"> <meta content="light dark" name="color-scheme"> <title>WebSockets Standard</title> <link crossorigin href="https://resources.whatwg.org/standard-shared-with-dev.css" rel="stylesheet"> <link crossorigin href="https://resources.whatwg.org/standard.css" rel="stylesheet"> <link crossorigin href="https://resources.whatwg.org/spec.css" rel="stylesheet"> <link crossorigin href="https://resources.whatwg.org/logo-websockets.svg" rel="icon"> <script crossorigin defer src="https://resources.whatwg.org/commit-snapshot-shortcut-key.js"></script> <meta content="Bikeshed version 4416b18d5, updated Tue Jan 2 15:52:39 2024 -0800" name="generator"> <meta content="7b748d313427d66108aa5c6906ef1c9a9219703d" name="revision"> <style>/* Boilerplate: style-dfn-panel */ :root { --dfnpanel-bg: #ddd; --dfnpanel-text: var(--text); --dfnpanel-target-bg: #ffc; --dfnpanel-target-outline: orange; } @media (prefers-color-scheme: dark) { :root { --dfnpanel-bg: #222; --dfnpanel-text: var(--text); --dfnpanel-target-bg: #333; --dfnpanel-target-outline: silver; } } .dfn-panel { position: absolute; z-index: 35; width: 20em; width: 300px; height: auto; max-height: 500px; overflow: auto; padding: 0.5em 0.75em; font: small Helvetica Neue, sans-serif, Droid Sans Fallback; background: var(--dfnpanel-bg); color: var(--dfnpanel-text); border: outset 0.2em; white-space: normal; /* in case it's moved into a pre */ } .dfn-panel:not(.on) { display: none; } .dfn-panel * { margin: 0; padding: 0; text-indent: 0; } .dfn-panel > b { display: block; } .dfn-panel a { color: var(--dfnpanel-text); } .dfn-panel a:not(:hover) { text-decoration: none !important; border-bottom: none !important; } .dfn-panel a:focus { outline: 5px auto Highlight; outline: 5px auto -webkit-focus-ring-color; } .dfn-panel > b + b { margin-top: 0.25em; } .dfn-panel ul { padding: 0 0 0 1em; list-style: none; } .dfn-panel li a { max-width: calc(300px - 1.5em - 1em); overflow: hidden; text-overflow: ellipsis; } .dfn-panel.activated { display: inline-block; position: fixed; left: 8px; bottom: 2em; margin: 0 auto; max-width: calc(100vw - 1.5em - .4em - .5em); max-height: 30vh; transition: left 1s ease-out, bottom 1s ease-out; } .dfn-panel .link-item:hover { text-decoration: underline; } .dfn-panel .link-item .copy-icon { opacity: 0; } .dfn-panel .link-item:hover .copy-icon, .dfn-panel .link-item .copy-icon:focus { opacity: 1; } .dfn-panel .copy-icon { display: inline-block; margin-right: 0.5em; width: 0.85em; height: 1em; border-radius: 3px; background-color: #ccc; cursor: pointer; } .dfn-panel .copy-icon .icon { width: 100%; height: 100%; background-color: #fff; display: flex; justify-content: center; align-items: center; position: relative; } .dfn-panel .copy-icon .icon::before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 1px solid black; background-color: #ccc; opacity: 0.25; transform: translate(3px, -3px); } .dfn-panel .copy-icon:active .icon::before { opacity: 1; } .dfn-paneled[role="button"] { cursor: help; } .highlighted { animation: target-fade 3s; } @keyframes target-fade { from { background-color: var(--dfnpanel-target-bg); outline: 5px solid var(--dfnpanel-target-outline); } to { color: var(--a-normal-text); background-color: transparent; outline: transparent; } } </style> <style>/* Boilerplate: style-mdn-anno */ :root { --mdn-bg: #EEE; --mdn-shadow: #999; --mdn-nosupport-text: #ccc; --mdn-pass: green; --mdn-fail: red; } @media (prefers-color-scheme: dark) { :root { --mdn-bg: #222; --mdn-shadow: #444; --mdn-nosupport-text: #666; --mdn-pass: #690; --mdn-fail: #d22; } } .mdn-anno { background: var(--mdn-bg, #EEE); border-radius: .25em; box-shadow: 0 0 3px var(--mdn-shadow, #999); color: var(--text, black); font: 1em sans-serif; hyphens: none; max-width: min-content; overflow: hidden; padding: 0.2em; position: absolute; right: 0.3em; top: auto; white-space: nowrap; word-wrap: normal; z-index: 8; } .mdn-anno.unpositioned { display: none; } .mdn-anno.overlapping-main { opacity: .2; transition: opacity .1s; } .mdn-anno[open] { opacity: 1; z-index: 9; min-width: 9em; } .mdn-anno:hover { opacity: 1; outline: var(--text, black) 1px solid; } .mdn-anno > summary { font-weight: normal; text-align: right; cursor: pointer; display: block; } .mdn-anno > summary > .less-than-two-engines-flag { color: var(--mdn-fail); padding-right: 2px; } .mdn-anno > summary > .all-engines-flag { color: var(--mdn-pass); padding-right: 2px; } .mdn-anno > summary > span { color: #fff; background-color: #000; font-weight: normal; font-family: zillaslab, Palatino, "Palatino Linotype", serif; padding: 2px 3px 0px 3px; line-height: 1.3em; vertical-align: top; } .mdn-anno > .feature { margin-top: 20px; } .mdn-anno > .feature:not(:first-of-type) { border-top: 1px solid #999; margin-top: 6px; padding-top: 2px; } .mdn-anno > .feature > .less-than-two-engines-text { color: var(--mdn-fail); } .mdn-anno > .feature > .all-engines-text { color: var(--mdn-pass); } .mdn-anno > .feature > p { font-size: .75em; margin-top: 6px; margin-bottom: 0; } .mdn-anno > .feature > p + p { margin-top: 3px; } .mdn-anno > .feature > .support { display: block; font-size: 0.6em; margin: 0; padding: 0; margin-top: 2px; } .mdn-anno > .feature > .support + div { padding-top: 0.5em; } .mdn-anno > .feature > .support > hr { display: block; border: none; border-top: 1px dotted #999; padding: 3px 0px 0px 0px; margin: 2px 3px 0px 3px; } .mdn-anno > .feature > .support > hr::before { content: ""; } .mdn-anno > .feature > .support > span { padding: 0.2em 0; display: block; display: table; } .mdn-anno > .feature > .support > span.no { color: var(--mdn-nosupport-text); filter: grayscale(100%); } .mdn-anno > .feature > .support > span.no::before { opacity: 0.5; } .mdn-anno > .feature > .support > span:first-of-type { padding-top: 0.5em; } .mdn-anno > .feature > .support > span > span { padding: 0 0.5em; display: table-cell; } .mdn-anno > .feature > .support > span > span:first-child { width: 100%; } .mdn-anno > .feature > .support > span > span:last-child { width: 100%; white-space: pre; padding: 0; } .mdn-anno > .feature > .support > span::before { content: ' '; display: table-cell; min-width: 1.5em; height: 1.5em; background: no-repeat center center; background-size: contain; text-align: right; font-size: 0.75em; font-weight: bold; } .mdn-anno > .feature > .support > .chrome_android::before { background-image: url(https://resources.whatwg.org/browser-logos/chrome.svg); } .mdn-anno > .feature > .support > .firefox_android::before { background-image: url(https://resources.whatwg.org/browser-logos/firefox.png); } .mdn-anno > .feature > .support > .chrome::before { background-image: url(https://resources.whatwg.org/browser-logos/chrome.svg); } .mdn-anno > .feature > .support > .edge_blink::before { background-image: url(https://resources.whatwg.org/browser-logos/edge.svg); } .mdn-anno > .feature > .support > .edge::before { background-image: url(https://resources.whatwg.org/browser-logos/edge_legacy.svg); } .mdn-anno > .feature > .support > .firefox::before { background-image: url(https://resources.whatwg.org/browser-logos/firefox.png); } .mdn-anno > .feature > .support > .ie::before { background-image: url(https://resources.whatwg.org/browser-logos/ie.png); } .mdn-anno > .feature > .support > .safari_ios::before { background-image: url(https://resources.whatwg.org/browser-logos/safari-ios.svg); } .mdn-anno > .feature > .support > .nodejs::before { background-image: url(https://nodejs.org/static/images/favicons/favicon.ico); } .mdn-anno > .feature > .support > .opera_android::before { background-image: url(https://resources.whatwg.org/browser-logos/opera.svg); } .mdn-anno > .feature > .support > .opera::before { background-image: url(https://resources.whatwg.org/browser-logos/opera.svg); } .mdn-anno > .feature > .support > .safari::before { background-image: url(https://resources.whatwg.org/browser-logos/safari.png); } .mdn-anno > .feature > .support > .samsunginternet_android::before { background-image: url(https://resources.whatwg.org/browser-logos/samsung.svg); } .mdn-anno > .feature > .support > .webview_android::before { background-image: url(https://resources.whatwg.org/browser-logos/android-webview.png); } .name-slug-mismatch { color: red; } .caniuse-status:hover { z-index: 9; } /* dt, li, .issue, .note, and .example are "position: relative", so to put annotation at right margin, must move to right of containing block */; .h-entry:not(.status-LS) dt > .mdn-anno, .h-entry:not(.status-LS) li > .mdn-anno, .h-entry:not(.status-LS) .issue > .mdn-anno, .h-entry:not(.status-LS) .note > .mdn-anno, .h-entry:not(.status-LS) .example > .mdn-anno { right: -6.7em; } .h-entry p + .mdn-anno { margin-top: 0; } h2 + .mdn-anno.after { margin: -48px 0 0 0; } h3 + .mdn-anno.after { margin: -46px 0 0 0; } h4 + .mdn-anno.after { margin: -42px 0 0 0; } h5 + .mdn-anno.after { margin: -40px 0 0 0; } h6 + .mdn-anno.after { margin: -40px 0 0 0; } </style> <style>/* Boilerplate: style-ref-hints */ :root { --ref-hint-bg: #ddd; --ref-hint-text: var(--text); } @media (prefers-color-scheme: dark) { :root { --ref-hint-bg: #222; --ref-hint-text: var(--text); } } .ref-hint { display: inline-block; position: absolute; z-index: 35; width: 20em; width: 300px; height: auto; max-height: 500px; overflow: auto; padding: 0.5em 0.5em; font: small Helvetica Neue, sans-serif, Droid Sans Fallback; background: var(--ref-hint-bg); color: var(--ref-hint-text); border: outset 0.2em; white-space: normal; /* in case it's moved into a pre */ } .ref-hint * { margin: 0; padding: 0; text-indent: 0; } .ref-hint ul { padding: 0 0 0 1em; list-style: none; } </style> <style>/* Boilerplate: style-var-click-highlighting */ /* Colors were chosen in Lab using https://nixsensor.com/free-color-converter/ D50 2deg illuminant, L in [0,100], a and b in [-128, 128] 0 = lab(85,0,85) 1 = lab(85,80,30) 2 = lab(85,-40,40) 3 = lab(85,-50,0) 4 = lab(85,5,15) 5 = lab(85,-10,-50) 6 = lab(85,35,-15) */ [data-algorithm] var { cursor: pointer; } var[data-var-color="0"] { background-color: #F4D200; box-shadow: 0 0 0 2px #F4D200; } var[data-var-color="1"] { background-color: #FF87A2; box-shadow: 0 0 0 2px #FF87A2; } var[data-var-color="2"] { background-color: #96E885; box-shadow: 0 0 0 2px #96E885; } var[data-var-color="3"] { background-color: #3EEED2; box-shadow: 0 0 0 2px #3EEED2; } var[data-var-color="4"] { background-color: #EACFB6; box-shadow: 0 0 0 2px #EACFB6; } var[data-var-color="5"] { background-color: #82DDFF; box-shadow: 0 0 0 2px #82DDFF; } var[data-var-color="6"] { background-color: #FFBCF2; box-shadow: 0 0 0 2px #FFBCF2; } </style> <body class="h-entry status-LS"> <div class="head"> <a class="logo" href="https://whatwg.org/"> <img alt="WHATWG" crossorigin height="100" src="https://resources.whatwg.org/logo-websockets.svg"> </a> <hgroup> <h1 class="p-name no-ref" id="title">WebSockets</h1> <p id="subtitle">Living Standard — Last Updated <time class="dt-updated" datetime="2024-01-24">24 January 2024</time> </p> </hgroup> <div data-fill-with="spec-metadata"> <dl> <dt>Participate: <dd><a href="https://github.com/whatwg/websockets">GitHub whatwg/websockets</a> (<a href="https://github.com/whatwg/websockets/issues/new/choose">new issue</a>, <a href="https://github.com/whatwg/websockets/issues">open issues</a>) <dd><a href="https://whatwg.org/chat">Chat on Matrix</a> <dt>Commits: <dd><a href="https://github.com/whatwg/websockets/commits">GitHub whatwg/websockets/commits</a> <dd><a href="/commit-snapshots/7b748d313427d66108aa5c6906ef1c9a9219703d/" id="commit-snapshot-link">Snapshot as of this commit</a> <dd><a href="https://twitter.com/whatsockets">@whatsockets</a> <dt>Tests: <dd><a href="https://github.com/web-platform-tests/wpt/tree/master/websockets">web-platform-tests websockets/</a> (<a href="https://github.com/web-platform-tests/wpt/labels/websockets">ongoing work</a>) <dt>Translations <small>(non-normative)</small>: <dd><span title="Japanese"><a href="https://triple-underscore.github.io/WebSocket-ja.html" hreflang="ja" lang="ja" rel="alternate">日本語</a></span> </dl> </div> <div data-fill-with="warning"></div> </div> <div class="p-summary" data-fill-with="abstract"> <h2 class="no-num no-toc no-ref heading settled" id="abstract"><span class="content">Abstract</span></h2> <p>This specification provides APIs to enable web applications to maintain bidirectional communications with server-side processes.</p> </div> <nav data-fill-with="table-of-contents" id="toc"> <h2 class="no-num no-toc no-ref" id="contents">Table of Contents</h2> <ol class="toc" role="directory"> <li><a href="#network-intro"><span class="secno">1</span> <span class="content">Introduction</span></a> <li> <a href="#websocket-protocol"><span class="secno">2</span> <span class="content">WebSocket protocol alterations</span></a> <ol class="toc"> <li><a href="#websocket-connections"><span class="secno">2.1</span> <span class="content">Connections</span></a> <li><a href="#websocket-opening-handshake"><span class="secno">2.2</span> <span class="content">Opening handshake</span></a> </ol> <li> <a href="#the-websocket-interface"><span class="secno">3</span> <span class="content">The <code class="idl"><span>WebSocket</span></code> interface</span></a> <ol class="toc"> <li><a href="#interface-definition"><span class="secno">3.1</span> <span class="content">Interface definition</span></a> </ol> <li><a href="#feedback-from-the-protocol"><span class="secno">4</span> <span class="content">Feedback from the protocol</span></a> <li><a href="#ping-and-pong-frames"><span class="secno">5</span> <span class="content">Ping and Pong frames</span></a> <li><a href="#the-closeevent-interface"><span class="secno">6</span> <span class="content">The <code class="idl"><span>CloseEvent</span></code> interface</span></a> <li><a href="#garbage-collection"><span class="secno">7</span> <span class="content">Garbage collection</span></a> <li><a href="#acks"><span class="secno"></span> <span class="content">Acknowledgments</span></a> <li><a href="#ipr"><span class="secno"></span> <span class="content">Intellectual property rights</span></a> <li> <a href="#index"><span class="secno"></span> <span class="content">Index</span></a> <ol class="toc"> <li><a href="#index-defined-here"><span class="secno"></span> <span class="content">Terms defined by this specification</span></a> <li><a href="#index-defined-elsewhere"><span class="secno"></span> <span class="content">Terms defined by reference</span></a> </ol> <li> <a href="#references"><span class="secno"></span> <span class="content">References</span></a> <ol class="toc"> <li><a href="#normative"><span class="secno"></span> <span class="content">Normative References</span></a> </ol> <li><a href="#idl-index"><span class="secno"></span> <span class="content">IDL Index</span></a> </ol> </nav> <main> <h2 class="heading settled" data-level="1" id="network-intro"><span class="secno">1. </span><span class="content">Introduction</span><a class="self-link" href="#network-intro"></a></h2> <div class="non-normative"> <p><em>This section is non-normative.</em></p> <p>To enable web applications to maintain bidirectional communications with server-side processes, this specification introduces the <code class="idl"><a data-link-type="idl" href="#websocket" id="ref-for-websocket">WebSocket</a></code> interface.</p> <p class="note" role="note">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.</p> </div> <h2 class="heading settled" data-level="2" id="websocket-protocol"><span class="secno">2. </span><span class="content">WebSocket protocol alterations</span><a class="self-link" href="#websocket-protocol"></a></h2> <div class="note" role="note"> This section replaces part of the WebSocket protocol opening handshake client requirement to integrate it with algorithms defined in <cite>Fetch</cite>. This way CSP, cookies, HSTS, and other <cite>Fetch</cite>-related protocols are handled in a single location. Ideally the RFC would be updated with this language, but it is never that easy. The <code class="idl"><a data-link-type="idl" href="#websocket" id="ref-for-websocket①">WebSocket</a></code> API, defined below, uses this language. <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a> <a data-link-type="biblio" href="#biblio-fetch" title="Fetch Standard">[FETCH]</a> <p>The way this works is by replacing The WebSocket Protocol’s "establish a WebSocket connection" algorithm with a new one that integrates with <cite>Fetch</cite>. "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 <cite>Fetch</cite>, 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.</p> </div> <h3 class="heading settled" data-level="2.1" id="websocket-connections"><span class="secno">2.1. </span><span class="content">Connections</span><a class="self-link" href="#websocket-connections"></a></h3> <div class="algorithm" data-algorithm="obtain a WebSocket connection"> <p>To <dfn class="dfn-paneled" data-dfn-type="dfn" data-export id="concept-websocket-connection-obtain">obtain a WebSocket connection</dfn>, given a <var>url</var>, run these steps:</p> <ol> <li data-md> <p>Let <var>host</var> be <var>url</var>’s <a data-link-type="dfn" href="https://url.spec.whatwg.org/#concept-url-host" id="ref-for-concept-url-host">host</a>.</p> <li data-md> <p>Let <var>port</var> be <var>url</var>’s <a data-link-type="dfn" href="https://url.spec.whatwg.org/#concept-url-port" id="ref-for-concept-url-port">port</a>.</p> <li data-md> <p>Let <var>resource name</var> be U+002F (/), followed by the strings in <var>url</var>’s <a data-link-type="dfn" href="https://url.spec.whatwg.org/#concept-url-path" id="ref-for-concept-url-path">path</a> (including empty strings), if any, separated from each other by U+002F (/).</p> <li data-md> <p>If <var>url</var>’s <a data-link-type="dfn" href="https://url.spec.whatwg.org/#concept-url-query" id="ref-for-concept-url-query">query</a> is non-empty, append U+003F (?), followed by <var>url</var>’s <a data-link-type="dfn" href="https://url.spec.whatwg.org/#concept-url-query" id="ref-for-concept-url-query①">query</a>, to <var>resource name</var>.</p> <li data-md> <p>Let <var>secure</var> be false, if <var>url</var>’s <a data-link-type="dfn" href="https://url.spec.whatwg.org/#concept-url-scheme" id="ref-for-concept-url-scheme">scheme</a> is "<code>http</code>"; otherwise true.</p> <li data-md> <p>Follow the requirements stated in step 2 to 5, inclusive, of the first set of steps in <a href="https://datatracker.ietf.org/doc/html/rfc6455#section-4.1">section 4.1</a> of The WebSocket Protocol to establish a <a data-link-type="dfn" href="#concept-websocket-connection-obtain" id="ref-for-concept-websocket-connection-obtain">WebSocket connection</a>, passing <var>host</var>, <var>port</var>, <var>resource name</var> and <var>secure</var>. <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a></p> <li data-md> <p>If that established a connection, return it, and return failure otherwise.</p> </ol> <p class="note" role="note">Although structured a little differently, carrying different properties, and therefore not shareable, a WebSocket connection is very close to identical to an "ordinary" <a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#concept-connection" id="ref-for-concept-connection">connection</a>. </p> </div> <h3 class="heading settled" data-level="2.2" id="websocket-opening-handshake"><span class="secno">2.2. </span><span class="content">Opening handshake</span><a class="self-link" href="#websocket-opening-handshake"></a></h3> <div class="algorithm" data-algorithm="establish a WebSocket connection"> <p>To <dfn class="dfn-paneled" data-dfn-type="dfn" data-noexport id="concept-websocket-establish">establish a WebSocket connection</dfn>, given a <var>url</var>, <var>protocols</var>, and <var>client</var>, run these steps:</p> <ol> <li data-md> <p>Let <var>requestURL</var> be a copy of <var>url</var>, with its <a data-link-type="dfn" href="https://url.spec.whatwg.org/#concept-url-scheme" id="ref-for-concept-url-scheme①">scheme</a> set to "<code>http</code>", if <var>url</var>’s <a data-link-type="dfn" href="https://url.spec.whatwg.org/#concept-url-scheme" id="ref-for-concept-url-scheme②">scheme</a> is "<code>ws</code>"; otherwise to "<code>https</code>".</p> <p class="note no-backref" role="note">This change of scheme is essential to integrate well with <a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#concept-fetch" id="ref-for-concept-fetch">fetching</a>. E.g., HSTS would not work without it. There is no real reason for WebSocket to have distinct schemes, it’s a legacy artefact. <a data-link-type="biblio" href="#biblio-hsts" title="HTTP Strict Transport Security (HSTS)">[HSTS]</a> </p> <li data-md> <p>Let <var>request</var> be a new <a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#concept-request" id="ref-for-concept-request">request</a>, whose <a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#concept-request-url" id="ref-for-concept-request-url">URL</a> is <var>requestURL</var>, <a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#concept-request-client" id="ref-for-concept-request-client">client</a> is <var>client</var>, <a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#request-service-workers-mode" id="ref-for-request-service-workers-mode">service-workers mode</a> is "<code>none</code>", <a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#concept-request-referrer" id="ref-for-concept-request-referrer">referrer</a> is "<code>no-referrer</code>", <a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#concept-request-mode" id="ref-for-concept-request-mode">mode</a> is "<code>websocket</code>", <a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#concept-request-credentials-mode" id="ref-for-concept-request-credentials-mode">credentials mode</a> is "<code>include</code>", <a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#concept-request-cache-mode" id="ref-for-concept-request-cache-mode">cache mode</a> is "<code>no-store</code>" , and <a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#concept-request-redirect-mode" id="ref-for-concept-request-redirect-mode">redirect mode</a> is "<code>error</code>".</p> <li data-md> <p><a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#concept-header-list-append" id="ref-for-concept-header-list-append">Append</a> (`<code>Upgrade</code>`, `<code>websocket</code>`) to <var>request</var>’s <a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#concept-request-header-list" id="ref-for-concept-request-header-list">header list</a>.</p> <li data-md> <p><a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#concept-header-list-append" id="ref-for-concept-header-list-append①">Append</a> (`<code>Connection</code>`, `<code>Upgrade</code>`) to <var>request</var>’s <a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#concept-request-header-list" id="ref-for-concept-request-header-list①">header list</a>.</p> <li data-md> <p>Let <var>keyValue</var> be a nonce consisting of a randomly selected 16-byte value that has been <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#forgiving-base64-encode" id="ref-for-forgiving-base64-encode">forgiving-base64-encoded</a> and <a data-link-type="dfn" href="https://infra.spec.whatwg.org/#isomorphic-encode" id="ref-for-isomorphic-encode">isomorphic encoded</a>.</p> <p class="example" id="example-random-value"><a class="self-link" href="#example-random-value"></a>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, <var>keyValue</var> would be forgiving-base64-encoded to "<code>AQIDBAUGBwgJCgsMDQ4PEC==</code>" and isomorphic encoded to `<code>AQIDBAUGBwgJCgsMDQ4PEC==</code>`. </p> <li data-md> <p><a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#concept-header-list-append" id="ref-for-concept-header-list-append②">Append</a> (`<code>Sec-WebSocket-Key</code>`, <var>keyValue</var>) to <var>request</var>’s <a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#concept-request-header-list" id="ref-for-concept-request-header-list②">header list</a>.</p> <li data-md> <p><a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#concept-header-list-append" id="ref-for-concept-header-list-append③">Append</a> (`<code>Sec-WebSocket-Version</code>`, `<code>13</code>`) to <var>request</var>’s <a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#concept-request-header-list" id="ref-for-concept-request-header-list③">header list</a>.</p> <li data-md> <p>For each <var>protocol</var> in <var>protocols</var>, <a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#concept-header-list-combine" id="ref-for-concept-header-list-combine">combine</a> (`<code>Sec-WebSocket-Protocol</code>`, <var>protocol</var>) in <var>request</var>’s <a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#concept-request-header-list" id="ref-for-concept-request-header-list④">header list</a>.</p> <li data-md> <p>Let <var>permessageDeflate</var> be a user-agent defined "<code>permessage-deflate</code>" extension <a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#header-value" id="ref-for-header-value">header value</a>. <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a></p> <p class="example" id="example-permessage-deflate"><a class="self-link" href="#example-permessage-deflate"></a>`<code>permessage-deflate; client_max_window_bits</code>` </p> <li data-md> <p><a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#concept-header-list-append" id="ref-for-concept-header-list-append④">Append</a> (`<code>Sec-WebSocket-Extensions</code>`, <var>permessageDeflate</var>) to <var>request</var>’s <a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#concept-request-header-list" id="ref-for-concept-request-header-list⑤">header list</a>.</p> <li data-md> <p><a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#concept-fetch" id="ref-for-concept-fetch①">Fetch</a> <var>request</var> with <a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#fetch-useparallelqueue" id="ref-for-fetch-useparallelqueue"><i>useParallelQueue</i></a> set to true, and <a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#process-response" id="ref-for-process-response"><i>processResponse</i></a> given <var>response</var> being these steps:</p> <ol> <li data-md> <p>If <var>response</var> is a <a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#concept-network-error" id="ref-for-concept-network-error">network error</a> or its <a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#concept-response-status" id="ref-for-concept-response-status">status</a> is not 101, <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.7" id="ref-for-section-7.1.7">fail the WebSocket connection</a>.</p> <li data-md> <p>If <var>protocols</var> is not the empty list and <a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#extract-header-list-values" id="ref-for-extract-header-list-values">extracting header list values</a> given `<code>Sec-WebSocket-Protocol</code>` and <var>response</var>’s <a data-link-type="dfn" href="https://fetch.spec.whatwg.org/#concept-request-header-list" id="ref-for-concept-request-header-list⑥">header list</a> results in null, failure, or the empty byte sequence, then <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.7" id="ref-for-section-7.1.7①">fail the WebSocket connection</a>.</p> <p class="note" role="note">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. </p> <li data-md> <p>Follow the requirements stated step 2 to step 6, inclusive, of the last set of steps in <a href="https://datatracker.ietf.org/doc/html/rfc6455#section-4.1">section 4.1</a> of The WebSocket Protocol to validate <var>response</var>. This either results in <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.7" id="ref-for-section-7.1.7②">fail the WebSocket connection</a> or <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and" id="ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and">the WebSocket connection is established</a>.</p> </ol> </ol> </div> <p><a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.7" id="ref-for-section-7.1.7③">Fail the WebSocket connection</a> and <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and" id="ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and①">the WebSocket connection is established</a> are defined by The WebSocket Protocol. <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a></p> <p class="warning">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. </p> <h2 class="heading settled" data-level="3" id="the-websocket-interface"><span class="secno">3. </span><span class="content">The <code class="idl"><a data-link-type="idl" href="#websocket" id="ref-for-websocket②">WebSocket</a></code> interface</span><a class="self-link" href="#the-websocket-interface"></a></h2> <h3 class="heading settled" data-level="3.1" id="interface-definition"><span class="secno">3.1. </span><span class="content">Interface definition</span><a class="self-link" href="#interface-definition"></a></h3> <p>The Web IDL definition for the <code class="idl"><a data-link-type="idl" href="#websocket" id="ref-for-websocket③">WebSocket</a></code> class is given as follows:</p> <pre class="idl highlight def"><c- b>enum</c-> <dfn class="dfn-paneled idl-code" data-dfn-type="enum" data-export id="enumdef-binarytype"><code><c- g>BinaryType</c-></code></dfn> { <a class="idl-code" data-link-type="enum-value" href="#dom-binarytype-blob" id="ref-for-dom-binarytype-blob"><c- s>"blob"</c-></a>, <a class="idl-code" data-link-type="enum-value" href="#dom-binarytype-arraybuffer" id="ref-for-dom-binarytype-arraybuffer"><c- s>"arraybuffer"</c-></a> }; [<a class="idl-code" data-link-type="extended-attribute" href="https://webidl.spec.whatwg.org/#Exposed" id="ref-for-Exposed"><c- g>Exposed</c-></a>=(<c- n>Window</c->,<c- n>Worker</c->)] <c- b>interface</c-> <dfn class="dfn-paneled idl-code" data-dfn-type="interface" data-export id="websocket"><code><c- g>WebSocket</c-></code></dfn> : <a data-link-type="idl-name" href="https://dom.spec.whatwg.org/#eventtarget" id="ref-for-eventtarget"><c- n>EventTarget</c-></a> { <a class="idl-code" data-link-type="constructor" href="#dom-websocket-websocket" id="ref-for-dom-websocket-websocket"><c- g>constructor</c-></a>(<a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-USVString" id="ref-for-idl-USVString"><c- b>USVString</c-></a> <dfn class="dfn-paneled idl-code" data-dfn-for="WebSocket/WebSocket(url, protocols), WebSocket/constructor(url, protocols), WebSocket/WebSocket(url), WebSocket/constructor(url)" data-dfn-type="argument" data-export id="dom-websocket-websocket-url-protocols-url"><code><c- g>url</c-></code></dfn>, <c- b>optional</c-> (<a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString" id="ref-for-idl-DOMString"><c- b>DOMString</c-></a> <c- b>or</c-> <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#idl-sequence" id="ref-for-idl-sequence"><c- b>sequence</c-></a>&lt;<a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString" id="ref-for-idl-DOMString①"><c- b>DOMString</c-></a>>) <dfn class="dfn-paneled idl-code" data-dfn-for="WebSocket/WebSocket(url, protocols), WebSocket/constructor(url, protocols), WebSocket/WebSocket(url), WebSocket/constructor(url)" data-dfn-type="argument" data-export id="dom-websocket-websocket-url-protocols-protocols"><code><c- g>protocols</c-></code></dfn> = []); <c- b>readonly</c-> <c- b>attribute</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-USVString" id="ref-for-idl-USVString①"><c- b>USVString</c-></a> <a class="idl-code" data-link-type="attribute" data-readonly data-type="USVString" href="#dom-websocket-url" id="ref-for-dom-websocket-url"><c- g>url</c-></a>; // ready state <c- b>const</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-unsigned-short" id="ref-for-idl-unsigned-short"><c- b>unsigned</c-> <c- b>short</c-></a> <a class="idl-code" data-link-type="const" href="#dom-websocket-connecting" id="ref-for-dom-websocket-connecting"><c- g>CONNECTING</c-></a> = 0; <c- b>const</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-unsigned-short" id="ref-for-idl-unsigned-short①"><c- b>unsigned</c-> <c- b>short</c-></a> <a class="idl-code" data-link-type="const" href="#dom-websocket-open" id="ref-for-dom-websocket-open"><c- g>OPEN</c-></a> = 1; <c- b>const</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-unsigned-short" id="ref-for-idl-unsigned-short②"><c- b>unsigned</c-> <c- b>short</c-></a> <a class="idl-code" data-link-type="const" href="#dom-websocket-closing" id="ref-for-dom-websocket-closing"><c- g>CLOSING</c-></a> = 2; <c- b>const</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-unsigned-short" id="ref-for-idl-unsigned-short③"><c- b>unsigned</c-> <c- b>short</c-></a> <a class="idl-code" data-link-type="const" href="#dom-websocket-closed" id="ref-for-dom-websocket-closed"><c- g>CLOSED</c-></a> = 3; <c- b>readonly</c-> <c- b>attribute</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-unsigned-short" id="ref-for-idl-unsigned-short④"><c- b>unsigned</c-> <c- b>short</c-></a> <a class="idl-code" data-link-type="attribute" data-readonly data-type="unsigned short" href="#dom-websocket-readystate" id="ref-for-dom-websocket-readystate"><c- g>readyState</c-></a>; <c- b>readonly</c-> <c- b>attribute</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-unsigned-long-long" id="ref-for-idl-unsigned-long-long"><c- b>unsigned</c-> <c- b>long</c-> <c- b>long</c-></a> <a class="idl-code" data-link-type="attribute" data-readonly data-type="unsigned long long" href="#dom-websocket-bufferedamount" id="ref-for-dom-websocket-bufferedamount"><c- g>bufferedAmount</c-></a>; // networking <c- b>attribute</c-> <a data-link-type="idl-name" href="https://html.spec.whatwg.org/multipage/webappapis.html#eventhandler" id="ref-for-eventhandler"><c- n>EventHandler</c-></a> <a class="idl-code" data-link-type="attribute" data-type="EventHandler" href="#dom-websocket-onopen" id="ref-for-dom-websocket-onopen"><c- g>onopen</c-></a>; <c- b>attribute</c-> <a data-link-type="idl-name" href="https://html.spec.whatwg.org/multipage/webappapis.html#eventhandler" id="ref-for-eventhandler①"><c- n>EventHandler</c-></a> <a class="idl-code" data-link-type="attribute" data-type="EventHandler" href="#dom-websocket-onerror" id="ref-for-dom-websocket-onerror"><c- g>onerror</c-></a>; <c- b>attribute</c-> <a data-link-type="idl-name" href="https://html.spec.whatwg.org/multipage/webappapis.html#eventhandler" id="ref-for-eventhandler②"><c- n>EventHandler</c-></a> <a class="idl-code" data-link-type="attribute" data-type="EventHandler" href="#dom-websocket-onclose" id="ref-for-dom-websocket-onclose"><c- g>onclose</c-></a>; <c- b>readonly</c-> <c- b>attribute</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString" id="ref-for-idl-DOMString②"><c- b>DOMString</c-></a> <a class="idl-code" data-link-type="attribute" data-readonly data-type="DOMString" href="#dom-websocket-extensions" id="ref-for-dom-websocket-extensions"><c- g>extensions</c-></a>; <c- b>readonly</c-> <c- b>attribute</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString" id="ref-for-idl-DOMString③"><c- b>DOMString</c-></a> <a class="idl-code" data-link-type="attribute" data-readonly data-type="DOMString" href="#dom-websocket-protocol" id="ref-for-dom-websocket-protocol"><c- g>protocol</c-></a>; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-undefined" id="ref-for-idl-undefined"><c- b>undefined</c-></a> <a class="idl-code" data-link-type="method" href="#dom-websocket-close" id="ref-for-dom-websocket-close"><c- g>close</c-></a>(<c- b>optional</c-> [<a class="idl-code" data-link-type="extended-attribute" href="https://webidl.spec.whatwg.org/#Clamp" id="ref-for-Clamp"><c- g>Clamp</c-></a>] <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-unsigned-short" id="ref-for-idl-unsigned-short⑤"><c- b>unsigned</c-> <c- b>short</c-></a> <dfn class="dfn-paneled idl-code" data-dfn-for="WebSocket/close(code, reason), WebSocket/close(code), WebSocket/close()" data-dfn-type="argument" data-export id="dom-websocket-close-code-reason-code"><code><c- g>code</c-></code></dfn>, <c- b>optional</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-USVString" id="ref-for-idl-USVString②"><c- b>USVString</c-></a> <dfn class="dfn-paneled idl-code" data-dfn-for="WebSocket/close(code, reason), WebSocket/close(code), WebSocket/close()" data-dfn-type="argument" data-export id="dom-websocket-close-code-reason-reason"><code><c- g>reason</c-></code></dfn>); // messaging <c- b>attribute</c-> <a data-link-type="idl-name" href="https://html.spec.whatwg.org/multipage/webappapis.html#eventhandler" id="ref-for-eventhandler③"><c- n>EventHandler</c-></a> <a class="idl-code" data-link-type="attribute" data-type="EventHandler" href="#dom-websocket-onmessage" id="ref-for-dom-websocket-onmessage"><c- g>onmessage</c-></a>; <c- b>attribute</c-> <a data-link-type="idl-name" href="#enumdef-binarytype" id="ref-for-enumdef-binarytype"><c- n>BinaryType</c-></a> <a class="idl-code" data-link-type="attribute" data-type="BinaryType" href="#dom-websocket-binarytype" id="ref-for-dom-websocket-binarytype"><c- g>binaryType</c-></a>; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-undefined" id="ref-for-idl-undefined①"><c- b>undefined</c-></a> <a class="idl-code" data-link-type="method" href="#dom-websocket-send" id="ref-for-dom-websocket-send"><c- g>send</c-></a>((<a data-link-type="idl-name" href="https://webidl.spec.whatwg.org/#BufferSource" id="ref-for-BufferSource"><c- n>BufferSource</c-></a> <c- b>or</c-> <a data-link-type="idl-name" href="https://w3c.github.io/FileAPI/#dfn-Blob" id="ref-for-dfn-Blob"><c- n>Blob</c-></a> <c- b>or</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-USVString" id="ref-for-idl-USVString③"><c- b>USVString</c-></a>) <dfn class="dfn-paneled idl-code" data-dfn-for="WebSocket/send(data)" data-dfn-type="argument" data-export id="dom-websocket-send-data-data"><code><c- g>data</c-></code></dfn>); }; </pre> <p>Each <code class="idl"><a data-link-type="idl" href="#websocket" id="ref-for-websocket④">WebSocket</a></code> object has an associated <dfn class="dfn-paneled" data-dfn-for="WebSocket" data-dfn-type="dfn" data-lt="internal-url" data-noexport id="websocket-internal-url">url</dfn>, which is a <a data-link-type="dfn" href="https://url.spec.whatwg.org/#concept-url" id="ref-for-concept-url">URL record</a>.</p> <p>Each <code class="idl"><a data-link-type="idl" href="#websocket" id="ref-for-websocket⑤">WebSocket</a></code> object has an associated <dfn class="dfn-paneled" data-dfn-for="WebSocket" data-dfn-type="dfn" data-noexport id="websocket-binary-type">binary type</dfn>, which is a <code class="idl"><a data-link-type="idl" href="#enumdef-binarytype" id="ref-for-enumdef-binarytype①">BinaryType</a></code>. Initially it must be "<code class="idl"><a data-link-type="idl" href="#dom-binarytype-blob" id="ref-for-dom-binarytype-blob①">blob</a></code>".</p> <p>Each <code class="idl"><a data-link-type="idl" href="#websocket" id="ref-for-websocket⑥">WebSocket</a></code> object has an associated <dfn class="dfn-paneled" data-dfn-for="WebSocket" data-dfn-type="dfn" data-noexport id="websocket-ready-state">ready state</dfn>, which is a number representing the state of the connection. Initially it must be <code class="idl"><a data-link-type="idl" href="#dom-websocket-connecting" id="ref-for-dom-websocket-connecting①">CONNECTING</a></code> (0). It can have the following values:</p> <dl> <dt data-md><dfn class="dfn-paneled idl-code" data-dfn-for="WebSocket" data-dfn-type="const" data-export id="dom-websocket-connecting"><code>CONNECTING</code></dfn> (numeric value 0) <dd data-md> <p>The connection has not yet been established.</p> <dt data-md><dfn class="dfn-paneled idl-code" data-dfn-for="WebSocket" data-dfn-type="const" data-export id="dom-websocket-open"><code>OPEN</code></dfn> (numeric value 1) <dd data-md> <p><a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and" id="ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and②">The WebSocket connection is established</a> and communication is possible.</p> <dt data-md><dfn class="dfn-paneled idl-code" data-dfn-for="WebSocket" data-dfn-type="const" data-export id="dom-websocket-closing"><code>CLOSING</code></dfn> (numeric value 2) <dd data-md> <p>The connection is going through the closing handshake, or the <code class="idl"><a data-link-type="idl" href="#dom-websocket-close" id="ref-for-dom-websocket-close①">close()</a></code> method has been invoked.</p> <dt data-md><dfn class="dfn-paneled idl-code" data-dfn-for="WebSocket" data-dfn-type="const" data-export id="dom-websocket-closed"><code>CLOSED</code></dfn> (numeric value 3) <dd data-md> <p>The connection has been closed or could not be opened.</p> </dl> <dl class="domintro non-normative"> <dt data-md><code><var>socket</var> = new <code class="idl"><a data-link-type="idl" href="#dom-websocket-websocket" id="ref-for-dom-websocket-websocket①">WebSocket</a></code>(<var>url</var> [, <var>protocols</var> ])</code> <dd data-md> <p>Creates a new <code class="idl"><a data-link-type="idl" href="#websocket" id="ref-for-websocket⑦">WebSocket</a></code> object, immediately establishing the associated WebSocket connection.</p> <p><var>url</var> is a string giving the <a data-link-type="dfn" href="https://url.spec.whatwg.org/#concept-url" id="ref-for-concept-url①">URL</a> over which the connection is established. Only "<code>ws</code>", "<code>wss</code>", "<code>http</code>", and "<code>https</code>" schemes are allowed; others will cause a "<code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#syntaxerror" id="ref-for-syntaxerror">SyntaxError</a></code>" <code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#idl-DOMException" id="ref-for-idl-DOMException">DOMException</a></code>. URLs with <a data-link-type="dfn" href="https://url.spec.whatwg.org/#concept-url-fragment" id="ref-for-concept-url-fragment">fragments</a> will always cause such an exception.</p> <p><var>protocols</var> 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 `<a data-link-type="http-header" href="https://datatracker.ietf.org/doc/html/rfc6455#section-11.3.4" id="ref-for-section-11.3.4"><code>Sec-WebSocket-Protocol</code></a>` fields as defined by The WebSocket protocol. <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a></p> <dt data-md><code><var>socket</var>.<a class="idl-code" data-link-type="method" href="#dom-websocket-send" id="ref-for-dom-websocket-send①">send</a>(<var>data</var>)</code> <dd data-md> <p>Transmits <var>data</var> using the WebSocket connection. <var>data</var> can be a string, a <code class="idl"><a data-link-type="idl" href="https://w3c.github.io/FileAPI/#dfn-Blob" id="ref-for-dfn-Blob①">Blob</a></code>, an <code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#idl-ArrayBuffer" id="ref-for-idl-ArrayBuffer">ArrayBuffer</a></code>, or an <code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#ArrayBufferView" id="ref-for-ArrayBufferView">ArrayBufferView</a></code>.</p> <dt data-md><code><var>socket</var>.<a class="idl-code" data-link-type="method" href="#dom-websocket-close" id="ref-for-dom-websocket-close②">close</a>([ <var>code</var> ] [, <var>reason</var> ])</code> <dd data-md> <p>Closes the WebSocket connection, optionally using <var>code</var> as <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.5" id="ref-for-section-7.1.5">the WebSocket connection close code</a> and <var>reason</var> as <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.6" id="ref-for-section-7.1.6">the WebSocket connection close reason</a>.</p> <dt data-md><code><var>socket</var>.<a class="idl-code" data-link-type="attribute" href="#dom-websocket-url" id="ref-for-dom-websocket-url①">url</a></code> <dd data-md> <p>Returns the <a data-link-type="dfn" href="https://url.spec.whatwg.org/#concept-url" id="ref-for-concept-url②">URL that was used</a> to establish the WebSocket connection.</p> <dt data-md><code><var>socket</var>.<a class="idl-code" data-link-type="attribute" href="#dom-websocket-readystate" id="ref-for-dom-websocket-readystate①">readyState</a></code> <dd data-md> <p>Returns the state of the WebSocket connection. It can have the values described above.</p> <dt data-md><code><var>socket</var>.<a class="idl-code" data-link-type="attribute" href="#dom-websocket-bufferedamount" id="ref-for-dom-websocket-bufferedamount①">bufferedAmount</a></code> <dd data-md> <p>Returns the number of bytes of application data (UTF-8 text and binary data) that have been queued using <code class="idl"><a data-link-type="idl" href="#dom-websocket-send" id="ref-for-dom-websocket-send②">send()</a></code> but not yet been transmitted to the network.</p> <p>If the WebSocket connection is closed, this attribute’s value will only increase with each call to the <code class="idl"><a data-link-type="idl" href="#dom-websocket-send" id="ref-for-dom-websocket-send③">send()</a></code> method. (The number does not reset to zero once the connection closes.)</p> <dt data-md><code><var>socket</var>.<a class="idl-code" data-link-type="attribute" href="#dom-websocket-extensions" id="ref-for-dom-websocket-extensions①">extensions</a></code> <dd data-md> <p>Returns the extensions selected by the server, if any.</p> <dt data-md><code><var>socket</var>.<a class="idl-code" data-link-type="attribute" href="#dom-websocket-protocol" id="ref-for-dom-websocket-protocol①">protocol</a></code> <dd data-md> <p>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.</p> <dt data-md><code><var>socket</var>.<a class="idl-code" data-link-type="attribute" href="#dom-websocket-binarytype" id="ref-for-dom-websocket-binarytype①">binaryType</a></code> <dd data-md> <p>Returns a string that indicates how binary data from <var>socket</var> is exposed to scripts:</p> <dl> <dt data-md>"<code class="idl"><a data-link-type="idl" href="#dom-binarytype-blob" id="ref-for-dom-binarytype-blob②">blob</a></code>" <dd data-md> <p>Binary data is returned in <code class="idl"><a data-link-type="idl" href="https://w3c.github.io/FileAPI/#dfn-Blob" id="ref-for-dfn-Blob②">Blob</a></code> form.</p> <dt data-md>"<code class="idl"><a data-link-type="idl" href="#dom-binarytype-arraybuffer" id="ref-for-dom-binarytype-arraybuffer①">arraybuffer</a></code>" <dd data-md> <p>Binary data is returned in <code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#idl-ArrayBuffer" id="ref-for-idl-ArrayBuffer①">ArrayBuffer</a></code> form.</p> </dl> <p>The default is "<code class="idl"><a data-link-type="idl" href="#dom-binarytype-blob" id="ref-for-dom-binarytype-blob③">blob</a></code>".</p> <dt data-md><code><var>socket</var>.<a class="idl-code" data-link-type="attribute" href="#dom-websocket-binarytype" id="ref-for-dom-websocket-binarytype②">binaryType</a> = <var>value</var></code> <dd data-md> <p>Changes how binary data is returned.</p> </dl> <div class="algorithm" data-algorithm="WebSocket(url, protocols)" data-algorithm-for="WebSocket"> The <dfn class="dfn-paneled idl-code" data-dfn-for="WebSocket" data-dfn-type="constructor" data-export data-lt="WebSocket(url, protocols)|constructor(url, protocols)|WebSocket(url)|constructor(url)" id="dom-websocket-websocket"><code>new WebSocket(<var>url</var>, <var>protocols</var>)</code></dfn> constructor steps are: <ol> <li data-md> <p>Let <var>baseURL</var> be <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#this" id="ref-for-this">this</a>'s <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#relevant-settings-object" id="ref-for-relevant-settings-object">relevant settings object</a>'s <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#api-base-url" id="ref-for-api-base-url">API base URL</a>.</p> <li data-md> <p>Let <var>urlRecord</var> be the result of applying the <a data-link-type="dfn" href="https://url.spec.whatwg.org/#concept-url-parser" id="ref-for-concept-url-parser">URL parser</a> to <var>url</var> with <var>baseURL</var>.</p> <li data-md> <p>If <var>urlRecord</var> is failure, then throw a "<code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#syntaxerror" id="ref-for-syntaxerror①">SyntaxError</a></code>" <code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#idl-DOMException" id="ref-for-idl-DOMException①">DOMException</a></code>.</p> <li data-md> <p>If <var>urlRecord</var>’s <a data-link-type="dfn" href="https://url.spec.whatwg.org/#concept-url-scheme" id="ref-for-concept-url-scheme③">scheme</a> is "<code>http</code>", then set <var>urlRecord</var>’s <a data-link-type="dfn" href="https://url.spec.whatwg.org/#concept-url-scheme" id="ref-for-concept-url-scheme④">scheme</a> to "<code>ws</code>".</p> <li data-md> <p>Otherwise, if <var>urlRecord</var>’s <a data-link-type="dfn" href="https://url.spec.whatwg.org/#concept-url-scheme" id="ref-for-concept-url-scheme⑤">scheme</a> is "<code>https</code>", set <var>urlRecord</var>’s <a data-link-type="dfn" href="https://url.spec.whatwg.org/#concept-url-scheme" id="ref-for-concept-url-scheme⑥">scheme</a> to "<code>wss</code>".</p> <li data-md> <p>If <var>urlRecord</var>’s <a data-link-type="dfn" href="https://url.spec.whatwg.org/#concept-url-scheme" id="ref-for-concept-url-scheme⑦">scheme</a> is not "<code><a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-11.1.1" id="ref-for-section-11.1.1">ws</a></code>" or "<code><a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-11.1.2" id="ref-for-section-11.1.2">wss</a></code>", then throw a "<code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#syntaxerror" id="ref-for-syntaxerror②">SyntaxError</a></code>" <code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#idl-DOMException" id="ref-for-idl-DOMException②">DOMException</a></code>.</p> <li data-md> <p>If <var>urlRecord</var>’s <a data-link-type="dfn" href="https://url.spec.whatwg.org/#concept-url-fragment" id="ref-for-concept-url-fragment①">fragment</a> is non-null, then throw a "<code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#syntaxerror" id="ref-for-syntaxerror③">SyntaxError</a></code>" <code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#idl-DOMException" id="ref-for-idl-DOMException③">DOMException</a></code>.</p> <li data-md> <p>If <var>protocols</var> is a string, set <var>protocols</var> to a sequence consisting of just that string.</p> <li data-md> <p>If any of the values in <var>protocols</var> occur more than once or otherwise fail to match the requirements for elements that comprise the value of `<a data-link-type="http-header" href="https://datatracker.ietf.org/doc/html/rfc6455#section-11.3.4" id="ref-for-section-11.3.4①"><code>Sec-WebSocket-Protocol</code></a>` fields as defined by The WebSocket protocol, then throw a "<code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#syntaxerror" id="ref-for-syntaxerror④">SyntaxError</a></code>" <code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#idl-DOMException" id="ref-for-idl-DOMException④">DOMException</a></code>. <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a></p> <li data-md> <p>Set <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#this" id="ref-for-this①">this</a>'s <a data-link-type="dfn" href="#websocket-internal-url" id="ref-for-websocket-internal-url">url</a> to <var>urlRecord</var>.</p> <li data-md> <p>Let <var>client</var> be <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#this" id="ref-for-this②">this</a>'s <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#relevant-settings-object" id="ref-for-relevant-settings-object①">relevant settings object</a>.</p> <li data-md> <p>Run this step <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/infrastructure.html#in-parallel" id="ref-for-in-parallel">in parallel</a>:</p> <ol> <li data-md> <p><a data-link-type="dfn" href="#concept-websocket-establish" id="ref-for-concept-websocket-establish">Establish a WebSocket connection</a> given <var>urlRecord</var>, <var>protocols</var>, and <var>client</var>. <a data-link-type="biblio" href="#biblio-fetch" title="Fetch Standard">[FETCH]</a></p> <p class="note" role="note">If the <a data-link-type="dfn" href="#concept-websocket-establish" id="ref-for-concept-websocket-establish①">establish a WebSocket connection</a> algorithm fails, it triggers the <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.7" id="ref-for-section-7.1.7④">fail the WebSocket connection</a> algorithm, which then invokes the <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.1" id="ref-for-section-7.1.1">close the WebSocket connection</a> algorithm, which then establishes that <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.4" id="ref-for-section-7.1.4">the WebSocket connection is closed</a>, which fires the <code class="idl"><a data-link-type="idl" href="#eventdef-websocket-close" id="ref-for-eventdef-websocket-close">close</a></code> event <a href="#closeWebSocket">as described below</a>. </p> </ol> </ol> </div> <hr> <p>The <dfn class="dfn-paneled idl-code" data-dfn-for="WebSocket" data-dfn-type="attribute" data-export id="dom-websocket-url"><code>url</code></dfn> getter steps are to return <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#this" id="ref-for-this③">this</a>'s <a data-link-type="dfn" href="#websocket-internal-url" id="ref-for-websocket-internal-url①">url</a>, <a data-link-type="dfn" href="https://url.spec.whatwg.org/#concept-url-serializer" id="ref-for-concept-url-serializer">serialized</a>.</p> <p>The <dfn class="dfn-paneled idl-code" data-dfn-for="WebSocket" data-dfn-type="attribute" data-export id="dom-websocket-readystate"><code>readyState</code></dfn> getter steps are to return <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#this" id="ref-for-this④">this</a>'s <a data-link-type="dfn" href="#websocket-ready-state" id="ref-for-websocket-ready-state">ready state</a>.</p> <p>The <dfn class="dfn-paneled idl-code" data-dfn-for="WebSocket" data-dfn-type="attribute" data-export id="dom-websocket-extensions"><code>extensions</code></dfn> attribute must initially return the empty string. After <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and" id="ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and③">the WebSocket connection is established</a>, its value might change, as defined below.</p> <p></p> <p>The <dfn class="dfn-paneled idl-code" data-dfn-for="WebSocket" data-dfn-type="attribute" data-export id="dom-websocket-protocol"><code>protocol</code></dfn> attribute must initially return the empty string. After <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and" id="ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and④">the WebSocket connection is established</a>, its value might change, as defined below.</p> <div class="algorithm" data-algorithm="close(code, reason)" data-algorithm-for="WebSocket"> The <dfn class="dfn-paneled idl-code" data-dfn-for="WebSocket" data-dfn-type="method" data-export data-lt="close(code, reason)|close(code)|close()" id="dom-websocket-close"><code>close(<var>code</var>, <var>reason</var>)</code></dfn> method steps are: <ol> <li data-md> <p>If <var>code</var> is present, but is neither an integer equal to 1000 nor an integer in the range 3000 to 4999, inclusive, throw an "<code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#invalidaccesserror" id="ref-for-invalidaccesserror">InvalidAccessError</a></code>" <code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#idl-DOMException" id="ref-for-idl-DOMException⑤">DOMException</a></code>.</p> <li data-md> <p>If <var>reason</var> is present, then run these substeps:</p> <ol> <li data-md> <p>Let <var>reasonBytes</var> be the result of <a data-link-type="dfn" href="https://encoding.spec.whatwg.org/#utf-8-encode" id="ref-for-utf-8-encode">encoding</a> <var>reason</var>.</p> <li data-md> <p>If <var>reasonBytes</var> is longer than 123 bytes, then throw a "<code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#syntaxerror" id="ref-for-syntaxerror⑤">SyntaxError</a></code>" <code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#idl-DOMException" id="ref-for-idl-DOMException⑥">DOMException</a></code>.</p> </ol> <li data-md> <p>Run the first matching steps from the following list:</p> <dl class="switch"> <dt data-md>If <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#this" id="ref-for-this⑤">this</a>'s <a data-link-type="dfn" href="#websocket-ready-state" id="ref-for-websocket-ready-state①">ready state</a> is <code class="idl"><a data-link-type="idl" href="#dom-websocket-closing" id="ref-for-dom-websocket-closing①">CLOSING</a></code> (2) or <code class="idl"><a data-link-type="idl" href="#dom-websocket-closed" id="ref-for-dom-websocket-closed①">CLOSED</a></code> (3) <dd data-md> <p>Do nothing.</p> <p class="note" role="note">The connection is already closing or is already closed. If it has not already, a <code class="idl"><a data-link-type="idl" href="#eventdef-websocket-close" id="ref-for-eventdef-websocket-close①">close</a></code> event will eventually fire <a href="#closeWebSocket">as described below</a>. </p> <dt data-md>If the WebSocket connection is not yet <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and" id="ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and⑤">established</a> <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a> <dd data-md> <p><a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.7" id="ref-for-section-7.1.7⑤">Fail the WebSocket connection</a> and set <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#this" id="ref-for-this⑥">this</a>'s <a data-link-type="dfn" href="#websocket-ready-state" id="ref-for-websocket-ready-state②">ready state</a> to <code class="idl"><a data-link-type="idl" href="#dom-websocket-closing" id="ref-for-dom-websocket-closing②">CLOSING</a></code> (2). <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a></p> <p class="note" role="note">The <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.7" id="ref-for-section-7.1.7⑥">fail the WebSocket connection</a> algorithm invokes the <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.1" id="ref-for-section-7.1.1①">close the WebSocket connection</a> algorithm, which then establishes that <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.4" id="ref-for-section-7.1.4①">the WebSocket connection is closed</a>, which fires the <code class="idl"><a data-link-type="idl" href="#eventdef-websocket-close" id="ref-for-eventdef-websocket-close②">close</a></code> event <a href="#closeWebSocket">as described below</a>. </p> <dt data-md>If the WebSocket closing handshake has not yet been <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.3" id="ref-for-section-7.1.3">started</a> <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a> <dd data-md> <p><a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.2" id="ref-for-section-7.1.2">Start the WebSocket closing handshake</a> and set <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#this" id="ref-for-this⑦">this</a>'s <a data-link-type="dfn" href="#websocket-ready-state" id="ref-for-websocket-ready-state③">ready state</a> to <code class="idl"><a data-link-type="idl" href="#dom-websocket-closing" id="ref-for-dom-websocket-closing③">CLOSING</a></code> (2). <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a></p> <p>If neither <var>code</var> nor <var>reason</var> is present, the WebSocket Close message must not have a body.</p> <p class="note" role="note">The WebSocket Protocol erroneously states that the status code is <span class="allow-2119">required for the <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.2" id="ref-for-section-7.1.2①">start the WebSocket closing handshake</a> algorithm. </span></p> <p>If <var>code</var> is present, then the status code to use in the WebSocket Close message must be the integer given by <var>code</var>. <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a></p> <p>If <var>reason</var> is also present, then <var>reasonBytes</var> must be provided in the Close message after the status code. <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a></p> <p class="note" role="note">The <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.2" id="ref-for-section-7.1.2②">start the WebSocket closing handshake</a> algorithm eventually invokes the <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.1" id="ref-for-section-7.1.1②">close the WebSocket connection</a> algorithm, which then establishes that <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.4" id="ref-for-section-7.1.4②">the WebSocket connection is closed</a>, which fires the <code class="idl"><a data-link-type="idl" href="#eventdef-websocket-close" id="ref-for-eventdef-websocket-close③">close</a></code> event <a href="#closeWebSocket">as described below</a>. </p> <dt data-md>Otherwise <dd data-md> <p>Set <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#this" id="ref-for-this⑧">this</a>'s <a data-link-type="dfn" href="#websocket-ready-state" id="ref-for-websocket-ready-state④">ready state</a> to <code class="idl"><a data-link-type="idl" href="#dom-websocket-closing" id="ref-for-dom-websocket-closing④">CLOSING</a></code> (2).</p> <p class="note" role="note"><a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.3" id="ref-for-section-7.1.3①">The WebSocket closing handshake is started</a>, and will eventually invoke the <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.1" id="ref-for-section-7.1.1③">close the WebSocket connection</a> algorithm, which will establish that <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.4" id="ref-for-section-7.1.4③">the WebSocket connection is closed</a>, and thus the <code class="idl"><a data-link-type="idl" href="#eventdef-websocket-close" id="ref-for-eventdef-websocket-close④">close</a></code> event will fire, <a href="#closeWebSocket">as described below</a>. </p> </dl> </ol> </div> <p class="note" role="note">The <code class="idl"><a data-link-type="idl" href="#dom-websocket-close" id="ref-for-dom-websocket-close③">close()</a></code> 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. </p> <hr> <p>The <dfn class="dfn-paneled idl-code" data-dfn-for="WebSocket" data-dfn-type="attribute" data-export id="dom-websocket-bufferedamount"><code>bufferedAmount</code></dfn> getter steps are to return the number of bytes of application data (UTF-8 text and binary data) that have been queued using <code class="idl"><a data-link-type="idl" href="#dom-websocket-send" id="ref-for-dom-websocket-send④">send()</a></code> but that, as of the last time the <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#event-loop" id="ref-for-event-loop">event loop</a> reached <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#step1" id="ref-for-step1">step 1</a>, 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 <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/infrastructure.html#in-parallel" id="ref-for-in-parallel①">in parallel</a> with script execution.) This does not include framing overhead incurred by the protocol, or buffering done by the operating system or network hardware.</p> <div class="example" id="buffered-amount-example"> <a class="self-link" href="#buffered-amount-example"></a> <p>In this simple example, the <code class="idl"><a data-link-type="idl" href="#dom-websocket-bufferedamount" id="ref-for-dom-websocket-bufferedamount②">bufferedAmount</a></code> 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 <em>can</em> handle, if that is too fast.</p> <pre class="highlight"><c- a>var</c-> socket <c- o>=</c-> <c- ow>new</c-> WebSocket<c- p>(</c-><c- t>'ws://game.example.com:12010/updates'</c-><c- p>);</c-> socket<c- p>.</c->onopen <c- o>=</c-> <c- a>function</c-> <c- p>()</c-> <c- p>{</c-> setInterval<c- p>(</c-><c- a>function</c-><c- p>()</c-> <c- p>{</c-> <c- k>if</c-> <c- p>(</c->socket<c- p>.</c->bufferedAmount <c- o>==</c-> <c- mf>0</c-><c- p>)</c-> socket<c- p>.</c->send<c- p>(</c->getUpdateData<c- p>());</c-> <c- p>},</c-> <c- mf>50</c-><c- p>);</c-> <c- p>};</c-> </pre> <p>The <code class="idl"><a data-link-type="idl" href="#dom-websocket-bufferedamount" id="ref-for-dom-websocket-bufferedamount③">bufferedAmount</a></code> 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.</p> </div> <hr> <p>The <dfn class="dfn-paneled idl-code" data-dfn-for="WebSocket" data-dfn-type="attribute" data-export id="dom-websocket-binarytype"><code>binaryType</code></dfn> getter steps are to return <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#this" id="ref-for-this⑨">this</a>'s <a data-link-type="dfn" href="#websocket-binary-type" id="ref-for-websocket-binary-type">binary type</a>.</p> <p>The <code class="idl"><a data-link-type="idl" href="#dom-websocket-binarytype" id="ref-for-dom-websocket-binarytype③">binaryType</a></code> setter steps are to set <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#this" id="ref-for-this①⓪">this</a>'s <a data-link-type="dfn" href="#websocket-binary-type" id="ref-for-websocket-binary-type①">binary type</a> to <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#the-given-value" id="ref-for-the-given-value">the given value</a>.</p> <p class="note" role="note">User agents can use the <a data-link-type="dfn" href="#websocket-binary-type" id="ref-for-websocket-binary-type②">binary type</a> as a hint for how to handle incoming binary data: if it is "<code class="idl"><a data-link-type="idl" href="#dom-binarytype-blob" id="ref-for-dom-binarytype-blob④">blob</a></code>", it is safe to spool it to disk, and if it is "<code class="idl"><a data-link-type="idl" href="#dom-binarytype-arraybuffer" id="ref-for-dom-binarytype-arraybuffer②">arraybuffer</a></code>", 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. </p> <div class="algorithm" data-algorithm="send(data)" data-algorithm-for="WebSocket"> The <dfn class="dfn-paneled idl-code" data-dfn-for="WebSocket" data-dfn-type="method" data-export id="dom-websocket-send"><code>send(<var>data</var>)</code></dfn> method steps are: <ol> <li data-md> <p>If <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#this" id="ref-for-this①①">this</a>'s <a data-link-type="dfn" href="#websocket-ready-state" id="ref-for-websocket-ready-state⑤">ready state</a> is <code class="idl"><a data-link-type="idl" href="#dom-websocket-connecting" id="ref-for-dom-websocket-connecting②">CONNECTING</a></code>, then throw an "<code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#invalidstateerror" id="ref-for-invalidstateerror">InvalidStateError</a></code>" <code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#idl-DOMException" id="ref-for-idl-DOMException⑦">DOMException</a></code>.</p> <li data-md> <p>Run the appropriate set of steps from the following list:</p> <dl> <dt data-md>If <var>data</var> is a string <dd data-md> <p>If <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and" id="ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and⑥">the WebSocket connection is established</a> and <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.3" id="ref-for-section-7.1.3②">the WebSocket closing handshake has not yet started</a>, then the user agent must <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#page-66:~:text=needs%20to-,_Send%20a%20WebSocket%20Message_" id="ref-for-page-66:~:text=needs%20to-,_Send%20a%20WebSocket%20Message_">send a WebSocket Message</a> comprised of the <var>data</var> 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 <a data-link-type="dfn" href="#flagged-as-full" id="ref-for-flagged-as-full">flag the WebSocket as full</a> and then <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.1" id="ref-for-section-7.1.1④">close the WebSocket connection</a>. Any invocation of this method with a string argument that does not throw an exception must increase the <code class="idl"><a data-link-type="idl" href="#dom-websocket-bufferedamount" id="ref-for-dom-websocket-bufferedamount④">bufferedAmount</a></code> attribute by the number of bytes needed to express the argument as UTF-8. <a data-link-type="biblio" href="#biblio-unicode" title="The Unicode Standard">[UNICODE]</a> <a data-link-type="biblio" href="#biblio-encoding" title="Encoding Standard">[ENCODING]</a> <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a></p> <dt data-md>If <var>data</var> is a <code class="idl"><a data-link-type="idl" href="https://w3c.github.io/FileAPI/#dfn-Blob" id="ref-for-dfn-Blob③">Blob</a></code> object <dd data-md> <p>If <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and" id="ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and⑦">the WebSocket connection is established</a>, and <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.3" id="ref-for-section-7.1.3③">the WebSocket closing handshake has not yet started</a>, then the user agent must <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#page-66:~:text=needs%20to-,_Send%20a%20WebSocket%20Message_" id="ref-for-page-66:~:text=needs%20to-,_Send%20a%20WebSocket%20Message_①">send a WebSocket Message</a> comprised of <var>data</var> 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 <a data-link-type="dfn" href="#flagged-as-full" id="ref-for-flagged-as-full①">flag the WebSocket as full</a> and then <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.1" id="ref-for-section-7.1.1⑤">close the WebSocket connection</a>. The data to be sent is the raw data represented by the <code class="idl"><a data-link-type="idl" href="https://w3c.github.io/FileAPI/#dfn-Blob" id="ref-for-dfn-Blob④">Blob</a></code> object. Any invocation of this method with a <code class="idl"><a data-link-type="idl" href="https://w3c.github.io/FileAPI/#dfn-Blob" id="ref-for-dfn-Blob⑤">Blob</a></code> argument that does not throw an exception must increase the <code class="idl"><a data-link-type="idl" href="#dom-websocket-bufferedamount" id="ref-for-dom-websocket-bufferedamount⑤">bufferedAmount</a></code> attribute by the size of the <code class="idl"><a data-link-type="idl" href="https://w3c.github.io/FileAPI/#dfn-Blob" id="ref-for-dfn-Blob⑥">Blob</a></code> object’s raw data, in bytes. <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a> <a data-link-type="biblio" href="#biblio-fileapi" title="File API">[FILEAPI]</a></p> <dt data-md>If <var>data</var> is an <code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#idl-ArrayBuffer" id="ref-for-idl-ArrayBuffer②">ArrayBuffer</a></code> <dd data-md> <p>If <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and" id="ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and⑧">the WebSocket connection is established</a>, and <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.3" id="ref-for-section-7.1.3④">the WebSocket closing handshake has not yet started</a>, then the user agent must <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#page-66:~:text=needs%20to-,_Send%20a%20WebSocket%20Message_" id="ref-for-page-66:~:text=needs%20to-,_Send%20a%20WebSocket%20Message_②">send a WebSocket Message</a> comprised of <var>data</var> 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 <a data-link-type="dfn" href="#flagged-as-full" id="ref-for-flagged-as-full②">flag the WebSocket as full</a> and then <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.1" id="ref-for-section-7.1.1⑥">close the WebSocket connection</a>. The data to be sent is the data stored in the buffer described by the <code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#idl-ArrayBuffer" id="ref-for-idl-ArrayBuffer③">ArrayBuffer</a></code> object. Any invocation of this method with an <code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#idl-ArrayBuffer" id="ref-for-idl-ArrayBuffer④">ArrayBuffer</a></code> argument that does not throw an exception must increase the <code class="idl"><a data-link-type="idl" href="#dom-websocket-bufferedamount" id="ref-for-dom-websocket-bufferedamount⑥">bufferedAmount</a></code> attribute by the length of the <code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#idl-ArrayBuffer" id="ref-for-idl-ArrayBuffer⑤">ArrayBuffer</a></code> in bytes. <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a></p> <dt data-md>If <var>data</var> is an <code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#ArrayBufferView" id="ref-for-ArrayBufferView①">ArrayBufferView</a></code> <dd data-md> <p>If <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and" id="ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and⑨">the WebSocket connection is established</a>, and <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.3" id="ref-for-section-7.1.3⑤">the WebSocket closing handshake has not yet started</a>, then the user agent must <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#page-66:~:text=needs%20to-,_Send%20a%20WebSocket%20Message_" id="ref-for-page-66:~:text=needs%20to-,_Send%20a%20WebSocket%20Message_③">send a WebSocket Message</a> comprised of <var>data</var> 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 <a data-link-type="dfn" href="#flagged-as-full" id="ref-for-flagged-as-full③">flag the WebSocket as full</a> and then <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.1" id="ref-for-section-7.1.1⑦">close the WebSocket connection</a>. The data to be sent is the data stored in the section of the buffer described by the <code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#idl-ArrayBuffer" id="ref-for-idl-ArrayBuffer⑥">ArrayBuffer</a></code> object that <var>data</var> references. Any invocation of this method with this kind of argument that does not throw an exception must increase the <code class="idl"><a data-link-type="idl" href="#dom-websocket-bufferedamount" id="ref-for-dom-websocket-bufferedamount⑦">bufferedAmount</a></code> attribute by the length of <var>data</var>’s buffer in bytes. <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a></p> </dl> </ol> </div> <hr> <p>The following are the <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handlers" id="ref-for-event-handlers">event handlers</a> (and their corresponding <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-event-type" id="ref-for-event-handler-event-type">event handler event types</a>) that must be supported, as <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-idl-attributes" id="ref-for-event-handler-idl-attributes">event handler IDL attributes</a>, by all objects implementing the <code class="idl"><a data-link-type="idl" href="#websocket" id="ref-for-websocket⑧">WebSocket</a></code> interface:</p> <table> <thead> <tr> <th><a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handlers" id="ref-for-event-handlers①">Event handler</a> <th><a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-event-type" id="ref-for-event-handler-event-type①">Event handler event type</a> <tbody> <tr> <td><dfn class="dfn-paneled idl-code" data-dfn-for="WebSocket" data-dfn-type="attribute" data-export id="dom-websocket-onopen"><code>onopen</code></dfn> <td> <code class="idl"><a data-link-type="idl" href="#eventdef-websocket-open" id="ref-for-eventdef-websocket-open">open</a></code> <tr> <td><dfn class="dfn-paneled idl-code" data-dfn-for="WebSocket" data-dfn-type="attribute" data-export id="dom-websocket-onmessage"><code>onmessage</code></dfn> <td> <code class="idl"><a data-link-type="idl" href="#eventdef-websocket-message" id="ref-for-eventdef-websocket-message">message</a></code> <tr> <td><dfn class="dfn-paneled idl-code" data-dfn-for="WebSocket" data-dfn-type="attribute" data-export id="dom-websocket-onerror"><code>onerror</code></dfn> <td> <code class="idl"><a data-link-type="idl" href="#eventdef-websocket-error" id="ref-for-eventdef-websocket-error">error</a></code> <tr> <td><dfn class="dfn-paneled idl-code" data-dfn-for="WebSocket" data-dfn-type="attribute" data-export id="dom-websocket-onclose"><code>onclose</code></dfn> <td> <code class="idl"><a data-link-type="idl" href="#eventdef-websocket-close" id="ref-for-eventdef-websocket-close⑤">close</a></code> </table> <h2 class="heading settled" data-level="4" id="feedback-from-the-protocol"><span class="secno">4. </span><span class="content">Feedback from the protocol</span><a class="self-link" href="#feedback-from-the-protocol"></a></h2> <p>When <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and" id="ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and①⓪">the WebSocket connection is established</a>, the user agent must <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task" id="ref-for-queue-a-task">queue a task</a> to run these steps:</p> <div class="algorithm" data-algorithm="handle connection establishment"> <ol> <li data-md> <p>Change the <a data-link-type="dfn" href="#websocket-ready-state" id="ref-for-websocket-ready-state⑥">ready state</a> to <code class="idl"><a data-link-type="idl" href="#dom-websocket-open" id="ref-for-dom-websocket-open①">OPEN</a></code> (1).</p> <li data-md> <p>Change the <code class="idl"><a data-link-type="idl" href="#dom-websocket-extensions" id="ref-for-dom-websocket-extensions②">extensions</a></code> attribute’s value to the <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and" id="ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and①①">extensions in use</a>, if it is not the null value. <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a></p> <li data-md> <p>Change the <code class="idl"><a data-link-type="idl" href="#dom-websocket-protocol" id="ref-for-dom-websocket-protocol②">protocol</a></code> attribute’s value to the <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_Subprotocol%20In,Use_" id="ref-for-page-19:~:text=_Subprotocol%20In,Use_">subprotocol in use</a>, if it is not the null value. <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a></p> <li data-md> <p><a data-link-type="dfn" href="https://dom.spec.whatwg.org/#concept-event-fire" id="ref-for-concept-event-fire">Fire an event</a> named <dfn class="dfn-paneled idl-code" data-dfn-for="WebSocket" data-dfn-type="event" data-export id="eventdef-websocket-open"><code>open</code></dfn> at the <code class="idl"><a data-link-type="idl" href="#websocket" id="ref-for-websocket⑨">WebSocket</a></code> object.</p> </ol> <p class="note" role="note">Since the algorithm above is <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task" id="ref-for-queue-a-task①">queued as a task</a>, there is no race condition between <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and" id="ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and①②">the WebSocket connection being established</a> and the script setting up an event listener for the <code class="idl"><a data-link-type="idl" href="#eventdef-websocket-open" id="ref-for-eventdef-websocket-open①">open</a></code> event. </p> </div> <hr> <div class="algorithm" data-algorithm="handle a WebSocket message"> <p>When <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#page-66:~:text=_A%20WebSocket%20Message%20Has%20Been%20Received_" id="ref-for-page-66:~:text=_A%20WebSocket%20Message%20Has%20Been%20Received_">a WebSocket message has been received</a> with type <var>type</var> and data <var>data</var>, the user agent must <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task" id="ref-for-queue-a-task②">queue a task</a> to follow these steps: <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a></p> <ol> <li data-md> <p>If <a data-link-type="dfn" href="#websocket-ready-state" id="ref-for-websocket-ready-state⑦">ready state</a> is not <code class="idl"><a data-link-type="idl" href="#dom-websocket-open" id="ref-for-dom-websocket-open②">OPEN</a></code> (1), then return.</p> <li data-md> <p>Let <var>dataForEvent</var> be determined by switching on <var>type</var> and <a data-link-type="dfn" href="#websocket-binary-type" id="ref-for-websocket-binary-type③">binary type</a>:</p> <dl class="switch"> <dt data-md><var>type</var> indicates that the data is Text <dd data-md> <p>a new <code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#idl-DOMString" id="ref-for-idl-DOMString④">DOMString</a></code> containing <var>data</var></p> <dt data-md><var>type</var> indicates that the data is Binary and <a data-link-type="dfn" href="#websocket-binary-type" id="ref-for-websocket-binary-type④">binary type</a> is <dfn class="dfn-paneled idl-code" data-dfn-for="BinaryType" data-dfn-type="enum-value" data-export id="dom-binarytype-blob"><code>"blob"</code></dfn> <dd data-md> <p>a new <code class="idl"><a data-link-type="idl" href="https://w3c.github.io/FileAPI/#dfn-Blob" id="ref-for-dfn-Blob⑦">Blob</a></code> object, created in the <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#concept-relevant-realm" id="ref-for-concept-relevant-realm">relevant Realm</a> of the <code class="idl"><a data-link-type="idl" href="#websocket" id="ref-for-websocket①⓪">WebSocket</a></code> object, that represents <var>data</var> as its raw data <a data-link-type="biblio" href="#biblio-fileapi" title="File API">[FILEAPI]</a></p> <dt data-md><var>type</var> indicates that the data is Binary and <a data-link-type="dfn" href="#websocket-binary-type" id="ref-for-websocket-binary-type⑤">binary type</a> is <dfn class="dfn-paneled idl-code" data-dfn-for="BinaryType" data-dfn-type="enum-value" data-export id="dom-binarytype-arraybuffer"><code>"arraybuffer"</code></dfn> <dd data-md> <p>a new <code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#idl-ArrayBuffer" id="ref-for-idl-ArrayBuffer⑦">ArrayBuffer</a></code> object, created in the <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#concept-relevant-realm" id="ref-for-concept-relevant-realm①">relevant Realm</a> of the <code class="idl"><a data-link-type="idl" href="#websocket" id="ref-for-websocket①①">WebSocket</a></code> object, whose contents are <var>data</var></p> </dl> <li data-md> <p><a data-link-type="dfn" href="https://dom.spec.whatwg.org/#concept-event-fire" id="ref-for-concept-event-fire①">Fire an event</a> named <dfn class="dfn-paneled idl-code" data-dfn-for="WebSocket" data-dfn-type="event" data-export id="eventdef-websocket-message"><code>message</code></dfn> at the <code class="idl"><a data-link-type="idl" href="#websocket" id="ref-for-websocket①②">WebSocket</a></code> object, using <code class="idl"><a data-link-type="idl" href="https://html.spec.whatwg.org/multipage/comms.html#messageevent" id="ref-for-messageevent">MessageEvent</a></code>, with the <code class="idl"><a data-link-type="idl" href="https://html.spec.whatwg.org/multipage/comms.html#dom-messageevent-origin" id="ref-for-dom-messageevent-origin">origin</a></code> attribute initialized to the <a data-link-type="dfn" href="https://url.spec.whatwg.org/#concept-url-serializer" id="ref-for-concept-url-serializer①">serialization</a> of the <code class="idl"><a data-link-type="idl" href="#websocket" id="ref-for-websocket①③">WebSocket</a></code> object’s <a data-link-type="dfn" href="https://url.spec.whatwg.org/#concept-url" id="ref-for-concept-url③">url</a>'s <a data-link-type="dfn" href="https://url.spec.whatwg.org/#concept-url-origin" id="ref-for-concept-url-origin">origin</a>, and the <code class="idl"><a data-link-type="idl" href="https://html.spec.whatwg.org/multipage/comms.html#dom-messageevent-data" id="ref-for-dom-messageevent-data">data</a></code> attribute initialized to <var>dataForEvent</var>.</p> </ol> <p class="note" role="note">User agents are encouraged to check if they can perform the above steps efficiently before they run the task, picking tasks from other <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#task-queue" id="ref-for-task-queue">task queues</a> while they prepare the buffers if not. For example, if the <a data-link-type="dfn" href="#websocket-binary-type" id="ref-for-websocket-binary-type⑥">binary type</a> is "<code class="idl"><a data-link-type="idl" href="#dom-binarytype-blob" id="ref-for-dom-binarytype-blob⑤">blob</a></code>" when the data arrived, and the user agent spooled all the data to disk, but just before running the above <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#concept-task" id="ref-for-concept-task">task</a> for this particular message the script switched <a data-link-type="dfn" href="#websocket-binary-type" id="ref-for-websocket-binary-type⑦">binary type</a> to "<code class="idl"><a data-link-type="idl" href="#dom-binarytype-arraybuffer" id="ref-for-dom-binarytype-arraybuffer③">arraybuffer</a></code>", the user agent would want to page the data back to RAM before running this <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#concept-task" id="ref-for-concept-task①">task</a> so as to avoid stalling the main thread while it created the <code class="idl"><a data-link-type="idl" href="https://webidl.spec.whatwg.org/#idl-ArrayBuffer" id="ref-for-idl-ArrayBuffer⑧">ArrayBuffer</a></code> object. </p> </div> <div class="example" id="message-example"> <a class="self-link" href="#message-example"></a> <p>Here is an example of how to define a handler for the <code class="idl"><a data-link-type="idl" href="#eventdef-websocket-message" id="ref-for-eventdef-websocket-message①">message</a></code> event in the case of text frames:</p> <pre class="highlight">mysocket<c- p>.</c->onmessage <c- o>=</c-> <c- a>function</c-> <c- p>(</c->event<c- p>)</c-> <c- p>{</c-> <c- k>if</c-> <c- p>(</c->event<c- p>.</c->data <c- o>==</c-> <c- t>'on'</c-><c- p>)</c-> <c- p>{</c-> turnLampOn<c- p>();</c-> <c- p>}</c-> <c- k>else</c-> <c- k>if</c-> <c- p>(</c->event<c- p>.</c->data <c- o>==</c-> <c- t>'off'</c-><c- p>)</c-> <c- p>{</c-> turnLampOff<c- p>();</c-> <c- p>}</c-> <c- p>};</c-> </pre> <p>The protocol here is a trivial one, with the server just sending "on" or "off" messages.</p> </div> <hr> <p>When <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.3" id="ref-for-section-7.1.3⑥">the WebSocket closing handshake is started</a>, the user agent must <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task" id="ref-for-queue-a-task③">queue a task</a> to change the <a data-link-type="dfn" href="#websocket-ready-state" id="ref-for-websocket-ready-state⑧">ready state</a> to <code class="idl"><a data-link-type="idl" href="#dom-websocket-closing" id="ref-for-dom-websocket-closing⑤">CLOSING</a></code> (2). (If the <code class="idl"><a data-link-type="idl" href="#dom-websocket-close" id="ref-for-dom-websocket-close④">close()</a></code> method was called, the <a data-link-type="dfn" href="#websocket-ready-state" id="ref-for-websocket-ready-state⑨">ready state</a> will already be set to <code class="idl"><a data-link-type="idl" href="#dom-websocket-closing" id="ref-for-dom-websocket-closing⑥">CLOSING</a></code> (2) when this task runs.) <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a></p> <hr> <p id="closeWebSocket">When <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.4" id="ref-for-section-7.1.4④">the WebSocket connection is closed</a>, possibly <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#page-41:~:text=closed-,_cleanly_." id="ref-for-page-41:~:text=closed-,_cleanly_.">cleanly</a>, the user agent must <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task" id="ref-for-queue-a-task④">queue a task</a> to run the following substeps: </p> <div class="algorithm" data-algorithm="handle connection close"> <ol> <li data-md> <p>Change the <a data-link-type="dfn" href="#websocket-ready-state" id="ref-for-websocket-ready-state①⓪">ready state</a> to <code class="idl"><a data-link-type="idl" href="#dom-websocket-closed" id="ref-for-dom-websocket-closed②">CLOSED</a></code> (3).</p> <li data-md> <p>If the user agent was required to <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.7" id="ref-for-section-7.1.7⑦">fail the WebSocket connection</a>, or if <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.4" id="ref-for-section-7.1.4⑤">the WebSocket connection was closed</a> after being <dfn class="dfn-paneled" data-dfn-type="dfn" data-lt="flagged as full" data-noexport id="flagged-as-full">flagged as full</dfn>, <a data-link-type="dfn" href="https://dom.spec.whatwg.org/#concept-event-fire" id="ref-for-concept-event-fire②">fire an event</a> named <dfn class="dfn-paneled idl-code" data-dfn-for="WebSocket" data-dfn-type="event" data-export id="eventdef-websocket-error"><code>error</code></dfn> at the <code class="idl"><a data-link-type="idl" href="#websocket" id="ref-for-websocket①④">WebSocket</a></code> object. <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a></p> <li data-md> <p><a data-link-type="dfn" href="https://dom.spec.whatwg.org/#concept-event-fire" id="ref-for-concept-event-fire③">Fire an event</a> named <dfn class="dfn-paneled idl-code" data-dfn-for="WebSocket" data-dfn-type="event" data-export id="eventdef-websocket-close"><code>close</code></dfn> at the <code class="idl"><a data-link-type="idl" href="#websocket" id="ref-for-websocket①⑤">WebSocket</a></code> object, using <code class="idl"><a data-link-type="idl" href="#closeevent" id="ref-for-closeevent">CloseEvent</a></code>, with the <code class="idl"><a data-link-type="idl" href="#dom-closeevent-wasclean" id="ref-for-dom-closeevent-wasclean">wasClean</a></code> attribute initialized to true if the connection closed <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#page-41:~:text=closed-,_cleanly_." id="ref-for-page-41:~:text=closed-,_cleanly_.①">cleanly</a> and false otherwise, the <code class="idl"><a data-link-type="idl" href="#dom-closeevent-code" id="ref-for-dom-closeevent-code">code</a></code> attribute initialized to <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.5" id="ref-for-section-7.1.5①">the WebSocket connection close code</a>, and the <code class="idl"><a data-link-type="idl" href="#dom-closeevent-reason" id="ref-for-dom-closeevent-reason">reason</a></code> attribute initialized to the result of applying <a data-link-type="dfn" href="https://encoding.spec.whatwg.org/#utf-8-decode-without-bom" id="ref-for-utf-8-decode-without-bom">UTF-8 decode without BOM</a> to <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.6" id="ref-for-section-7.1.6①">the WebSocket connection close reason</a>. <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a></p> </ol> </div> <div class="warning"> <p>User agents must not convey any failure information to scripts in a way that would allow a script to distinguish the following situations:</p> <ul> <li data-md> <p>A server whose host name could not be resolved.</p> <li data-md> <p>A server to which packets could not successfully be routed.</p> <li data-md> <p>A server that refused the connection on the specified port.</p> <li data-md> <p>A server that failed to correctly perform a TLS handshake (e.g., the server certificate can’t be verified).</p> <li data-md> <p>A server that did not complete the opening handshake (e.g. because it was not a WebSocket server).</p> <li data-md> <p>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).</p> <li data-md> <p>A WebSocket server that abruptly closed the connection after successfully completing the opening handshake.</p> </ul> <p>In all of these cases, <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.5" id="ref-for-section-7.1.5②">the WebSocket connection close code</a> would be 1006, as required by <cite>WebSocket Protocol</cite>. <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a></p> <p>Allowing a script to distinguish these cases would allow a script to probe the user’s local network in preparation for an attack.</p> <p class="note" role="note">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). </p> </div> <hr> <p>The <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#task-source" id="ref-for-task-source">task source</a> for all <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#concept-task" id="ref-for-concept-task②">tasks</a> <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task" id="ref-for-queue-a-task⑤">queued</a> in this section is the <dfn class="dfn-paneled" data-dfn-type="dfn" data-export id="websocket-task-source">WebSocket task source</dfn>.</p> <h2 class="heading settled" data-level="5" id="ping-and-pong-frames"><span class="secno">5. </span><span class="content">Ping and Pong frames</span><a class="self-link" href="#ping-and-pong-frames"></a></h2> <p><cite>The WebSocket protocol</cite> 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.</p> <p>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.</p> <h2 class="heading settled" data-level="6" id="the-closeevent-interface"><span class="secno">6. </span><span class="content">The <code class="idl"><a data-link-type="idl" href="#closeevent" id="ref-for-closeevent①">CloseEvent</a></code> interface</span><a class="self-link" href="#the-closeevent-interface"></a></h2> <p><code class="idl"><a data-link-type="idl" href="#websocket" id="ref-for-websocket①⑥">WebSocket</a></code> objects use the <code class="idl"><a data-link-type="idl" href="#closeevent" id="ref-for-closeevent②">CloseEvent</a></code> interface for their <code class="idl"><a data-link-type="idl" href="#eventdef-websocket-close" id="ref-for-eventdef-websocket-close⑥">close</a></code> events:</p> <pre class="idl highlight def">[<a class="idl-code" data-link-type="extended-attribute" href="https://webidl.spec.whatwg.org/#Exposed" id="ref-for-Exposed①"><c- g>Exposed</c-></a>=(<c- n>Window</c->,<c- n>Worker</c->)] <c- b>interface</c-> <dfn class="dfn-paneled idl-code" data-dfn-type="interface" data-export id="closeevent"><code><c- g>CloseEvent</c-></code></dfn> : <a data-link-type="idl-name" href="https://dom.spec.whatwg.org/#event" id="ref-for-event"><c- n>Event</c-></a> { <dfn class="dfn-paneled idl-code" data-dfn-for="CloseEvent" data-dfn-type="constructor" data-export data-lt="CloseEvent(type, eventInitDict)|constructor(type, eventInitDict)|CloseEvent(type)|constructor(type)" id="dom-closeevent-closeevent"><code><c- g>constructor</c-></code></dfn>(<a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString" id="ref-for-idl-DOMString⑤"><c- b>DOMString</c-></a> <dfn class="dfn-paneled idl-code" data-dfn-for="CloseEvent/CloseEvent(type, eventInitDict), CloseEvent/constructor(type, eventInitDict), CloseEvent/CloseEvent(type), CloseEvent/constructor(type)" data-dfn-type="argument" data-export id="dom-closeevent-closeevent-type-eventinitdict-type"><code><c- g>type</c-></code></dfn>, <c- b>optional</c-> <a data-link-type="idl-name" href="#dictdef-closeeventinit" id="ref-for-dictdef-closeeventinit"><c- n>CloseEventInit</c-></a> <dfn class="dfn-paneled idl-code" data-dfn-for="CloseEvent/CloseEvent(type, eventInitDict), CloseEvent/constructor(type, eventInitDict), CloseEvent/CloseEvent(type), CloseEvent/constructor(type)" data-dfn-type="argument" data-export id="dom-closeevent-closeevent-type-eventinitdict-eventinitdict"><code><c- g>eventInitDict</c-></code></dfn> = {}); <c- b>readonly</c-> <c- b>attribute</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-boolean" id="ref-for-idl-boolean"><c- b>boolean</c-></a> <a class="idl-code" data-link-type="attribute" data-readonly data-type="boolean" href="#dom-closeevent-wasclean" id="ref-for-dom-closeevent-wasclean①"><c- g>wasClean</c-></a>; <c- b>readonly</c-> <c- b>attribute</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-unsigned-short" id="ref-for-idl-unsigned-short⑥"><c- b>unsigned</c-> <c- b>short</c-></a> <a class="idl-code" data-link-type="attribute" data-readonly data-type="unsigned short" href="#dom-closeevent-code" id="ref-for-dom-closeevent-code①"><c- g>code</c-></a>; <c- b>readonly</c-> <c- b>attribute</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-USVString" id="ref-for-idl-USVString④"><c- b>USVString</c-></a> <a class="idl-code" data-link-type="attribute" data-readonly data-type="USVString" href="#dom-closeevent-reason" id="ref-for-dom-closeevent-reason①"><c- g>reason</c-></a>; }; <c- b>dictionary</c-> <dfn class="dfn-paneled idl-code" data-dfn-type="dictionary" data-export id="dictdef-closeeventinit"><code><c- g>CloseEventInit</c-></code></dfn> : <a data-link-type="idl-name" href="https://dom.spec.whatwg.org/#dictdef-eventinit" id="ref-for-dictdef-eventinit"><c- n>EventInit</c-></a> { <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-boolean" id="ref-for-idl-boolean①"><c- b>boolean</c-></a> <dfn class="dfn-paneled idl-code" data-default="false" data-dfn-for="CloseEventInit" data-dfn-type="dict-member" data-export data-type="boolean " id="dom-closeeventinit-wasclean"><code><c- g>wasClean</c-></code></dfn> = <c- b>false</c->; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-unsigned-short" id="ref-for-idl-unsigned-short⑦"><c- b>unsigned</c-> <c- b>short</c-></a> <dfn class="dfn-paneled idl-code" data-default="0" data-dfn-for="CloseEventInit" data-dfn-type="dict-member" data-export data-type="unsigned short " id="dom-closeeventinit-code"><code><c- g>code</c-></code></dfn> = 0; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-USVString" id="ref-for-idl-USVString⑤"><c- b>USVString</c-></a> <dfn class="dfn-paneled idl-code" data-default="&quot;&quot;" data-dfn-for="CloseEventInit" data-dfn-type="dict-member" data-export data-type="USVString " id="dom-closeeventinit-reason"><code><c- g>reason</c-></code></dfn> = ""; }; </pre> <dl class="domintro"> <dt data-md><var>event</var> . <code class="idl"><a data-link-type="idl" href="#dom-closeevent-wasclean" id="ref-for-dom-closeevent-wasclean②">wasClean</a></code> <dd data-md> <p>Returns true if the connection closed cleanly; false otherwise.</p> <dt data-md><var>event</var> . <code class="idl"><a data-link-type="idl" href="#dom-closeevent-code" id="ref-for-dom-closeevent-code②">code</a></code> <dd data-md> <p>Returns the WebSocket connection close code provided by the server.</p> <dt data-md><var>event</var> . <code class="idl"><a data-link-type="idl" href="#dom-closeevent-reason" id="ref-for-dom-closeevent-reason②">reason</a></code> <dd data-md> <p>Returns the WebSocket connection close reason provided by the server.</p> </dl> <p>The <dfn class="dfn-paneled idl-code" data-dfn-for="CloseEvent" data-dfn-type="attribute" data-export id="dom-closeevent-wasclean"><code>wasClean</code></dfn> attribute must return the value it was initialized to. It represents whether the connection closed cleanly or not.</p> <p>The <dfn class="dfn-paneled idl-code" data-dfn-for="CloseEvent" data-dfn-type="attribute" data-export id="dom-closeevent-code"><code>code</code></dfn> attribute must return the value it was initialized to. It represents the WebSocket connection close code provided by the server.</p> <p>The <dfn class="dfn-paneled idl-code" data-dfn-for="CloseEvent" data-dfn-type="attribute" data-export id="dom-closeevent-reason"><code>reason</code></dfn> attribute must return the value it was initialized to. It represents the WebSocket connection close reason provided by the server.</p> <h2 class="heading settled" data-level="7" id="garbage-collection"><span class="secno">7. </span><span class="content">Garbage collection</span><a class="self-link" href="#garbage-collection"></a></h2> <p>A <code class="idl"><a data-link-type="idl" href="#websocket" id="ref-for-websocket①⑦">WebSocket</a></code> object whose <a data-link-type="dfn" href="#websocket-ready-state" id="ref-for-websocket-ready-state①①">ready state</a> was set to <code class="idl"><a data-link-type="idl" href="#dom-websocket-connecting" id="ref-for-dom-websocket-connecting③">CONNECTING</a></code> (0) as of the last time the <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#event-loop" id="ref-for-event-loop①">event loop</a> reached <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#step1" id="ref-for-step1①">step 1</a> must not be garbage collected if there are any event listeners registered for <code class="idl"><a data-link-type="idl" href="#eventdef-websocket-open" id="ref-for-eventdef-websocket-open②">open</a></code> events, <code class="idl"><a data-link-type="idl" href="#eventdef-websocket-message" id="ref-for-eventdef-websocket-message②">message</a></code> events, <code class="idl"><a data-link-type="idl" href="#eventdef-websocket-error" id="ref-for-eventdef-websocket-error①">error</a></code> events, or <code class="idl"><a data-link-type="idl" href="#eventdef-websocket-close" id="ref-for-eventdef-websocket-close⑦">close</a></code> events.</p> <p>A <code class="idl"><a data-link-type="idl" href="#websocket" id="ref-for-websocket①⑧">WebSocket</a></code> object whose <a data-link-type="dfn" href="#websocket-ready-state" id="ref-for-websocket-ready-state①②">ready state</a> was set to <code class="idl"><a data-link-type="idl" href="#dom-websocket-open" id="ref-for-dom-websocket-open③">OPEN</a></code> (1) as of the last time the <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#event-loop" id="ref-for-event-loop②">event loop</a> reached <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#step1" id="ref-for-step1②">step 1</a> must not be garbage collected if there are any event listeners registered for <code class="idl"><a data-link-type="idl" href="#eventdef-websocket-message" id="ref-for-eventdef-websocket-message③">message</a></code> events, <code class="idl"><a data-link-type="idl" href="#eventdef-websocket-error" id="ref-for-eventdef-websocket-error②">error</a></code>, or <code class="idl"><a data-link-type="idl" href="#eventdef-websocket-close" id="ref-for-eventdef-websocket-close⑧">close</a></code> events.</p> <p>A <code class="idl"><a data-link-type="idl" href="#websocket" id="ref-for-websocket①⑨">WebSocket</a></code> object whose <a data-link-type="dfn" href="#websocket-ready-state" id="ref-for-websocket-ready-state①③">ready state</a> was set to <code class="idl"><a data-link-type="idl" href="#dom-websocket-closing" id="ref-for-dom-websocket-closing⑦">CLOSING</a></code> (2) as of the last time the <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#event-loop" id="ref-for-event-loop③">event loop</a> reached <a data-link-type="dfn" href="https://html.spec.whatwg.org/multipage/webappapis.html#step1" id="ref-for-step1③">step 1</a> must not be garbage collected if there are any event listeners registered for <code class="idl"><a data-link-type="idl" href="#eventdef-websocket-error" id="ref-for-eventdef-websocket-error③">error</a></code> or <code class="idl"><a data-link-type="idl" href="#eventdef-websocket-close" id="ref-for-eventdef-websocket-close⑨">close</a></code> events.</p> <p>A <code class="idl"><a data-link-type="idl" href="#websocket" id="ref-for-websocket②⓪">WebSocket</a></code> object with <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and" id="ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and①③">an established connection</a> that has data queued to be transmitted to the network must not be garbage collected. <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a></p> <p>If a <code class="idl"><a data-link-type="idl" href="#websocket" id="ref-for-websocket②①">WebSocket</a></code> object is garbage collected while its connection is still open, the user agent must <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.2" id="ref-for-section-7.1.2③">start the WebSocket closing handshake</a>, with no status code for the Close message. <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a></p> <hr> <p>If a user agent is to <dfn class="dfn-paneled" data-dfn-type="dfn" data-export id="make-disappear">make disappear</dfn> a <code class="idl"><a data-link-type="idl" href="#websocket" id="ref-for-websocket②②">WebSocket</a></code> object (this happens when a <code class="idl"><a data-link-type="idl" href="https://dom.spec.whatwg.org/#document" id="ref-for-document">Document</a></code> object goes away), the user agent must follow the first appropriate set of steps from the following list:</p> <div class="algorithm" data-algorithm="to make disappear"> <dl class="switch"> <dt data-md>If the WebSocket connection is not yet <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and" id="ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and①④">established</a> <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a> <dd data-md> <p><a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.7" id="ref-for-section-7.1.7⑧">Fail the WebSocket connection</a>. <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a></p> <dt data-md>If the WebSocket closing handshake has not yet been <a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.3" id="ref-for-section-7.1.3⑦">started</a> <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a> <dd data-md> <p><a data-link-type="dfn" href="https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.2" id="ref-for-section-7.1.2④">Start the WebSocket closing handshake</a>, with the status code to use in the WebSocket Close message being 1001. <a data-link-type="biblio" href="#biblio-wsp" title="The WebSocket Protocol">[WSP]</a></p> <dt data-md>Otherwise <dd data-md> <p>Do nothing.</p> </dl> </div> <h2 class="no-num heading settled" id="acks"><span class="content">Acknowledgments</span><a class="self-link" href="#acks"></a></h2> <p>Until the creation of this standard in 2021, the text here was maintained in the <a href="https://html.spec.whatwg.org/multipage/">HTML Standard</a> and <a href="https://fetch.spec.whatwg.org/">Fetch Standard</a>. 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.</p> <p>Thanks to devsnek and 平野裕 (Yutaka Hirano) for their contributions after the creation of the WebSockets Standard.</p> <p>This standard is written by Adam Rice (<a href="https://google.com">Google</a>, <a href="mailto:ricea@chromium.org">ricea@chromium.org</a>).</p> <h2 class="no-num heading settled" id="ipr"><span class="content">Intellectual property rights</span><a class="self-link" href="#ipr"></a></h2> <p>Copyright © WHATWG (Apple, Google, Mozilla, Microsoft). This work is licensed under a <a href="https://creativecommons.org/licenses/by/4.0/" rel="license">Creative Commons Attribution 4.0 International License</a>. To the extent portions of it are incorporated into source code, such portions in the source code are licensed under the <a href="https://opensource.org/licenses/BSD-3-Clause" rel="license">BSD 3-Clause License</a> instead.</p> <p>This is the Living Standard. Those interested in the patent-review version should view the <a href="/review-drafts/2023-09/">Living Standard Review Draft</a>.</p> </main> <script> "use strict"; if ("serviceWorker" in navigator) { navigator.serviceWorker.register("/service-worker.js"); } </script> <h2 class="no-num no-ref heading settled" id="index"><span class="content">Index</span><a class="self-link" href="#index"></a></h2> <h3 class="no-num no-ref heading settled" id="index-defined-here"><span class="content">Terms defined by this specification</span><a class="self-link" href="#index-defined-here"></a></h3> <ul class="index"> <li><a href="#dom-binarytype-arraybuffer">"arraybuffer"</a><span>, in § 4</span> <li><a href="#websocket-binary-type">binary type</a><span>, in § 3.1</span> <li><a href="#enumdef-binarytype">BinaryType</a><span>, in § 3.1</span> <li><a href="#dom-websocket-binarytype">binaryType</a><span>, in § 3.1</span> <li><a href="#dom-binarytype-blob">"blob"</a><span>, in § 4</span> <li><a href="#dom-websocket-bufferedamount">bufferedAmount</a><span>, in § 3.1</span> <li><a href="#eventdef-websocket-close">close</a><span>, in § 4</span> <li><a href="#dom-websocket-close">close()</a><span>, in § 3.1</span> <li><a href="#dom-websocket-close">close(code)</a><span>, in § 3.1</span> <li><a href="#dom-websocket-close">close(code, reason)</a><span>, in § 3.1</span> <li><a href="#dom-websocket-closed">CLOSED</a><span>, in § 3.1</span> <li><a href="#closeevent">CloseEvent</a><span>, in § 6</span> <li><a href="#dictdef-closeeventinit">CloseEventInit</a><span>, in § 6</span> <li><a href="#dom-closeevent-closeevent">CloseEvent(type)</a><span>, in § 6</span> <li><a href="#dom-closeevent-closeevent">CloseEvent(type, eventInitDict)</a><span>, in § 6</span> <li><a href="#dom-websocket-closing">CLOSING</a><span>, in § 3.1</span> <li> code <ul> <li><a href="#dom-closeevent-code">attribute for CloseEvent</a><span>, in § 6</span> <li><a href="#dom-closeeventinit-code">dict-member for CloseEventInit</a><span>, in § 6</span> </ul> <li><a href="#dom-websocket-connecting">CONNECTING</a><span>, in § 3.1</span> <li><a href="#dom-closeevent-closeevent">constructor(type)</a><span>, in § 6</span> <li><a href="#dom-closeevent-closeevent">constructor(type, eventInitDict)</a><span>, in § 6</span> <li><a href="#dom-websocket-websocket">constructor(url)</a><span>, in § 3.1</span> <li><a href="#dom-websocket-websocket">constructor(url, protocols)</a><span>, in § 3.1</span> <li><a href="#eventdef-websocket-error">error</a><span>, in § 4</span> <li><a href="#concept-websocket-establish">establish a WebSocket connection</a><span>, in § 2.2</span> <li><a href="#dom-websocket-extensions">extensions</a><span>, in § 3.1</span> <li><a href="#flagged-as-full">flagged as full</a><span>, in § 4</span> <li><a href="#websocket-internal-url">internal-url</a><span>, in § 3.1</span> <li><a href="#make-disappear">make disappear</a><span>, in § 7</span> <li><a href="#eventdef-websocket-message">message</a><span>, in § 4</span> <li><a href="#concept-websocket-connection-obtain">obtain a WebSocket connection</a><span>, in § 2.1</span> <li><a href="#dom-websocket-onclose">onclose</a><span>, in § 3.1</span> <li><a href="#dom-websocket-onerror">onerror</a><span>, in § 3.1</span> <li><a href="#dom-websocket-onmessage">onmessage</a><span>, in § 3.1</span> <li><a href="#dom-websocket-onopen">onopen</a><span>, in § 3.1</span> <li><a href="#dom-websocket-open">OPEN</a><span>, in § 3.1</span> <li><a href="#eventdef-websocket-open">open</a><span>, in § 4</span> <li><a href="#dom-websocket-protocol">protocol</a><span>, in § 3.1</span> <li><a href="#websocket-ready-state">ready state</a><span>, in § 3.1</span> <li><a href="#dom-websocket-readystate">readyState</a><span>, in § 3.1</span> <li> reason <ul> <li><a href="#dom-closeevent-reason">attribute for CloseEvent</a><span>, in § 6</span> <li><a href="#dom-closeeventinit-reason">dict-member for CloseEventInit</a><span>, in § 6</span> </ul> <li><a href="#dom-websocket-send">send(data)</a><span>, in § 3.1</span> <li><a href="#dom-websocket-url">url</a><span>, in § 3.1</span> <li> wasClean <ul> <li><a href="#dom-closeevent-wasclean">attribute for CloseEvent</a><span>, in § 6</span> <li><a href="#dom-closeeventinit-wasclean">dict-member for CloseEventInit</a><span>, in § 6</span> </ul> <li><a href="#websocket">WebSocket</a><span>, in § 3.1</span> <li><a href="#websocket-task-source">WebSocket task source</a><span>, in § 4</span> <li><a href="#dom-websocket-websocket">WebSocket(url)</a><span>, in § 3.1</span> <li><a href="#dom-websocket-websocket">WebSocket(url, protocols)</a><span>, in § 3.1</span> </ul> <h3 class="no-num no-ref heading settled" id="index-defined-elsewhere"><span class="content">Terms defined by reference</span><a class="self-link" href="#index-defined-elsewhere"></a></h3> <ul class="index"> <li> <a data-link-type="biblio">[DOM]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="85394472">Document</span> <li><span class="dfn-paneled" id="129bdae8">Event</span> <li><span class="dfn-paneled" id="44a7708c">EventInit</span> <li><span class="dfn-paneled" id="2bc0cdf4">EventTarget</span> <li><span class="dfn-paneled" id="5fd23811">fire an event</span> </ul> <li> <a data-link-type="biblio">[ENCODING]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="a3033be5">utf-8 decode without bom</span> <li><span class="dfn-paneled" id="0303e8e5">utf-8 encode</span> </ul> <li> <a data-link-type="biblio">[FETCH]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="a6a8ec88">append</span> <li><span class="dfn-paneled" id="688f9669">cache mode</span> <li><span class="dfn-paneled" id="857d5516">client</span> <li><span class="dfn-paneled" id="0a52a8b4">combine</span> <li><span class="dfn-paneled" id="697965b2">connection</span> <li><span class="dfn-paneled" id="902380f7">credentials mode</span> <li><span class="dfn-paneled" id="3be1d4ac">extracting header list values</span> <li><span class="dfn-paneled" id="a33db89a">fetch</span> <li><span class="dfn-paneled" id="6ee0eab1">header list</span> <li><span class="dfn-paneled" id="c07f8014">header value</span> <li><span class="dfn-paneled" id="cb98f71f">mode</span> <li><span class="dfn-paneled" id="eb1b1af3">network error</span> <li><span class="dfn-paneled" id="bd2fe71e">processresponse</span> <li><span class="dfn-paneled" id="64b62ea0">redirect mode</span> <li><span class="dfn-paneled" id="358f1dbd">referrer</span> <li><span class="dfn-paneled" id="55213b5b">request</span> <li><span class="dfn-paneled" id="6d1db60d">service-workers mode</span> <li><span class="dfn-paneled" id="a1d47575">status</span> <li><span class="dfn-paneled" id="dc1cd39b">url</span> <li><span class="dfn-paneled" id="2c8ec3a8">useparallelqueue</span> </ul> <li> <a data-link-type="biblio">[FILEAPI]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="b7d73f5b">Blob</span> </ul> <li> <a data-link-type="biblio">[HTML]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="f0951476">EventHandler</span> <li><span class="dfn-paneled" id="3e8c0e5f">MessageEvent</span> <li><span class="dfn-paneled" id="1b5b1c0c">api base url</span> <li><span class="dfn-paneled" id="3700794f">data</span> <li><span class="dfn-paneled" id="6a5a59a0">event handler</span> <li><span class="dfn-paneled" id="9d386f55">event handler event type</span> <li><span class="dfn-paneled" id="03675365">event handler idl attribute</span> <li><span class="dfn-paneled" id="c6d19e56">event loop</span> <li><span class="dfn-paneled" id="a72449dd">in parallel</span> <li><span class="dfn-paneled" id="e0eefdd9">origin</span> <li><span class="dfn-paneled" id="9a517a7d">queue a task</span> <li><span class="dfn-paneled" id="5991ccfb">relevant realm</span> <li><span class="dfn-paneled" id="9c4c1e66">relevant settings object</span> <li><span class="dfn-paneled" id="683cb370">step 1</span> <li><span class="dfn-paneled" id="e270bd2a">task</span> <li><span class="dfn-paneled" id="80726755">task queues</span> <li><span class="dfn-paneled" id="c3b2d08c">task source</span> </ul> <li> <a data-link-type="biblio">[INFRA]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="b012ccb2">forgiving-base64 encode</span> <li><span class="dfn-paneled" id="16b1470a">isomorphic encode</span> </ul> <li> <a data-link-type="biblio">[URL]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="ed948033">fragment</span> <li><span class="dfn-paneled" id="b85ee3be">host</span> <li><span class="dfn-paneled" id="959ad97b">origin</span> <li><span class="dfn-paneled" id="c0868016">path</span> <li><span class="dfn-paneled" id="852ada56">port</span> <li><span class="dfn-paneled" id="3ab2ec8b">query</span> <li><span class="dfn-paneled" id="3a711be7">scheme</span> <li><span class="dfn-paneled" id="dcffbccd">url</span> <li><span class="dfn-paneled" id="ca3ca4ae">url parser</span> <li><span class="dfn-paneled" id="a8c7461b">url record</span> <li><span class="dfn-paneled" id="5442ea33">url serializer</span> </ul> <li> <a data-link-type="biblio">[WEBIDL]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="2f8afbfe">ArrayBuffer</span> <li><span class="dfn-paneled" id="6c9ab516">ArrayBufferView</span> <li><span class="dfn-paneled" id="3aff2fb3">BufferSource</span> <li><span class="dfn-paneled" id="f89c7d0d">Clamp</span> <li><span class="dfn-paneled" id="dca2de17">DOMException</span> <li><span class="dfn-paneled" id="8855a9aa">DOMString</span> <li><span class="dfn-paneled" id="889e932f">Exposed</span> <li><span class="dfn-paneled" id="37afd48d">InvalidAccessError</span> <li><span class="dfn-paneled" id="797018a7">InvalidStateError</span> <li><span class="dfn-paneled" id="be2d2b4c">SyntaxError</span> <li><span class="dfn-paneled" id="b0d7f3c3">USVString</span> <li><span class="dfn-paneled" id="5372cca8">boolean</span> <li><span class="dfn-paneled" id="9cce47fd">sequence</span> <li><span class="dfn-paneled" id="3b5f2424">the given value</span> <li><span class="dfn-paneled" id="4013a022">this</span> <li><span class="dfn-paneled" id="5f90bbfb">undefined</span> <li><span class="dfn-paneled" id="f14b47b8">unsigned long long</span> <li><span class="dfn-paneled" id="450958f7">unsigned short</span> </ul> <li> <a data-link-type="biblio">[WSP]</a> defines the following terms: <ul> <li><span class="dfn-paneled" id="1172cc05">a websocket message has been received</span> <li><span class="dfn-paneled" id="e746eb27">cleanly</span> <li><span class="dfn-paneled" id="ae698447">close the websocket connection</span> <li><span class="dfn-paneled" id="a7100bf9">established</span> <li><span class="dfn-paneled" id="cd622903">extensions in use</span> <li><span class="dfn-paneled" id="2bd00413">fail the websocket connection</span> <li><span class="dfn-paneled" id="28bb6bc9">sec-websocket-protocol</span> <li><span class="dfn-paneled" id="f9982e17">send a websocket message</span> <li><span class="dfn-paneled" id="a4fa4138">start the websocket closing handshake</span> <li><span class="dfn-paneled" id="7eb570ba">subprotocol in use</span> <li><span class="dfn-paneled" id="b75eba20">the websocket closing handshake is started</span> <li><span class="dfn-paneled" id="a37b7863">the websocket connection close code</span> <li><span class="dfn-paneled" id="a0841248">the websocket connection close reason</span> <li><span class="dfn-paneled" id="c9b060e8">the websocket connection is closed</span> <li><span class="dfn-paneled" id="4e3cd62b">the websocket connection is established</span> <li><span class="dfn-paneled" id="33680a76">ws</span> <li><span class="dfn-paneled" id="7d0af9ea">wss</span> </ul> </ul> <h2 class="no-num no-ref heading settled" id="references"><span class="content">References</span><a class="self-link" href="#references"></a></h2> <h3 class="no-num no-ref heading settled" id="normative"><span class="content">Normative References</span><a class="self-link" href="#normative"></a></h3> <dl> <dt id="biblio-dom">[DOM] <dd>Anne van Kesteren. <a href="https://dom.spec.whatwg.org/"><cite>DOM Standard</cite></a>. Living Standard. URL: <a href="https://dom.spec.whatwg.org/">https://dom.spec.whatwg.org/</a> <dt id="biblio-encoding">[ENCODING] <dd>Anne van Kesteren. <a href="https://encoding.spec.whatwg.org/"><cite>Encoding Standard</cite></a>. Living Standard. URL: <a href="https://encoding.spec.whatwg.org/">https://encoding.spec.whatwg.org/</a> <dt id="biblio-fetch">[FETCH] <dd>Anne van Kesteren. <a href="https://fetch.spec.whatwg.org/"><cite>Fetch Standard</cite></a>. Living Standard. URL: <a href="https://fetch.spec.whatwg.org/">https://fetch.spec.whatwg.org/</a> <dt id="biblio-fileapi">[FILEAPI] <dd>Marijn Kruisselbrink. <a href="https://w3c.github.io/FileAPI/"><cite>File API</cite></a>. URL: <a href="https://w3c.github.io/FileAPI/">https://w3c.github.io/FileAPI/</a> <dt id="biblio-hsts">[HSTS] <dd>J. Hodges; C. Jackson; A. Barth. <a href="https://www.rfc-editor.org/rfc/rfc6797"><cite>HTTP Strict Transport Security (HSTS)</cite></a>. November 2012. Proposed Standard. URL: <a href="https://www.rfc-editor.org/rfc/rfc6797">https://www.rfc-editor.org/rfc/rfc6797</a> <dt id="biblio-html">[HTML] <dd>Anne van Kesteren; et al. <a href="https://html.spec.whatwg.org/multipage/"><cite>HTML Standard</cite></a>. Living Standard. URL: <a href="https://html.spec.whatwg.org/multipage/">https://html.spec.whatwg.org/multipage/</a> <dt id="biblio-infra">[INFRA] <dd>Anne van Kesteren; Domenic Denicola. <a href="https://infra.spec.whatwg.org/"><cite>Infra Standard</cite></a>. Living Standard. URL: <a href="https://infra.spec.whatwg.org/">https://infra.spec.whatwg.org/</a> <dt id="biblio-unicode">[UNICODE] <dd><a href="https://www.unicode.org/versions/latest/"><cite>The Unicode Standard</cite></a>. URL: <a href="https://www.unicode.org/versions/latest/">https://www.unicode.org/versions/latest/</a> <dt id="biblio-url">[URL] <dd>Anne van Kesteren. <a href="https://url.spec.whatwg.org/"><cite>URL Standard</cite></a>. Living Standard. URL: <a href="https://url.spec.whatwg.org/">https://url.spec.whatwg.org/</a> <dt id="biblio-webidl">[WEBIDL] <dd>Edgar Chen; Timothy Gu. <a href="https://webidl.spec.whatwg.org/"><cite>Web IDL Standard</cite></a>. Living Standard. URL: <a href="https://webidl.spec.whatwg.org/">https://webidl.spec.whatwg.org/</a> <dt id="biblio-wsp">[WSP] <dd>I. Fette; A. Melnikov. <a href="https://www.rfc-editor.org/rfc/rfc6455"><cite>The WebSocket Protocol</cite></a>. December 2011. Proposed Standard. URL: <a href="https://www.rfc-editor.org/rfc/rfc6455">https://www.rfc-editor.org/rfc/rfc6455</a> </dl> <h2 class="no-num no-ref heading settled" id="idl-index"><span class="content">IDL Index</span><a class="self-link" href="#idl-index"></a></h2> <pre class="idl highlight def"><c- b>enum</c-> <a href="#enumdef-binarytype"><code><c- g>BinaryType</c-></code></a> { <a class="idl-code" data-link-type="enum-value" href="#dom-binarytype-blob"><c- s>"blob"</c-></a>, <a class="idl-code" data-link-type="enum-value" href="#dom-binarytype-arraybuffer"><c- s>"arraybuffer"</c-></a> }; [<a class="idl-code" data-link-type="extended-attribute" href="https://webidl.spec.whatwg.org/#Exposed"><c- g>Exposed</c-></a>=(<c- n>Window</c->,<c- n>Worker</c->)] <c- b>interface</c-> <a href="#websocket"><code><c- g>WebSocket</c-></code></a> : <a data-link-type="idl-name" href="https://dom.spec.whatwg.org/#eventtarget"><c- n>EventTarget</c-></a> { <a class="idl-code" data-link-type="constructor" href="#dom-websocket-websocket"><c- g>constructor</c-></a>(<a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-USVString"><c- b>USVString</c-></a> <a href="#dom-websocket-websocket-url-protocols-url"><code><c- g>url</c-></code></a>, <c- b>optional</c-> (<a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString"><c- b>DOMString</c-></a> <c- b>or</c-> <a data-link-type="dfn" href="https://webidl.spec.whatwg.org/#idl-sequence"><c- b>sequence</c-></a>&lt;<a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString"><c- b>DOMString</c-></a>>) <a href="#dom-websocket-websocket-url-protocols-protocols"><code><c- g>protocols</c-></code></a> = []); <c- b>readonly</c-> <c- b>attribute</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-USVString"><c- b>USVString</c-></a> <a class="idl-code" data-link-type="attribute" data-readonly data-type="USVString" href="#dom-websocket-url"><c- g>url</c-></a>; // ready state <c- b>const</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-unsigned-short"><c- b>unsigned</c-> <c- b>short</c-></a> <a class="idl-code" data-link-type="const" href="#dom-websocket-connecting"><c- g>CONNECTING</c-></a> = 0; <c- b>const</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-unsigned-short"><c- b>unsigned</c-> <c- b>short</c-></a> <a class="idl-code" data-link-type="const" href="#dom-websocket-open"><c- g>OPEN</c-></a> = 1; <c- b>const</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-unsigned-short"><c- b>unsigned</c-> <c- b>short</c-></a> <a class="idl-code" data-link-type="const" href="#dom-websocket-closing"><c- g>CLOSING</c-></a> = 2; <c- b>const</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-unsigned-short"><c- b>unsigned</c-> <c- b>short</c-></a> <a class="idl-code" data-link-type="const" href="#dom-websocket-closed"><c- g>CLOSED</c-></a> = 3; <c- b>readonly</c-> <c- b>attribute</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-unsigned-short"><c- b>unsigned</c-> <c- b>short</c-></a> <a class="idl-code" data-link-type="attribute" data-readonly data-type="unsigned short" href="#dom-websocket-readystate"><c- g>readyState</c-></a>; <c- b>readonly</c-> <c- b>attribute</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-unsigned-long-long"><c- b>unsigned</c-> <c- b>long</c-> <c- b>long</c-></a> <a class="idl-code" data-link-type="attribute" data-readonly data-type="unsigned long long" href="#dom-websocket-bufferedamount"><c- g>bufferedAmount</c-></a>; // networking <c- b>attribute</c-> <a data-link-type="idl-name" href="https://html.spec.whatwg.org/multipage/webappapis.html#eventhandler"><c- n>EventHandler</c-></a> <a class="idl-code" data-link-type="attribute" data-type="EventHandler" href="#dom-websocket-onopen"><c- g>onopen</c-></a>; <c- b>attribute</c-> <a data-link-type="idl-name" href="https://html.spec.whatwg.org/multipage/webappapis.html#eventhandler"><c- n>EventHandler</c-></a> <a class="idl-code" data-link-type="attribute" data-type="EventHandler" href="#dom-websocket-onerror"><c- g>onerror</c-></a>; <c- b>attribute</c-> <a data-link-type="idl-name" href="https://html.spec.whatwg.org/multipage/webappapis.html#eventhandler"><c- n>EventHandler</c-></a> <a class="idl-code" data-link-type="attribute" data-type="EventHandler" href="#dom-websocket-onclose"><c- g>onclose</c-></a>; <c- b>readonly</c-> <c- b>attribute</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString"><c- b>DOMString</c-></a> <a class="idl-code" data-link-type="attribute" data-readonly data-type="DOMString" href="#dom-websocket-extensions"><c- g>extensions</c-></a>; <c- b>readonly</c-> <c- b>attribute</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString"><c- b>DOMString</c-></a> <a class="idl-code" data-link-type="attribute" data-readonly data-type="DOMString" href="#dom-websocket-protocol"><c- g>protocol</c-></a>; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-undefined"><c- b>undefined</c-></a> <a class="idl-code" data-link-type="method" href="#dom-websocket-close"><c- g>close</c-></a>(<c- b>optional</c-> [<a class="idl-code" data-link-type="extended-attribute" href="https://webidl.spec.whatwg.org/#Clamp"><c- g>Clamp</c-></a>] <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-unsigned-short"><c- b>unsigned</c-> <c- b>short</c-></a> <a href="#dom-websocket-close-code-reason-code"><code><c- g>code</c-></code></a>, <c- b>optional</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-USVString"><c- b>USVString</c-></a> <a href="#dom-websocket-close-code-reason-reason"><code><c- g>reason</c-></code></a>); // messaging <c- b>attribute</c-> <a data-link-type="idl-name" href="https://html.spec.whatwg.org/multipage/webappapis.html#eventhandler"><c- n>EventHandler</c-></a> <a class="idl-code" data-link-type="attribute" data-type="EventHandler" href="#dom-websocket-onmessage"><c- g>onmessage</c-></a>; <c- b>attribute</c-> <a data-link-type="idl-name" href="#enumdef-binarytype"><c- n>BinaryType</c-></a> <a class="idl-code" data-link-type="attribute" data-type="BinaryType" href="#dom-websocket-binarytype"><c- g>binaryType</c-></a>; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-undefined"><c- b>undefined</c-></a> <a class="idl-code" data-link-type="method" href="#dom-websocket-send"><c- g>send</c-></a>((<a data-link-type="idl-name" href="https://webidl.spec.whatwg.org/#BufferSource"><c- n>BufferSource</c-></a> <c- b>or</c-> <a data-link-type="idl-name" href="https://w3c.github.io/FileAPI/#dfn-Blob"><c- n>Blob</c-></a> <c- b>or</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-USVString"><c- b>USVString</c-></a>) <a href="#dom-websocket-send-data-data"><code><c- g>data</c-></code></a>); }; [<a class="idl-code" data-link-type="extended-attribute" href="https://webidl.spec.whatwg.org/#Exposed"><c- g>Exposed</c-></a>=(<c- n>Window</c->,<c- n>Worker</c->)] <c- b>interface</c-> <a href="#closeevent"><code><c- g>CloseEvent</c-></code></a> : <a data-link-type="idl-name" href="https://dom.spec.whatwg.org/#event"><c- n>Event</c-></a> { <a href="#dom-closeevent-closeevent"><code><c- g>constructor</c-></code></a>(<a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-DOMString"><c- b>DOMString</c-></a> <a href="#dom-closeevent-closeevent-type-eventinitdict-type"><code><c- g>type</c-></code></a>, <c- b>optional</c-> <a data-link-type="idl-name" href="#dictdef-closeeventinit"><c- n>CloseEventInit</c-></a> <a href="#dom-closeevent-closeevent-type-eventinitdict-eventinitdict"><code><c- g>eventInitDict</c-></code></a> = {}); <c- b>readonly</c-> <c- b>attribute</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-boolean"><c- b>boolean</c-></a> <a class="idl-code" data-link-type="attribute" data-readonly data-type="boolean" href="#dom-closeevent-wasclean"><c- g>wasClean</c-></a>; <c- b>readonly</c-> <c- b>attribute</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-unsigned-short"><c- b>unsigned</c-> <c- b>short</c-></a> <a class="idl-code" data-link-type="attribute" data-readonly data-type="unsigned short" href="#dom-closeevent-code"><c- g>code</c-></a>; <c- b>readonly</c-> <c- b>attribute</c-> <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-USVString"><c- b>USVString</c-></a> <a class="idl-code" data-link-type="attribute" data-readonly data-type="USVString" href="#dom-closeevent-reason"><c- g>reason</c-></a>; }; <c- b>dictionary</c-> <a href="#dictdef-closeeventinit"><code><c- g>CloseEventInit</c-></code></a> : <a data-link-type="idl-name" href="https://dom.spec.whatwg.org/#dictdef-eventinit"><c- n>EventInit</c-></a> { <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-boolean"><c- b>boolean</c-></a> <a data-default="false" data-type="boolean " href="#dom-closeeventinit-wasclean"><code><c- g>wasClean</c-></code></a> = <c- b>false</c->; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-unsigned-short"><c- b>unsigned</c-> <c- b>short</c-></a> <a data-default="0" data-type="unsigned short " href="#dom-closeeventinit-code"><code><c- g>code</c-></code></a> = 0; <a class="idl-code" data-link-type="interface" href="https://webidl.spec.whatwg.org/#idl-USVString"><c- b>USVString</c-></a> <a data-default="&quot;&quot;" data-type="USVString " href="#dom-closeeventinit-reason"><code><c- g>reason</c-></code></a> = ""; }; </pre> <details class="mdn-anno unpositioned" data-anno-for="dom-closeevent-closeevent"> <summary><b class="all-engines-flag" title="This feature is in all current engines.">✔</b><span>MDN</span></summary> <div class="feature"> <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/CloseEvent" title="The CloseEvent() constructor creates a new CloseEvent object.">CloseEvent/CloseEvent</a></p> <p class="all-engines-text">In all current engines.</p> <div class="support"> <span class="firefox yes"><span>Firefox</span><span>11+</span></span><span class="safari yes"><span>Safari</span><span>6+</span></span><span class="chrome yes"><span>Chrome</span><span>16+</span></span> <hr> <span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span> <hr> <span class="edge yes"><span>Edge (Legacy)</span><span>14+</span></span><span class="ie no"><span>IE</span><span>None</span></span> <hr> <span class="firefox_android no"><span>Firefox for Android</span><span>?</span></span><span class="safari_ios no"><span>iOS Safari</span><span>?</span></span><span class="chrome_android no"><span>Chrome for Android</span><span>?</span></span><span class="webview_android no"><span>Android WebView</span><span>?</span></span><span class="samsunginternet_android no"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Mobile</span><span>12.1+</span></span> </div> </div> </details> <details class="mdn-anno unpositioned" data-anno-for="ref-for-dom-closeevent-code②"> <summary><b class="all-engines-flag" title="This feature is in all current engines.">✔</b><span>MDN</span></summary> <div class="feature"> <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/code" title="The code read-only property of the CloseEvent interface returns a WebSocket connection close code indicating the reason the server gave for closing the connection.">CloseEvent/code</a></p> <p class="all-engines-text">In all current engines.</p> <div class="support"> <span class="firefox yes"><span>Firefox</span><span>8+</span></span><span class="safari yes"><span>Safari</span><span>6+</span></span><span class="chrome yes"><span>Chrome</span><span>15+</span></span> <hr> <span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span> <hr> <span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>IE</span><span>10+</span></span> <hr> <span class="firefox_android no"><span>Firefox for Android</span><span>?</span></span><span class="safari_ios no"><span>iOS Safari</span><span>?</span></span><span class="chrome_android no"><span>Chrome for Android</span><span>?</span></span><span class="webview_android no"><span>Android WebView</span><span>?</span></span><span class="samsunginternet_android no"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Mobile</span><span>12.1+</span></span> </div> </div> </details> <details class="mdn-anno unpositioned" data-anno-for="ref-for-dom-closeevent-reason②"> <summary><b class="all-engines-flag" title="This feature is in all current engines.">✔</b><span>MDN</span></summary> <div class="feature"> <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/reason" title="The reason read-only property of the CloseEvent interface returns the WebSocket connection close reason the server gave for closing the connection; that is, a concise human-readable prose explanation for the closure.">CloseEvent/reason</a></p> <p class="all-engines-text">In all current engines.</p> <div class="support"> <span class="firefox yes"><span>Firefox</span><span>8+</span></span><span class="safari yes"><span>Safari</span><span>6+</span></span><span class="chrome yes"><span>Chrome</span><span>15+</span></span> <hr> <span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span> <hr> <span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>IE</span><span>10+</span></span> <hr> <span class="firefox_android no"><span>Firefox for Android</span><span>?</span></span><span class="safari_ios no"><span>iOS Safari</span><span>?</span></span><span class="chrome_android no"><span>Chrome for Android</span><span>?</span></span><span class="webview_android no"><span>Android WebView</span><span>?</span></span><span class="samsunginternet_android no"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Mobile</span><span>12.1+</span></span> </div> </div> </details> <details class="mdn-anno unpositioned" data-anno-for="ref-for-dom-closeevent-wasclean②"> <summary><b class="all-engines-flag" title="This feature is in all current engines.">✔</b><span>MDN</span></summary> <div class="feature"> <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/wasClean" title="The wasClean read-only property of the CloseEvent interface returns true if the connection closed cleanly.">CloseEvent/wasClean</a></p> <p class="all-engines-text">In all current engines.</p> <div class="support"> <span class="firefox yes"><span>Firefox</span><span>8+</span></span><span class="safari yes"><span>Safari</span><span>6+</span></span><span class="chrome yes"><span>Chrome</span><span>15+</span></span> <hr> <span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span> <hr> <span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>IE</span><span>10+</span></span> <hr> <span class="firefox_android no"><span>Firefox for Android</span><span>?</span></span><span class="safari_ios no"><span>iOS Safari</span><span>?</span></span><span class="chrome_android no"><span>Chrome for Android</span><span>?</span></span><span class="webview_android no"><span>Android WebView</span><span>?</span></span><span class="samsunginternet_android no"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Mobile</span><span>12.1+</span></span> </div> </div> </details> <details class="mdn-anno unpositioned" data-anno-for="the-closeevent-interface"> <summary><b class="all-engines-flag" title="This feature is in all current engines.">✔</b><span>MDN</span></summary> <div class="feature"> <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent" title="A CloseEvent is sent to clients using WebSockets when the connection is closed. This is delivered to the listener indicated by the WebSocket object&apos;s onclose attribute.">CloseEvent</a></p> <p class="all-engines-text">In all current engines.</p> <div class="support"> <span class="firefox yes"><span>Firefox</span><span>8+</span></span><span class="safari yes"><span>Safari</span><span>6+</span></span><span class="chrome yes"><span>Chrome</span><span>15+</span></span> <hr> <span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span> <hr> <span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>IE</span><span>10+</span></span> <hr> <span class="firefox_android yes"><span>Firefox for Android</span><span>8+</span></span><span class="safari_ios no"><span>iOS Safari</span><span>?</span></span><span class="chrome_android no"><span>Chrome for Android</span><span>?</span></span><span class="webview_android no"><span>Android WebView</span><span>?</span></span><span class="samsunginternet_android no"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Mobile</span><span>12.1+</span></span> </div> </div> </details> <details class="mdn-anno unpositioned" data-anno-for="ref-for-dom-websocket-websocket①"> <summary><b class="all-engines-flag" title="This feature is in all current engines.">✔</b><span>MDN</span></summary> <div class="feature"> <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/WebSocket" title="The WebSocket() constructor returns a new WebSocket object.">WebSocket/WebSocket</a></p> <p class="all-engines-text">In all current engines.</p> <div class="support"> <span class="firefox yes"><span>Firefox</span><span>11+</span></span><span class="safari yes"><span>Safari</span><span>5+</span></span><span class="chrome yes"><span>Chrome</span><span>5+</span></span> <hr> <span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span> <hr> <span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>IE</span><span>10+</span></span> <hr> <span class="firefox_android no"><span>Firefox for Android</span><span>?</span></span><span class="safari_ios no"><span>iOS Safari</span><span>?</span></span><span class="chrome_android no"><span>Chrome for Android</span><span>?</span></span><span class="webview_android no"><span>Android WebView</span><span>?</span></span><span class="samsunginternet_android no"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Mobile</span><span>12.1+</span></span> </div> </div> </details> <details class="mdn-anno unpositioned" data-anno-for="ref-for-dom-websocket-binarytype①"> <summary><b class="all-engines-flag" title="This feature is in all current engines.">✔</b><span>MDN</span></summary> <div class="feature"> <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/binaryType" title="The WebSocket.binaryType property controls the type of binary data being received over the WebSocket connection.">WebSocket/binaryType</a></p> <p class="all-engines-text">In all current engines.</p> <div class="support"> <span class="firefox yes"><span>Firefox</span><span>11+</span></span><span class="safari yes"><span>Safari</span><span>6+</span></span><span class="chrome yes"><span>Chrome</span><span>15+</span></span> <hr> <span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span> <hr> <span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>IE</span><span>10+</span></span> <hr> <span class="firefox_android no"><span>Firefox for Android</span><span>?</span></span><span class="safari_ios no"><span>iOS Safari</span><span>?</span></span><span class="chrome_android no"><span>Chrome for Android</span><span>?</span></span><span class="webview_android no"><span>Android WebView</span><span>?</span></span><span class="samsunginternet_android no"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Mobile</span><span>12.1+</span></span> </div> </div> </details> <details class="mdn-anno unpositioned" data-anno-for="ref-for-dom-websocket-bufferedamount①"> <summary><b class="all-engines-flag" title="This feature is in all current engines.">✔</b><span>MDN</span></summary> <div class="feature"> <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/bufferedAmount" title="The WebSocket.bufferedAmount read-only property returns the number of bytes of data that have been queued using calls to send() but not yet transmitted to the network. This value resets to zero once all queued data has been sent. This value does not reset to zero when the connection is closed; if you keep calling send(), this will continue to climb.">WebSocket/bufferedAmount</a></p> <p class="all-engines-text">In all current engines.</p> <div class="support"> <span class="firefox yes"><span>Firefox</span><span>7+</span></span><span class="safari yes"><span>Safari</span><span>5+</span></span><span class="chrome yes"><span>Chrome</span><span>5+</span></span> <hr> <span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span> <hr> <span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>IE</span><span>10+</span></span> <hr> <span class="firefox_android no"><span>Firefox for Android</span><span>?</span></span><span class="safari_ios no"><span>iOS Safari</span><span>?</span></span><span class="chrome_android no"><span>Chrome for Android</span><span>?</span></span><span class="webview_android no"><span>Android WebView</span><span>?</span></span><span class="samsunginternet_android no"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Mobile</span><span>12.1+</span></span> </div> </div> </details> <details class="mdn-anno unpositioned" data-anno-for="ref-for-dom-websocket-close①"> <summary><b class="all-engines-flag" title="This feature is in all current engines.">✔</b><span>MDN</span></summary> <div class="feature"> <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close" title="The WebSocket.close() method closes the WebSocket connection or connection attempt, if any. If the connection is already CLOSED, this method does nothing.">WebSocket/close</a></p> <p class="all-engines-text">In all current engines.</p> <div class="support"> <span class="firefox yes"><span>Firefox</span><span>7+</span></span><span class="safari yes"><span>Safari</span><span>5+</span></span><span class="chrome yes"><span>Chrome</span><span>5+</span></span> <hr> <span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span> <hr> <span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>IE</span><span>10+</span></span> <hr> <span class="firefox_android no"><span>Firefox for Android</span><span>?</span></span><span class="safari_ios no"><span>iOS Safari</span><span>?</span></span><span class="chrome_android no"><span>Chrome for Android</span><span>?</span></span><span class="webview_android no"><span>Android WebView</span><span>?</span></span><span class="samsunginternet_android no"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Mobile</span><span>12.1+</span></span> </div> </div> </details> <details class="mdn-anno unpositioned" data-anno-for="dom-websocket-onclose"> <summary><b class="all-engines-flag" title="This feature is in all current engines.">✔</b><span>MDN</span></summary> <div class="feature"> <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close_event" title="The close event is fired when a connection with a WebSocket is closed.">WebSocket/close_event</a></p> <p class="all-engines-text">In all current engines.</p> <div class="support"> <span class="firefox yes"><span>Firefox</span><span>7+</span></span><span class="safari yes"><span>Safari</span><span>5+</span></span><span class="chrome yes"><span>Chrome</span><span>5+</span></span> <hr> <span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span> <hr> <span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>IE</span><span>10+</span></span> <hr> <span class="firefox_android no"><span>Firefox for Android</span><span>?</span></span><span class="safari_ios no"><span>iOS Safari</span><span>?</span></span><span class="chrome_android no"><span>Chrome for Android</span><span>?</span></span><span class="webview_android yes"><span>Android WebView</span><span>37+</span></span><span class="samsunginternet_android no"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Mobile</span><span>12.1+</span></span> </div> </div> </details> <details class="mdn-anno unpositioned" data-anno-for="dom-websocket-onerror"> <summary><b class="all-engines-flag" title="This feature is in all current engines.">✔</b><span>MDN</span></summary> <div class="feature"> <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/error_event" title="The error event is fired when a connection with a WebSocket has been closed due to an error (some data couldn&apos;t be sent for example).">WebSocket/error_event</a></p> <p class="all-engines-text">In all current engines.</p> <div class="support"> <span class="firefox yes"><span>Firefox</span><span>7+</span></span><span class="safari yes"><span>Safari</span><span>5+</span></span><span class="chrome yes"><span>Chrome</span><span>5+</span></span> <hr> <span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span> <hr> <span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>IE</span><span>10+</span></span> <hr> <span class="firefox_android no"><span>Firefox for Android</span><span>?</span></span><span class="safari_ios no"><span>iOS Safari</span><span>?</span></span><span class="chrome_android no"><span>Chrome for Android</span><span>?</span></span><span class="webview_android yes"><span>Android WebView</span><span>37+</span></span><span class="samsunginternet_android no"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Mobile</span><span>12.1+</span></span> </div> </div> </details> <details class="mdn-anno unpositioned" data-anno-for="ref-for-dom-websocket-extensions①"> <summary><b class="all-engines-flag" title="This feature is in all current engines.">✔</b><span>MDN</span></summary> <div class="feature"> <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/extensions" title="The WebSocket.extensions read-only property returns the extensions selected by the server. This is currently only the empty string or a list of extensions as negotiated by the connection.">WebSocket/extensions</a></p> <p class="all-engines-text">In all current engines.</p> <div class="support"> <span class="firefox yes"><span>Firefox</span><span>8+</span></span><span class="safari yes"><span>Safari</span><span>6+</span></span><span class="chrome yes"><span>Chrome</span><span>16+</span></span> <hr> <span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span> <hr> <span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>IE</span><span>10+</span></span> <hr> <span class="firefox_android no"><span>Firefox for Android</span><span>?</span></span><span class="safari_ios no"><span>iOS Safari</span><span>?</span></span><span class="chrome_android no"><span>Chrome for Android</span><span>?</span></span><span class="webview_android no"><span>Android WebView</span><span>?</span></span><span class="samsunginternet_android no"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Mobile</span><span>12.1+</span></span> </div> </div> </details> <details class="mdn-anno unpositioned" data-anno-for="dom-websocket-onmessage"> <summary><b class="all-engines-flag" title="This feature is in all current engines.">✔</b><span>MDN</span></summary> <div class="feature"> <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/message_event" title="The message event is fired when data is received through a WebSocket.">WebSocket/message_event</a></p> <p class="all-engines-text">In all current engines.</p> <div class="support"> <span class="firefox yes"><span>Firefox</span><span>7+</span></span><span class="safari yes"><span>Safari</span><span>5+</span></span><span class="chrome yes"><span>Chrome</span><span>5+</span></span> <hr> <span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span> <hr> <span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>IE</span><span>10+</span></span> <hr> <span class="firefox_android no"><span>Firefox for Android</span><span>?</span></span><span class="safari_ios no"><span>iOS Safari</span><span>?</span></span><span class="chrome_android no"><span>Chrome for Android</span><span>?</span></span><span class="webview_android yes"><span>Android WebView</span><span>37+</span></span><span class="samsunginternet_android no"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Mobile</span><span>12.1+</span></span> </div> </div> </details> <details class="mdn-anno unpositioned" data-anno-for="dom-websocket-onopen"> <summary><b class="all-engines-flag" title="This feature is in all current engines.">✔</b><span>MDN</span></summary> <div class="feature"> <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/open_event" title="The open event is fired when a connection with a WebSocket is opened.">WebSocket/open_event</a></p> <p class="all-engines-text">In all current engines.</p> <div class="support"> <span class="firefox yes"><span>Firefox</span><span>7+</span></span><span class="safari yes"><span>Safari</span><span>5+</span></span><span class="chrome yes"><span>Chrome</span><span>5+</span></span> <hr> <span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span> <hr> <span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>IE</span><span>10+</span></span> <hr> <span class="firefox_android no"><span>Firefox for Android</span><span>?</span></span><span class="safari_ios no"><span>iOS Safari</span><span>?</span></span><span class="chrome_android no"><span>Chrome for Android</span><span>?</span></span><span class="webview_android yes"><span>Android WebView</span><span>37+</span></span><span class="samsunginternet_android no"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Mobile</span><span>12.1+</span></span> </div> </div> </details> <details class="mdn-anno unpositioned" data-anno-for="ref-for-dom-websocket-protocol①"> <summary><b class="all-engines-flag" title="This feature is in all current engines.">✔</b><span>MDN</span></summary> <div class="feature"> <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/protocol" title="The WebSocket.protocol read-only property returns the name of the sub-protocol the server selected; this will be one of the strings specified in the protocols parameter when creating the WebSocket object, or the empty string if no connection is established.">WebSocket/protocol</a></p> <p class="all-engines-text">In all current engines.</p> <div class="support"> <span class="firefox yes"><span>Firefox</span><span>7+</span></span><span class="safari yes"><span>Safari</span><span>6+</span></span><span class="chrome yes"><span>Chrome</span><span>15+</span></span> <hr> <span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span> <hr> <span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie no"><span>IE</span><span>None</span></span> <hr> <span class="firefox_android no"><span>Firefox for Android</span><span>?</span></span><span class="safari_ios no"><span>iOS Safari</span><span>?</span></span><span class="chrome_android no"><span>Chrome for Android</span><span>?</span></span><span class="webview_android no"><span>Android WebView</span><span>?</span></span><span class="samsunginternet_android no"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Mobile</span><span>12.1+</span></span> </div> </div> </details> <details class="mdn-anno unpositioned" data-anno-for="ref-for-dom-websocket-readystate①"> <summary><b class="all-engines-flag" title="This feature is in all current engines.">✔</b><span>MDN</span></summary> <div class="feature"> <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/readyState" title="The WebSocket.readyState read-only property returns the current state of the WebSocket connection.">WebSocket/readyState</a></p> <p class="all-engines-text">In all current engines.</p> <div class="support"> <span class="firefox yes"><span>Firefox</span><span>7+</span></span><span class="safari yes"><span>Safari</span><span>5+</span></span><span class="chrome yes"><span>Chrome</span><span>5+</span></span> <hr> <span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span> <hr> <span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>IE</span><span>10+</span></span> <hr> <span class="firefox_android no"><span>Firefox for Android</span><span>?</span></span><span class="safari_ios no"><span>iOS Safari</span><span>?</span></span><span class="chrome_android no"><span>Chrome for Android</span><span>?</span></span><span class="webview_android no"><span>Android WebView</span><span>?</span></span><span class="samsunginternet_android no"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Mobile</span><span>12.1+</span></span> </div> </div> </details> <details class="mdn-anno unpositioned" data-anno-for="ref-for-dom-websocket-send①"> <summary><b class="all-engines-flag" title="This feature is in all current engines.">✔</b><span>MDN</span></summary> <div class="feature"> <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send" title="The WebSocket.send() method enqueues the specified data to be transmitted to the server over the WebSocket connection, increasing the value of bufferedAmount by the number of bytes needed to contain the data. If the data can&apos;t be sent (for example, because it needs to be buffered but the buffer is full), the socket is closed automatically. The browser will throw an exception if you call send() when the connection is in the CONNECTING state. If you call send() when the connection is in the CLOSING or CLOSED states, the browser will silently discard the data.">WebSocket/send</a></p> <p class="all-engines-text">In all current engines.</p> <div class="support"> <span class="firefox yes"><span>Firefox</span><span>18+</span></span><span class="safari yes"><span>Safari</span><span>5+</span></span><span class="chrome yes"><span>Chrome</span><span>5+</span></span> <hr> <span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span> <hr> <span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>IE</span><span>10+</span></span> <hr> <span class="firefox_android no"><span>Firefox for Android</span><span>?</span></span><span class="safari_ios no"><span>iOS Safari</span><span>?</span></span><span class="chrome_android no"><span>Chrome for Android</span><span>?</span></span><span class="webview_android no"><span>Android WebView</span><span>?</span></span><span class="samsunginternet_android no"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Mobile</span><span>12.1+</span></span> </div> </div> </details> <details class="mdn-anno unpositioned" data-anno-for="ref-for-dom-websocket-url①"> <summary><b class="all-engines-flag" title="This feature is in all current engines.">✔</b><span>MDN</span></summary> <div class="feature"> <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/url" title="The WebSocket.url read-only property returns the absolute URL of the WebSocket as resolved by the constructor.">WebSocket/url</a></p> <p class="all-engines-text">In all current engines.</p> <div class="support"> <span class="firefox yes"><span>Firefox</span><span>7+</span></span><span class="safari yes"><span>Safari</span><span>6+</span></span><span class="chrome yes"><span>Chrome</span><span>18+</span></span> <hr> <span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span> <hr> <span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie no"><span>IE</span><span>None</span></span> <hr> <span class="firefox_android no"><span>Firefox for Android</span><span>?</span></span><span class="safari_ios no"><span>iOS Safari</span><span>?</span></span><span class="chrome_android no"><span>Chrome for Android</span><span>?</span></span><span class="webview_android no"><span>Android WebView</span><span>?</span></span><span class="samsunginternet_android no"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Mobile</span><span>12.1+</span></span> </div> </div> </details> <details class="mdn-anno unpositioned" data-anno-for="the-websocket-interface"> <summary><b class="all-engines-flag" title="This feature is in all current engines.">✔</b><span>MDN</span></summary> <div class="feature"> <p><a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSocket" title="The WebSocket object provides the API for creating and managing a WebSocket connection to a server, as well as for sending and receiving data on the connection.">WebSocket</a></p> <p class="all-engines-text">In all current engines.</p> <div class="support"> <span class="firefox yes"><span>Firefox</span><span>11+</span></span><span class="safari yes"><span>Safari</span><span>5+</span></span><span class="chrome yes"><span>Chrome</span><span>5+</span></span> <hr> <span class="opera yes"><span>Opera</span><span>12.1+</span></span><span class="edge_blink yes"><span>Edge</span><span>79+</span></span> <hr> <span class="edge yes"><span>Edge (Legacy)</span><span>12+</span></span><span class="ie yes"><span>IE</span><span>10+</span></span> <hr> <span class="firefox_android no"><span>Firefox for Android</span><span>?</span></span><span class="safari_ios no"><span>iOS Safari</span><span>?</span></span><span class="chrome_android no"><span>Chrome for Android</span><span>?</span></span><span class="webview_android no"><span>Android WebView</span><span>?</span></span><span class="samsunginternet_android no"><span>Samsung Internet</span><span>?</span></span><span class="opera_android yes"><span>Opera Mobile</span><span>12.1+</span></span> </div> </div> </details> <script>/* Boilerplate: script-dom-helper */ "use strict"; function query(sel) { return document.querySelector(sel); } function queryAll(sel) { return [...document.querySelectorAll(sel)]; } function iter(obj) { if(!obj) return []; var it = obj[Symbol.iterator]; if(it) return it; return Object.entries(obj); } function mk(tagname, attrs, ...children) { const el = document.createElement(tagname); for(const [k,v] of iter(attrs)) { if(k.slice(0,3) == "_on") { const eventName = k.slice(3); el.addEventListener(eventName, v); } else if(k[0] == "_") { // property, not attribute el[k.slice(1)] = v; } else { if(v === false || v == null) { continue; } else if(v === true) { el.setAttribute(k, ""); continue; } else { el.setAttribute(k, v); } } } append(el, children); return el; } /* Create shortcuts for every known HTML element */ [ "a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio", "b", "base", "basefont", "bdo", "big", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "datalist", "dd", "del", "details", "dfn", "dialog", "div", "dl", "dt", "em", "embed", "fieldset", "figcaption", "figure", "font", "footer", "form", "frame", "frameset", "head", "header", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "html", "i", "iframe", "img", "input", "ins", "kbd", "label", "legend", "li", "link", "main", "map", "mark", "meta", "meter", "nav", "nobr", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param", "pre", "progress", "q", "s", "samp", "script", "section", "select", "small", "source", "span", "strike", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "u", "ul", "var", "video", "wbr", "xmp", ].forEach(tagname=>{ mk[tagname] = (...args) => mk(tagname, ...args); }); function* nodesFromChildList(children) { for(const child of children.flat(Infinity)) { if(child instanceof Node) { yield child; } else { yield new Text(child); } } } function append(el, ...children) { for(const child of nodesFromChildList(children)) { if(el instanceof Node) el.appendChild(child); else el.push(child); } return el; } function insertAfter(el, ...children) { for(const child of nodesFromChildList(children)) { el.parentNode.insertBefore(child, el.nextSibling); } return el; } function clearContents(el) { el.innerHTML = ""; return el; } function parseHTML(markup) { if(markup.toLowerCase().trim().indexOf('<!doctype') === 0) { const doc = document.implementation.createHTMLDocument(""); doc.documentElement.innerHTML = markup; return doc; } else { const el = mk.template({}); el.innerHTML = markup; return el.content; } }</script> <script>/* Boilerplate: script-dfn-panel */ "use strict"; { let dfnPanelData = { "0303e8e5": {"dfnID":"0303e8e5","dfnText":"utf-8 encode","external":true,"refSections":[{"refs":[{"id":"ref-for-utf-8-encode"}],"title":"3.1. Interface definition"}],"url":"https://encoding.spec.whatwg.org/#utf-8-encode"}, "03675365": {"dfnID":"03675365","dfnText":"event handler idl attribute","external":true,"refSections":[{"refs":[{"id":"ref-for-event-handler-idl-attributes"}],"title":"3.1. Interface definition"}],"url":"https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-idl-attributes"}, "0a52a8b4": {"dfnID":"0a52a8b4","dfnText":"combine","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-header-list-combine"}],"title":"2.2. Opening handshake"}],"url":"https://fetch.spec.whatwg.org/#concept-header-list-combine"}, "1172cc05": {"dfnID":"1172cc05","dfnText":"a websocket message has been received","external":true,"refSections":[{"refs":[{"id":"ref-for-page-66:~:text=_A%20WebSocket%20Message%20Has%20Been%20Received_"}],"title":"4. Feedback from the protocol"}],"url":"https://datatracker.ietf.org/doc/html/rfc6455#page-66:~:text=_A%20WebSocket%20Message%20Has%20Been%20Received_"}, "129bdae8": {"dfnID":"129bdae8","dfnText":"Event","external":true,"refSections":[{"refs":[{"id":"ref-for-event"}],"title":"6. The CloseEvent interface"}],"url":"https://dom.spec.whatwg.org/#event"}, "16b1470a": {"dfnID":"16b1470a","dfnText":"isomorphic encode","external":true,"refSections":[{"refs":[{"id":"ref-for-isomorphic-encode"}],"title":"2.2. Opening handshake"}],"url":"https://infra.spec.whatwg.org/#isomorphic-encode"}, "1b5b1c0c": {"dfnID":"1b5b1c0c","dfnText":"api base url","external":true,"refSections":[{"refs":[{"id":"ref-for-api-base-url"}],"title":"3.1. Interface definition"}],"url":"https://html.spec.whatwg.org/multipage/webappapis.html#api-base-url"}, "28bb6bc9": {"dfnID":"28bb6bc9","dfnText":"sec-websocket-protocol","external":true,"refSections":[{"refs":[{"id":"ref-for-section-11.3.4"},{"id":"ref-for-section-11.3.4\u2460"}],"title":"3.1. Interface definition"}],"url":"https://datatracker.ietf.org/doc/html/rfc6455#section-11.3.4"}, "2bc0cdf4": {"dfnID":"2bc0cdf4","dfnText":"EventTarget","external":true,"refSections":[{"refs":[{"id":"ref-for-eventtarget"}],"title":"3.1. Interface definition"}],"url":"https://dom.spec.whatwg.org/#eventtarget"}, "2bd00413": {"dfnID":"2bd00413","dfnText":"fail the websocket connection","external":true,"refSections":[{"refs":[{"id":"ref-for-section-7.1.7"},{"id":"ref-for-section-7.1.7\u2460"},{"id":"ref-for-section-7.1.7\u2461"},{"id":"ref-for-section-7.1.7\u2462"}],"title":"2.2. Opening handshake"},{"refs":[{"id":"ref-for-section-7.1.7\u2463"},{"id":"ref-for-section-7.1.7\u2464"},{"id":"ref-for-section-7.1.7\u2465"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-section-7.1.7\u2466"}],"title":"4. Feedback from the protocol"},{"refs":[{"id":"ref-for-section-7.1.7\u2467"}],"title":"7. Garbage collection"}],"url":"https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.7"}, "2c8ec3a8": {"dfnID":"2c8ec3a8","dfnText":"useparallelqueue","external":true,"refSections":[{"refs":[{"id":"ref-for-fetch-useparallelqueue"}],"title":"2.2. Opening handshake"}],"url":"https://fetch.spec.whatwg.org/#fetch-useparallelqueue"}, "2f8afbfe": {"dfnID":"2f8afbfe","dfnText":"ArrayBuffer","external":true,"refSections":[{"refs":[{"id":"ref-for-idl-ArrayBuffer"},{"id":"ref-for-idl-ArrayBuffer\u2460"},{"id":"ref-for-idl-ArrayBuffer\u2461"},{"id":"ref-for-idl-ArrayBuffer\u2462"},{"id":"ref-for-idl-ArrayBuffer\u2463"},{"id":"ref-for-idl-ArrayBuffer\u2464"},{"id":"ref-for-idl-ArrayBuffer\u2465"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-idl-ArrayBuffer\u2466"},{"id":"ref-for-idl-ArrayBuffer\u2467"}],"title":"4. Feedback from the protocol"}],"url":"https://webidl.spec.whatwg.org/#idl-ArrayBuffer"}, "33680a76": {"dfnID":"33680a76","dfnText":"ws","external":true,"refSections":[{"refs":[{"id":"ref-for-section-11.1.1"}],"title":"3.1. Interface definition"}],"url":"https://datatracker.ietf.org/doc/html/rfc6455#section-11.1.1"}, "358f1dbd": {"dfnID":"358f1dbd","dfnText":"referrer","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-request-referrer"}],"title":"2.2. Opening handshake"}],"url":"https://fetch.spec.whatwg.org/#concept-request-referrer"}, "3700794f": {"dfnID":"3700794f","dfnText":"data","external":true,"refSections":[{"refs":[{"id":"ref-for-dom-messageevent-data"}],"title":"4. Feedback from the protocol"}],"url":"https://html.spec.whatwg.org/multipage/comms.html#dom-messageevent-data"}, "37afd48d": {"dfnID":"37afd48d","dfnText":"InvalidAccessError","external":true,"refSections":[{"refs":[{"id":"ref-for-invalidaccesserror"}],"title":"3.1. Interface definition"}],"url":"https://webidl.spec.whatwg.org/#invalidaccesserror"}, "3a711be7": {"dfnID":"3a711be7","dfnText":"scheme","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-url-scheme"}],"title":"2.1. Connections"},{"refs":[{"id":"ref-for-concept-url-scheme\u2460"},{"id":"ref-for-concept-url-scheme\u2461"}],"title":"2.2. Opening handshake"},{"refs":[{"id":"ref-for-concept-url-scheme\u2462"},{"id":"ref-for-concept-url-scheme\u2463"},{"id":"ref-for-concept-url-scheme\u2464"},{"id":"ref-for-concept-url-scheme\u2465"},{"id":"ref-for-concept-url-scheme\u2466"}],"title":"3.1. Interface definition"}],"url":"https://url.spec.whatwg.org/#concept-url-scheme"}, "3ab2ec8b": {"dfnID":"3ab2ec8b","dfnText":"query","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-url-query"},{"id":"ref-for-concept-url-query\u2460"}],"title":"2.1. Connections"}],"url":"https://url.spec.whatwg.org/#concept-url-query"}, "3aff2fb3": {"dfnID":"3aff2fb3","dfnText":"BufferSource","external":true,"refSections":[{"refs":[{"id":"ref-for-BufferSource"}],"title":"3.1. Interface definition"}],"url":"https://webidl.spec.whatwg.org/#BufferSource"}, "3b5f2424": {"dfnID":"3b5f2424","dfnText":"the given value","external":true,"refSections":[{"refs":[{"id":"ref-for-the-given-value"}],"title":"3.1. Interface definition"}],"url":"https://webidl.spec.whatwg.org/#the-given-value"}, "3be1d4ac": {"dfnID":"3be1d4ac","dfnText":"extracting header list values","external":true,"refSections":[{"refs":[{"id":"ref-for-extract-header-list-values"}],"title":"2.2. Opening handshake"}],"url":"https://fetch.spec.whatwg.org/#extract-header-list-values"}, "3e8c0e5f": {"dfnID":"3e8c0e5f","dfnText":"MessageEvent","external":true,"refSections":[{"refs":[{"id":"ref-for-messageevent"}],"title":"4. Feedback from the protocol"}],"url":"https://html.spec.whatwg.org/multipage/comms.html#messageevent"}, "4013a022": {"dfnID":"4013a022","dfnText":"this","external":true,"refSections":[{"refs":[{"id":"ref-for-this"},{"id":"ref-for-this\u2460"},{"id":"ref-for-this\u2461"},{"id":"ref-for-this\u2462"},{"id":"ref-for-this\u2463"},{"id":"ref-for-this\u2464"},{"id":"ref-for-this\u2465"},{"id":"ref-for-this\u2466"},{"id":"ref-for-this\u2467"},{"id":"ref-for-this\u2468"},{"id":"ref-for-this\u2460\u24ea"},{"id":"ref-for-this\u2460\u2460"}],"title":"3.1. Interface definition"}],"url":"https://webidl.spec.whatwg.org/#this"}, "44a7708c": {"dfnID":"44a7708c","dfnText":"EventInit","external":true,"refSections":[{"refs":[{"id":"ref-for-dictdef-eventinit"}],"title":"6. The CloseEvent interface"}],"url":"https://dom.spec.whatwg.org/#dictdef-eventinit"}, "450958f7": {"dfnID":"450958f7","dfnText":"unsigned short","external":true,"refSections":[{"refs":[{"id":"ref-for-idl-unsigned-short"},{"id":"ref-for-idl-unsigned-short\u2460"},{"id":"ref-for-idl-unsigned-short\u2461"},{"id":"ref-for-idl-unsigned-short\u2462"},{"id":"ref-for-idl-unsigned-short\u2463"},{"id":"ref-for-idl-unsigned-short\u2464"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-idl-unsigned-short\u2465"},{"id":"ref-for-idl-unsigned-short\u2466"}],"title":"6. The CloseEvent interface"}],"url":"https://webidl.spec.whatwg.org/#idl-unsigned-short"}, "4e3cd62b": {"dfnID":"4e3cd62b","dfnText":"the websocket connection is established","external":true,"refSections":[{"refs":[{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2460"}],"title":"2.2. Opening handshake"},{"refs":[{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2461"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2462"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2463"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2464"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2465"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2466"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2467"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2468"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2460\u24ea"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2460\u2460"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2460\u2461"}],"title":"4. Feedback from the protocol"},{"refs":[{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2460\u2462"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2460\u2463"}],"title":"7. Garbage collection"}],"url":"https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and"}, "5372cca8": {"dfnID":"5372cca8","dfnText":"boolean","external":true,"refSections":[{"refs":[{"id":"ref-for-idl-boolean"},{"id":"ref-for-idl-boolean\u2460"}],"title":"6. The CloseEvent interface"}],"url":"https://webidl.spec.whatwg.org/#idl-boolean"}, "5442ea33": {"dfnID":"5442ea33","dfnText":"url serializer","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-url-serializer"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-concept-url-serializer\u2460"}],"title":"4. Feedback from the protocol"}],"url":"https://url.spec.whatwg.org/#concept-url-serializer"}, "55213b5b": {"dfnID":"55213b5b","dfnText":"request","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-request"}],"title":"2.2. Opening handshake"}],"url":"https://fetch.spec.whatwg.org/#concept-request"}, "5991ccfb": {"dfnID":"5991ccfb","dfnText":"relevant realm","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-relevant-realm"},{"id":"ref-for-concept-relevant-realm\u2460"}],"title":"4. Feedback from the protocol"}],"url":"https://html.spec.whatwg.org/multipage/webappapis.html#concept-relevant-realm"}, "5f90bbfb": {"dfnID":"5f90bbfb","dfnText":"undefined","external":true,"refSections":[{"refs":[{"id":"ref-for-idl-undefined"},{"id":"ref-for-idl-undefined\u2460"}],"title":"3.1. Interface definition"}],"url":"https://webidl.spec.whatwg.org/#idl-undefined"}, "5fd23811": {"dfnID":"5fd23811","dfnText":"fire an event","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-event-fire"},{"id":"ref-for-concept-event-fire\u2460"},{"id":"ref-for-concept-event-fire\u2461"},{"id":"ref-for-concept-event-fire\u2462"}],"title":"4. Feedback from the protocol"}],"url":"https://dom.spec.whatwg.org/#concept-event-fire"}, "64b62ea0": {"dfnID":"64b62ea0","dfnText":"redirect mode","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-request-redirect-mode"}],"title":"2.2. Opening handshake"}],"url":"https://fetch.spec.whatwg.org/#concept-request-redirect-mode"}, "683cb370": {"dfnID":"683cb370","dfnText":"step 1","external":true,"refSections":[{"refs":[{"id":"ref-for-step1"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-step1\u2460"},{"id":"ref-for-step1\u2461"},{"id":"ref-for-step1\u2462"}],"title":"7. Garbage collection"}],"url":"https://html.spec.whatwg.org/multipage/webappapis.html#step1"}, "688f9669": {"dfnID":"688f9669","dfnText":"cache mode","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-request-cache-mode"}],"title":"2.2. Opening handshake"}],"url":"https://fetch.spec.whatwg.org/#concept-request-cache-mode"}, "697965b2": {"dfnID":"697965b2","dfnText":"connection","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-connection"}],"title":"2.1. Connections"}],"url":"https://fetch.spec.whatwg.org/#concept-connection"}, "6a5a59a0": {"dfnID":"6a5a59a0","dfnText":"event handler","external":true,"refSections":[{"refs":[{"id":"ref-for-event-handlers"},{"id":"ref-for-event-handlers\u2460"}],"title":"3.1. Interface definition"}],"url":"https://html.spec.whatwg.org/multipage/webappapis.html#event-handlers"}, "6c9ab516": {"dfnID":"6c9ab516","dfnText":"ArrayBufferView","external":true,"refSections":[{"refs":[{"id":"ref-for-ArrayBufferView"},{"id":"ref-for-ArrayBufferView\u2460"}],"title":"3.1. Interface definition"}],"url":"https://webidl.spec.whatwg.org/#ArrayBufferView"}, "6d1db60d": {"dfnID":"6d1db60d","dfnText":"service-workers mode","external":true,"refSections":[{"refs":[{"id":"ref-for-request-service-workers-mode"}],"title":"2.2. Opening handshake"}],"url":"https://fetch.spec.whatwg.org/#request-service-workers-mode"}, "6ee0eab1": {"dfnID":"6ee0eab1","dfnText":"header list","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-request-header-list"},{"id":"ref-for-concept-request-header-list\u2460"},{"id":"ref-for-concept-request-header-list\u2461"},{"id":"ref-for-concept-request-header-list\u2462"},{"id":"ref-for-concept-request-header-list\u2463"},{"id":"ref-for-concept-request-header-list\u2464"},{"id":"ref-for-concept-request-header-list\u2465"}],"title":"2.2. Opening handshake"}],"url":"https://fetch.spec.whatwg.org/#concept-request-header-list"}, "797018a7": {"dfnID":"797018a7","dfnText":"InvalidStateError","external":true,"refSections":[{"refs":[{"id":"ref-for-invalidstateerror"}],"title":"3.1. Interface definition"}],"url":"https://webidl.spec.whatwg.org/#invalidstateerror"}, "7d0af9ea": {"dfnID":"7d0af9ea","dfnText":"wss","external":true,"refSections":[{"refs":[{"id":"ref-for-section-11.1.2"}],"title":"3.1. Interface definition"}],"url":"https://datatracker.ietf.org/doc/html/rfc6455#section-11.1.2"}, "7eb570ba": {"dfnID":"7eb570ba","dfnText":"subprotocol in use","external":true,"refSections":[{"refs":[{"id":"ref-for-page-19:~:text=_Subprotocol%20In,Use_"}],"title":"4. Feedback from the protocol"}],"url":"https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_Subprotocol%20In,Use_"}, "80726755": {"dfnID":"80726755","dfnText":"task queues","external":true,"refSections":[{"refs":[{"id":"ref-for-task-queue"}],"title":"4. Feedback from the protocol"}],"url":"https://html.spec.whatwg.org/multipage/webappapis.html#task-queue"}, "852ada56": {"dfnID":"852ada56","dfnText":"port","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-url-port"}],"title":"2.1. Connections"}],"url":"https://url.spec.whatwg.org/#concept-url-port"}, "85394472": {"dfnID":"85394472","dfnText":"Document","external":true,"refSections":[{"refs":[{"id":"ref-for-document"}],"title":"7. Garbage collection"}],"url":"https://dom.spec.whatwg.org/#document"}, "857d5516": {"dfnID":"857d5516","dfnText":"client","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-request-client"}],"title":"2.2. Opening handshake"}],"url":"https://fetch.spec.whatwg.org/#concept-request-client"}, "8855a9aa": {"dfnID":"8855a9aa","dfnText":"DOMString","external":true,"refSections":[{"refs":[{"id":"ref-for-idl-DOMString"},{"id":"ref-for-idl-DOMString\u2460"},{"id":"ref-for-idl-DOMString\u2461"},{"id":"ref-for-idl-DOMString\u2462"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-idl-DOMString\u2463"}],"title":"4. Feedback from the protocol"},{"refs":[{"id":"ref-for-idl-DOMString\u2464"}],"title":"6. The CloseEvent interface"}],"url":"https://webidl.spec.whatwg.org/#idl-DOMString"}, "889e932f": {"dfnID":"889e932f","dfnText":"Exposed","external":true,"refSections":[{"refs":[{"id":"ref-for-Exposed"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-Exposed\u2460"}],"title":"6. The CloseEvent interface"}],"url":"https://webidl.spec.whatwg.org/#Exposed"}, "902380f7": {"dfnID":"902380f7","dfnText":"credentials mode","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-request-credentials-mode"}],"title":"2.2. Opening handshake"}],"url":"https://fetch.spec.whatwg.org/#concept-request-credentials-mode"}, "959ad97b": {"dfnID":"959ad97b","dfnText":"origin","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-url-origin"}],"title":"4. Feedback from the protocol"}],"url":"https://url.spec.whatwg.org/#concept-url-origin"}, "9a517a7d": {"dfnID":"9a517a7d","dfnText":"queue a task","external":true,"refSections":[{"refs":[{"id":"ref-for-queue-a-task"},{"id":"ref-for-queue-a-task\u2460"},{"id":"ref-for-queue-a-task\u2461"},{"id":"ref-for-queue-a-task\u2462"},{"id":"ref-for-queue-a-task\u2463"},{"id":"ref-for-queue-a-task\u2464"}],"title":"4. Feedback from the protocol"}],"url":"https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task"}, "9c4c1e66": {"dfnID":"9c4c1e66","dfnText":"relevant settings object","external":true,"refSections":[{"refs":[{"id":"ref-for-relevant-settings-object"},{"id":"ref-for-relevant-settings-object\u2460"}],"title":"3.1. Interface definition"}],"url":"https://html.spec.whatwg.org/multipage/webappapis.html#relevant-settings-object"}, "9cce47fd": {"dfnID":"9cce47fd","dfnText":"sequence","external":true,"refSections":[{"refs":[{"id":"ref-for-idl-sequence"}],"title":"3.1. Interface definition"}],"url":"https://webidl.spec.whatwg.org/#idl-sequence"}, "9d386f55": {"dfnID":"9d386f55","dfnText":"event handler event type","external":true,"refSections":[{"refs":[{"id":"ref-for-event-handler-event-type"},{"id":"ref-for-event-handler-event-type\u2460"}],"title":"3.1. Interface definition"}],"url":"https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-event-type"}, "a0841248": {"dfnID":"a0841248","dfnText":"the websocket connection close reason","external":true,"refSections":[{"refs":[{"id":"ref-for-section-7.1.6"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-section-7.1.6\u2460"}],"title":"4. Feedback from the protocol"}],"url":"https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.6"}, "a1d47575": {"dfnID":"a1d47575","dfnText":"status","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-response-status"}],"title":"2.2. Opening handshake"}],"url":"https://fetch.spec.whatwg.org/#concept-response-status"}, "a3033be5": {"dfnID":"a3033be5","dfnText":"utf-8 decode without bom","external":true,"refSections":[{"refs":[{"id":"ref-for-utf-8-decode-without-bom"}],"title":"4. Feedback from the protocol"}],"url":"https://encoding.spec.whatwg.org/#utf-8-decode-without-bom"}, "a33db89a": {"dfnID":"a33db89a","dfnText":"fetch","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-fetch"},{"id":"ref-for-concept-fetch\u2460"}],"title":"2.2. Opening handshake"}],"url":"https://fetch.spec.whatwg.org/#concept-fetch"}, "a37b7863": {"dfnID":"a37b7863","dfnText":"the websocket connection close code","external":true,"refSections":[{"refs":[{"id":"ref-for-section-7.1.5"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-section-7.1.5\u2460"},{"id":"ref-for-section-7.1.5\u2461"}],"title":"4. Feedback from the protocol"}],"url":"https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.5"}, "a4fa4138": {"dfnID":"a4fa4138","dfnText":"start the websocket closing handshake","external":true,"refSections":[{"refs":[{"id":"ref-for-section-7.1.2"},{"id":"ref-for-section-7.1.2\u2460"},{"id":"ref-for-section-7.1.2\u2461"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-section-7.1.2\u2462"},{"id":"ref-for-section-7.1.2\u2463"}],"title":"7. Garbage collection"}],"url":"https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.2"}, "a6a8ec88": {"dfnID":"a6a8ec88","dfnText":"append","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-header-list-append"},{"id":"ref-for-concept-header-list-append\u2460"},{"id":"ref-for-concept-header-list-append\u2461"},{"id":"ref-for-concept-header-list-append\u2462"},{"id":"ref-for-concept-header-list-append\u2463"}],"title":"2.2. Opening handshake"}],"url":"https://fetch.spec.whatwg.org/#concept-header-list-append"}, "a7100bf9": {"dfnID":"a7100bf9","dfnText":"established","external":true,"refSections":[{"refs":[{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2460"}],"title":"2.2. Opening handshake"},{"refs":[{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2461"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2462"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2463"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2464"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2465"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2466"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2467"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2468"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2460\u24ea"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2460\u2460"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2460\u2461"}],"title":"4. Feedback from the protocol"},{"refs":[{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2460\u2462"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2460\u2463"}],"title":"7. Garbage collection"}],"url":"https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and"}, "a72449dd": {"dfnID":"a72449dd","dfnText":"in parallel","external":true,"refSections":[{"refs":[{"id":"ref-for-in-parallel"},{"id":"ref-for-in-parallel\u2460"}],"title":"3.1. Interface definition"}],"url":"https://html.spec.whatwg.org/multipage/infrastructure.html#in-parallel"}, "a8c7461b": {"dfnID":"a8c7461b","dfnText":"url record","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-url"},{"id":"ref-for-concept-url\u2460"},{"id":"ref-for-concept-url\u2461"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-concept-url\u2462"}],"title":"4. Feedback from the protocol"}],"url":"https://url.spec.whatwg.org/#concept-url"}, "ae698447": {"dfnID":"ae698447","dfnText":"close the websocket connection","external":true,"refSections":[{"refs":[{"id":"ref-for-section-7.1.1"},{"id":"ref-for-section-7.1.1\u2460"},{"id":"ref-for-section-7.1.1\u2461"},{"id":"ref-for-section-7.1.1\u2462"},{"id":"ref-for-section-7.1.1\u2463"},{"id":"ref-for-section-7.1.1\u2464"},{"id":"ref-for-section-7.1.1\u2465"},{"id":"ref-for-section-7.1.1\u2466"}],"title":"3.1. Interface definition"}],"url":"https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.1"}, "b012ccb2": {"dfnID":"b012ccb2","dfnText":"forgiving-base64 encode","external":true,"refSections":[{"refs":[{"id":"ref-for-forgiving-base64-encode"}],"title":"2.2. Opening handshake"}],"url":"https://infra.spec.whatwg.org/#forgiving-base64-encode"}, "b0d7f3c3": {"dfnID":"b0d7f3c3","dfnText":"USVString","external":true,"refSections":[{"refs":[{"id":"ref-for-idl-USVString"},{"id":"ref-for-idl-USVString\u2460"},{"id":"ref-for-idl-USVString\u2461"},{"id":"ref-for-idl-USVString\u2462"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-idl-USVString\u2463"},{"id":"ref-for-idl-USVString\u2464"}],"title":"6. The CloseEvent interface"}],"url":"https://webidl.spec.whatwg.org/#idl-USVString"}, "b75eba20": {"dfnID":"b75eba20","dfnText":"the websocket closing handshake is started","external":true,"refSections":[{"refs":[{"id":"ref-for-section-7.1.3"},{"id":"ref-for-section-7.1.3\u2460"},{"id":"ref-for-section-7.1.3\u2461"},{"id":"ref-for-section-7.1.3\u2462"},{"id":"ref-for-section-7.1.3\u2463"},{"id":"ref-for-section-7.1.3\u2464"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-section-7.1.3\u2465"}],"title":"4. Feedback from the protocol"},{"refs":[{"id":"ref-for-section-7.1.3\u2466"}],"title":"7. Garbage collection"}],"url":"https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.3"}, "b7d73f5b": {"dfnID":"b7d73f5b","dfnText":"Blob","external":true,"refSections":[{"refs":[{"id":"ref-for-dfn-Blob"},{"id":"ref-for-dfn-Blob\u2460"},{"id":"ref-for-dfn-Blob\u2461"},{"id":"ref-for-dfn-Blob\u2462"},{"id":"ref-for-dfn-Blob\u2463"},{"id":"ref-for-dfn-Blob\u2464"},{"id":"ref-for-dfn-Blob\u2465"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-dfn-Blob\u2466"}],"title":"4. Feedback from the protocol"}],"url":"https://w3c.github.io/FileAPI/#dfn-Blob"}, "b85ee3be": {"dfnID":"b85ee3be","dfnText":"host","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-url-host"}],"title":"2.1. Connections"}],"url":"https://url.spec.whatwg.org/#concept-url-host"}, "bd2fe71e": {"dfnID":"bd2fe71e","dfnText":"processresponse","external":true,"refSections":[{"refs":[{"id":"ref-for-process-response"}],"title":"2.2. Opening handshake"}],"url":"https://fetch.spec.whatwg.org/#process-response"}, "be2d2b4c": {"dfnID":"be2d2b4c","dfnText":"SyntaxError","external":true,"refSections":[{"refs":[{"id":"ref-for-syntaxerror"},{"id":"ref-for-syntaxerror\u2460"},{"id":"ref-for-syntaxerror\u2461"},{"id":"ref-for-syntaxerror\u2462"},{"id":"ref-for-syntaxerror\u2463"},{"id":"ref-for-syntaxerror\u2464"}],"title":"3.1. Interface definition"}],"url":"https://webidl.spec.whatwg.org/#syntaxerror"}, "c07f8014": {"dfnID":"c07f8014","dfnText":"header value","external":true,"refSections":[{"refs":[{"id":"ref-for-header-value"}],"title":"2.2. Opening handshake"}],"url":"https://fetch.spec.whatwg.org/#header-value"}, "c0868016": {"dfnID":"c0868016","dfnText":"path","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-url-path"}],"title":"2.1. Connections"}],"url":"https://url.spec.whatwg.org/#concept-url-path"}, "c3b2d08c": {"dfnID":"c3b2d08c","dfnText":"task source","external":true,"refSections":[{"refs":[{"id":"ref-for-task-source"}],"title":"4. Feedback from the protocol"}],"url":"https://html.spec.whatwg.org/multipage/webappapis.html#task-source"}, "c6d19e56": {"dfnID":"c6d19e56","dfnText":"event loop","external":true,"refSections":[{"refs":[{"id":"ref-for-event-loop"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-event-loop\u2460"},{"id":"ref-for-event-loop\u2461"},{"id":"ref-for-event-loop\u2462"}],"title":"7. Garbage collection"}],"url":"https://html.spec.whatwg.org/multipage/webappapis.html#event-loop"}, "c9b060e8": {"dfnID":"c9b060e8","dfnText":"the websocket connection is closed","external":true,"refSections":[{"refs":[{"id":"ref-for-section-7.1.4"},{"id":"ref-for-section-7.1.4\u2460"},{"id":"ref-for-section-7.1.4\u2461"},{"id":"ref-for-section-7.1.4\u2462"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-section-7.1.4\u2463"},{"id":"ref-for-section-7.1.4\u2464"}],"title":"4. Feedback from the protocol"}],"url":"https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.4"}, "ca3ca4ae": {"dfnID":"ca3ca4ae","dfnText":"url parser","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-url-parser"}],"title":"3.1. Interface definition"}],"url":"https://url.spec.whatwg.org/#concept-url-parser"}, "cb98f71f": {"dfnID":"cb98f71f","dfnText":"mode","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-request-mode"}],"title":"2.2. Opening handshake"}],"url":"https://fetch.spec.whatwg.org/#concept-request-mode"}, "cd622903": {"dfnID":"cd622903","dfnText":"extensions in use","external":true,"refSections":[{"refs":[{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2460"}],"title":"2.2. Opening handshake"},{"refs":[{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2461"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2462"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2463"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2464"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2465"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2466"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2467"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2468"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2460\u24ea"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2460\u2460"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2460\u2461"}],"title":"4. Feedback from the protocol"},{"refs":[{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2460\u2462"},{"id":"ref-for-page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and\u2460\u2463"}],"title":"7. Garbage collection"}],"url":"https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and"}, "closeevent": {"dfnID":"closeevent","dfnText":"CloseEvent","external":false,"refSections":[{"refs":[{"id":"ref-for-closeevent"}],"title":"4. Feedback from the protocol"},{"refs":[{"id":"ref-for-closeevent\u2460"},{"id":"ref-for-closeevent\u2461"}],"title":"6. The CloseEvent interface"}],"url":"#closeevent"}, "concept-websocket-connection-obtain": {"dfnID":"concept-websocket-connection-obtain","dfnText":"obtain a WebSocket connection","external":false,"refSections":[{"refs":[{"id":"ref-for-concept-websocket-connection-obtain"}],"title":"2.1. Connections"}],"url":"#concept-websocket-connection-obtain"}, "concept-websocket-establish": {"dfnID":"concept-websocket-establish","dfnText":"establish a WebSocket connection","external":false,"refSections":[{"refs":[{"id":"ref-for-concept-websocket-establish"},{"id":"ref-for-concept-websocket-establish\u2460"}],"title":"3.1. Interface definition"}],"url":"#concept-websocket-establish"}, "dc1cd39b": {"dfnID":"dc1cd39b","dfnText":"url","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-request-url"}],"title":"2.2. Opening handshake"}],"url":"https://fetch.spec.whatwg.org/#concept-request-url"}, "dca2de17": {"dfnID":"dca2de17","dfnText":"DOMException","external":true,"refSections":[{"refs":[{"id":"ref-for-idl-DOMException"},{"id":"ref-for-idl-DOMException\u2460"},{"id":"ref-for-idl-DOMException\u2461"},{"id":"ref-for-idl-DOMException\u2462"},{"id":"ref-for-idl-DOMException\u2463"},{"id":"ref-for-idl-DOMException\u2464"},{"id":"ref-for-idl-DOMException\u2465"},{"id":"ref-for-idl-DOMException\u2466"}],"title":"3.1. Interface definition"}],"url":"https://webidl.spec.whatwg.org/#idl-DOMException"}, "dcffbccd": {"dfnID":"dcffbccd","dfnText":"url","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-url"},{"id":"ref-for-concept-url\u2460"},{"id":"ref-for-concept-url\u2461"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-concept-url\u2462"}],"title":"4. Feedback from the protocol"}],"url":"https://url.spec.whatwg.org/#concept-url"}, "dictdef-closeeventinit": {"dfnID":"dictdef-closeeventinit","dfnText":"CloseEventInit","external":false,"refSections":[{"refs":[{"id":"ref-for-dictdef-closeeventinit"}],"title":"6. The CloseEvent interface"}],"url":"#dictdef-closeeventinit"}, "dom-binarytype-arraybuffer": {"dfnID":"dom-binarytype-arraybuffer","dfnText":"\"arraybuffer\"","external":false,"refSections":[{"refs":[{"id":"ref-for-dom-binarytype-arraybuffer"},{"id":"ref-for-dom-binarytype-arraybuffer\u2460"},{"id":"ref-for-dom-binarytype-arraybuffer\u2461"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-dom-binarytype-arraybuffer\u2462"}],"title":"4. Feedback from the protocol"}],"url":"#dom-binarytype-arraybuffer"}, "dom-binarytype-blob": {"dfnID":"dom-binarytype-blob","dfnText":"\"blob\"","external":false,"refSections":[{"refs":[{"id":"ref-for-dom-binarytype-blob"},{"id":"ref-for-dom-binarytype-blob\u2460"},{"id":"ref-for-dom-binarytype-blob\u2461"},{"id":"ref-for-dom-binarytype-blob\u2462"},{"id":"ref-for-dom-binarytype-blob\u2463"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-dom-binarytype-blob\u2464"}],"title":"4. Feedback from the protocol"}],"url":"#dom-binarytype-blob"}, "dom-closeevent-closeevent": {"dfnID":"dom-closeevent-closeevent","dfnText":"constructor","external":false,"refSections":[],"url":"#dom-closeevent-closeevent"}, "dom-closeevent-closeevent-type-eventinitdict-eventinitdict": {"dfnID":"dom-closeevent-closeevent-type-eventinitdict-eventinitdict","dfnText":"eventInitDict","external":false,"refSections":[],"url":"#dom-closeevent-closeevent-type-eventinitdict-eventinitdict"}, "dom-closeevent-closeevent-type-eventinitdict-type": {"dfnID":"dom-closeevent-closeevent-type-eventinitdict-type","dfnText":"type","external":false,"refSections":[],"url":"#dom-closeevent-closeevent-type-eventinitdict-type"}, "dom-closeevent-code": {"dfnID":"dom-closeevent-code","dfnText":"code","external":false,"refSections":[{"refs":[{"id":"ref-for-dom-closeevent-code"}],"title":"4. Feedback from the protocol"},{"refs":[{"id":"ref-for-dom-closeevent-code\u2460"},{"id":"ref-for-dom-closeevent-code\u2461"}],"title":"6. The CloseEvent interface"}],"url":"#dom-closeevent-code"}, "dom-closeevent-reason": {"dfnID":"dom-closeevent-reason","dfnText":"reason","external":false,"refSections":[{"refs":[{"id":"ref-for-dom-closeevent-reason"}],"title":"4. Feedback from the protocol"},{"refs":[{"id":"ref-for-dom-closeevent-reason\u2460"},{"id":"ref-for-dom-closeevent-reason\u2461"}],"title":"6. The CloseEvent interface"}],"url":"#dom-closeevent-reason"}, "dom-closeevent-wasclean": {"dfnID":"dom-closeevent-wasclean","dfnText":"wasClean","external":false,"refSections":[{"refs":[{"id":"ref-for-dom-closeevent-wasclean"}],"title":"4. Feedback from the protocol"},{"refs":[{"id":"ref-for-dom-closeevent-wasclean\u2460"},{"id":"ref-for-dom-closeevent-wasclean\u2461"}],"title":"6. The CloseEvent interface"}],"url":"#dom-closeevent-wasclean"}, "dom-closeeventinit-code": {"dfnID":"dom-closeeventinit-code","dfnText":"code","external":false,"refSections":[],"url":"#dom-closeeventinit-code"}, "dom-closeeventinit-reason": {"dfnID":"dom-closeeventinit-reason","dfnText":"reason","external":false,"refSections":[],"url":"#dom-closeeventinit-reason"}, "dom-closeeventinit-wasclean": {"dfnID":"dom-closeeventinit-wasclean","dfnText":"wasClean","external":false,"refSections":[],"url":"#dom-closeeventinit-wasclean"}, "dom-websocket-binarytype": {"dfnID":"dom-websocket-binarytype","dfnText":"binaryType","external":false,"refSections":[{"refs":[{"id":"ref-for-dom-websocket-binarytype"},{"id":"ref-for-dom-websocket-binarytype\u2460"},{"id":"ref-for-dom-websocket-binarytype\u2461"},{"id":"ref-for-dom-websocket-binarytype\u2462"}],"title":"3.1. Interface definition"}],"url":"#dom-websocket-binarytype"}, "dom-websocket-bufferedamount": {"dfnID":"dom-websocket-bufferedamount","dfnText":"bufferedAmount","external":false,"refSections":[{"refs":[{"id":"ref-for-dom-websocket-bufferedamount"},{"id":"ref-for-dom-websocket-bufferedamount\u2460"},{"id":"ref-for-dom-websocket-bufferedamount\u2461"},{"id":"ref-for-dom-websocket-bufferedamount\u2462"},{"id":"ref-for-dom-websocket-bufferedamount\u2463"},{"id":"ref-for-dom-websocket-bufferedamount\u2464"},{"id":"ref-for-dom-websocket-bufferedamount\u2465"},{"id":"ref-for-dom-websocket-bufferedamount\u2466"}],"title":"3.1. Interface definition"}],"url":"#dom-websocket-bufferedamount"}, "dom-websocket-close": {"dfnID":"dom-websocket-close","dfnText":"close(code, reason)","external":false,"refSections":[{"refs":[{"id":"ref-for-dom-websocket-close"},{"id":"ref-for-dom-websocket-close\u2460"},{"id":"ref-for-dom-websocket-close\u2461"},{"id":"ref-for-dom-websocket-close\u2462"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-dom-websocket-close\u2463"}],"title":"4. Feedback from the protocol"}],"url":"#dom-websocket-close"}, "dom-websocket-close-code-reason-code": {"dfnID":"dom-websocket-close-code-reason-code","dfnText":"code","external":false,"refSections":[],"url":"#dom-websocket-close-code-reason-code"}, "dom-websocket-close-code-reason-reason": {"dfnID":"dom-websocket-close-code-reason-reason","dfnText":"reason","external":false,"refSections":[],"url":"#dom-websocket-close-code-reason-reason"}, "dom-websocket-closed": {"dfnID":"dom-websocket-closed","dfnText":"CLOSED","external":false,"refSections":[{"refs":[{"id":"ref-for-dom-websocket-closed"},{"id":"ref-for-dom-websocket-closed\u2460"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-dom-websocket-closed\u2461"}],"title":"4. Feedback from the protocol"}],"url":"#dom-websocket-closed"}, "dom-websocket-closing": {"dfnID":"dom-websocket-closing","dfnText":"CLOSING","external":false,"refSections":[{"refs":[{"id":"ref-for-dom-websocket-closing"},{"id":"ref-for-dom-websocket-closing\u2460"},{"id":"ref-for-dom-websocket-closing\u2461"},{"id":"ref-for-dom-websocket-closing\u2462"},{"id":"ref-for-dom-websocket-closing\u2463"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-dom-websocket-closing\u2464"},{"id":"ref-for-dom-websocket-closing\u2465"}],"title":"4. Feedback from the protocol"},{"refs":[{"id":"ref-for-dom-websocket-closing\u2466"}],"title":"7. Garbage collection"}],"url":"#dom-websocket-closing"}, "dom-websocket-connecting": {"dfnID":"dom-websocket-connecting","dfnText":"CONNECTING","external":false,"refSections":[{"refs":[{"id":"ref-for-dom-websocket-connecting"},{"id":"ref-for-dom-websocket-connecting\u2460"},{"id":"ref-for-dom-websocket-connecting\u2461"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-dom-websocket-connecting\u2462"}],"title":"7. Garbage collection"}],"url":"#dom-websocket-connecting"}, "dom-websocket-extensions": {"dfnID":"dom-websocket-extensions","dfnText":"extensions","external":false,"refSections":[{"refs":[{"id":"ref-for-dom-websocket-extensions"},{"id":"ref-for-dom-websocket-extensions\u2460"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-dom-websocket-extensions\u2461"}],"title":"4. Feedback from the protocol"}],"url":"#dom-websocket-extensions"}, "dom-websocket-onclose": {"dfnID":"dom-websocket-onclose","dfnText":"onclose","external":false,"refSections":[{"refs":[{"id":"ref-for-dom-websocket-onclose"}],"title":"3.1. Interface definition"}],"url":"#dom-websocket-onclose"}, "dom-websocket-onerror": {"dfnID":"dom-websocket-onerror","dfnText":"onerror","external":false,"refSections":[{"refs":[{"id":"ref-for-dom-websocket-onerror"}],"title":"3.1. Interface definition"}],"url":"#dom-websocket-onerror"}, "dom-websocket-onmessage": {"dfnID":"dom-websocket-onmessage","dfnText":"onmessage","external":false,"refSections":[{"refs":[{"id":"ref-for-dom-websocket-onmessage"}],"title":"3.1. Interface definition"}],"url":"#dom-websocket-onmessage"}, "dom-websocket-onopen": {"dfnID":"dom-websocket-onopen","dfnText":"onopen","external":false,"refSections":[{"refs":[{"id":"ref-for-dom-websocket-onopen"}],"title":"3.1. Interface definition"}],"url":"#dom-websocket-onopen"}, "dom-websocket-open": {"dfnID":"dom-websocket-open","dfnText":"OPEN","external":false,"refSections":[{"refs":[{"id":"ref-for-dom-websocket-open"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-dom-websocket-open\u2460"},{"id":"ref-for-dom-websocket-open\u2461"}],"title":"4. Feedback from the protocol"},{"refs":[{"id":"ref-for-dom-websocket-open\u2462"}],"title":"7. Garbage collection"}],"url":"#dom-websocket-open"}, "dom-websocket-protocol": {"dfnID":"dom-websocket-protocol","dfnText":"protocol","external":false,"refSections":[{"refs":[{"id":"ref-for-dom-websocket-protocol"},{"id":"ref-for-dom-websocket-protocol\u2460"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-dom-websocket-protocol\u2461"}],"title":"4. Feedback from the protocol"}],"url":"#dom-websocket-protocol"}, "dom-websocket-readystate": {"dfnID":"dom-websocket-readystate","dfnText":"readyState","external":false,"refSections":[{"refs":[{"id":"ref-for-dom-websocket-readystate"},{"id":"ref-for-dom-websocket-readystate\u2460"}],"title":"3.1. Interface definition"}],"url":"#dom-websocket-readystate"}, "dom-websocket-send": {"dfnID":"dom-websocket-send","dfnText":"send(data)","external":false,"refSections":[{"refs":[{"id":"ref-for-dom-websocket-send"},{"id":"ref-for-dom-websocket-send\u2460"},{"id":"ref-for-dom-websocket-send\u2461"},{"id":"ref-for-dom-websocket-send\u2462"},{"id":"ref-for-dom-websocket-send\u2463"}],"title":"3.1. Interface definition"}],"url":"#dom-websocket-send"}, "dom-websocket-send-data-data": {"dfnID":"dom-websocket-send-data-data","dfnText":"data","external":false,"refSections":[],"url":"#dom-websocket-send-data-data"}, "dom-websocket-url": {"dfnID":"dom-websocket-url","dfnText":"url","external":false,"refSections":[{"refs":[{"id":"ref-for-dom-websocket-url"},{"id":"ref-for-dom-websocket-url\u2460"}],"title":"3.1. Interface definition"}],"url":"#dom-websocket-url"}, "dom-websocket-websocket": {"dfnID":"dom-websocket-websocket","dfnText":"new\n WebSocket(url, protocols)","external":false,"refSections":[{"refs":[{"id":"ref-for-dom-websocket-websocket"},{"id":"ref-for-dom-websocket-websocket\u2460"}],"title":"3.1. Interface definition"}],"url":"#dom-websocket-websocket"}, "dom-websocket-websocket-url-protocols-protocols": {"dfnID":"dom-websocket-websocket-url-protocols-protocols","dfnText":"protocols","external":false,"refSections":[],"url":"#dom-websocket-websocket-url-protocols-protocols"}, "dom-websocket-websocket-url-protocols-url": {"dfnID":"dom-websocket-websocket-url-protocols-url","dfnText":"url","external":false,"refSections":[],"url":"#dom-websocket-websocket-url-protocols-url"}, "e0eefdd9": {"dfnID":"e0eefdd9","dfnText":"origin","external":true,"refSections":[{"refs":[{"id":"ref-for-dom-messageevent-origin"}],"title":"4. Feedback from the protocol"}],"url":"https://html.spec.whatwg.org/multipage/comms.html#dom-messageevent-origin"}, "e270bd2a": {"dfnID":"e270bd2a","dfnText":"task","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-task"},{"id":"ref-for-concept-task\u2460"},{"id":"ref-for-concept-task\u2461"}],"title":"4. Feedback from the protocol"}],"url":"https://html.spec.whatwg.org/multipage/webappapis.html#concept-task"}, "e746eb27": {"dfnID":"e746eb27","dfnText":"cleanly","external":true,"refSections":[{"refs":[{"id":"ref-for-page-41:~:text=closed-,_cleanly_."},{"id":"ref-for-page-41:~:text=closed-,_cleanly_.\u2460"}],"title":"4. Feedback from the protocol"}],"url":"https://datatracker.ietf.org/doc/html/rfc6455#page-41:~:text=closed-,_cleanly_."}, "eb1b1af3": {"dfnID":"eb1b1af3","dfnText":"network error","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-network-error"}],"title":"2.2. Opening handshake"}],"url":"https://fetch.spec.whatwg.org/#concept-network-error"}, "ed948033": {"dfnID":"ed948033","dfnText":"fragment","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-url-fragment"},{"id":"ref-for-concept-url-fragment\u2460"}],"title":"3.1. Interface definition"}],"url":"https://url.spec.whatwg.org/#concept-url-fragment"}, "enumdef-binarytype": {"dfnID":"enumdef-binarytype","dfnText":"BinaryType","external":false,"refSections":[{"refs":[{"id":"ref-for-enumdef-binarytype"},{"id":"ref-for-enumdef-binarytype\u2460"}],"title":"3.1. Interface definition"}],"url":"#enumdef-binarytype"}, "eventdef-websocket-close": {"dfnID":"eventdef-websocket-close","dfnText":"close","external":false,"refSections":[{"refs":[{"id":"ref-for-eventdef-websocket-close"},{"id":"ref-for-eventdef-websocket-close\u2460"},{"id":"ref-for-eventdef-websocket-close\u2461"},{"id":"ref-for-eventdef-websocket-close\u2462"},{"id":"ref-for-eventdef-websocket-close\u2463"},{"id":"ref-for-eventdef-websocket-close\u2464"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-eventdef-websocket-close\u2465"}],"title":"6. The CloseEvent interface"},{"refs":[{"id":"ref-for-eventdef-websocket-close\u2466"},{"id":"ref-for-eventdef-websocket-close\u2467"},{"id":"ref-for-eventdef-websocket-close\u2468"}],"title":"7. Garbage collection"}],"url":"#eventdef-websocket-close"}, "eventdef-websocket-error": {"dfnID":"eventdef-websocket-error","dfnText":"error","external":false,"refSections":[{"refs":[{"id":"ref-for-eventdef-websocket-error"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-eventdef-websocket-error\u2460"},{"id":"ref-for-eventdef-websocket-error\u2461"},{"id":"ref-for-eventdef-websocket-error\u2462"}],"title":"7. Garbage collection"}],"url":"#eventdef-websocket-error"}, "eventdef-websocket-message": {"dfnID":"eventdef-websocket-message","dfnText":"message","external":false,"refSections":[{"refs":[{"id":"ref-for-eventdef-websocket-message"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-eventdef-websocket-message\u2460"}],"title":"4. Feedback from the protocol"},{"refs":[{"id":"ref-for-eventdef-websocket-message\u2461"},{"id":"ref-for-eventdef-websocket-message\u2462"}],"title":"7. Garbage collection"}],"url":"#eventdef-websocket-message"}, "eventdef-websocket-open": {"dfnID":"eventdef-websocket-open","dfnText":"open","external":false,"refSections":[{"refs":[{"id":"ref-for-eventdef-websocket-open"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-eventdef-websocket-open\u2460"}],"title":"4. Feedback from the protocol"},{"refs":[{"id":"ref-for-eventdef-websocket-open\u2461"}],"title":"7. Garbage collection"}],"url":"#eventdef-websocket-open"}, "f0951476": {"dfnID":"f0951476","dfnText":"EventHandler","external":true,"refSections":[{"refs":[{"id":"ref-for-eventhandler"},{"id":"ref-for-eventhandler\u2460"},{"id":"ref-for-eventhandler\u2461"},{"id":"ref-for-eventhandler\u2462"}],"title":"3.1. Interface definition"}],"url":"https://html.spec.whatwg.org/multipage/webappapis.html#eventhandler"}, "f14b47b8": {"dfnID":"f14b47b8","dfnText":"unsigned long long","external":true,"refSections":[{"refs":[{"id":"ref-for-idl-unsigned-long-long"}],"title":"3.1. Interface definition"}],"url":"https://webidl.spec.whatwg.org/#idl-unsigned-long-long"}, "f89c7d0d": {"dfnID":"f89c7d0d","dfnText":"Clamp","external":true,"refSections":[{"refs":[{"id":"ref-for-Clamp"}],"title":"3.1. Interface definition"}],"url":"https://webidl.spec.whatwg.org/#Clamp"}, "f9982e17": {"dfnID":"f9982e17","dfnText":"send a websocket message","external":true,"refSections":[{"refs":[{"id":"ref-for-page-66:~:text=needs%20to-,_Send%20a%20WebSocket%20Message_"},{"id":"ref-for-page-66:~:text=needs%20to-,_Send%20a%20WebSocket%20Message_\u2460"},{"id":"ref-for-page-66:~:text=needs%20to-,_Send%20a%20WebSocket%20Message_\u2461"},{"id":"ref-for-page-66:~:text=needs%20to-,_Send%20a%20WebSocket%20Message_\u2462"}],"title":"3.1. Interface definition"}],"url":"https://datatracker.ietf.org/doc/html/rfc6455#page-66:~:text=needs%20to-,_Send%20a%20WebSocket%20Message_"}, "flagged-as-full": {"dfnID":"flagged-as-full","dfnText":"flagged\n as full","external":false,"refSections":[{"refs":[{"id":"ref-for-flagged-as-full"},{"id":"ref-for-flagged-as-full\u2460"},{"id":"ref-for-flagged-as-full\u2461"},{"id":"ref-for-flagged-as-full\u2462"}],"title":"3.1. Interface definition"}],"url":"#flagged-as-full"}, "make-disappear": {"dfnID":"make-disappear","dfnText":"make disappear","external":false,"refSections":[],"url":"#make-disappear"}, "websocket": {"dfnID":"websocket","dfnText":"WebSocket","external":false,"refSections":[{"refs":[{"id":"ref-for-websocket"}],"title":"1. Introduction"},{"refs":[{"id":"ref-for-websocket\u2460"}],"title":"2. WebSocket protocol alterations"},{"refs":[{"id":"ref-for-websocket\u2461"}],"title":"3. The WebSocket interface"},{"refs":[{"id":"ref-for-websocket\u2462"},{"id":"ref-for-websocket\u2463"},{"id":"ref-for-websocket\u2464"},{"id":"ref-for-websocket\u2465"},{"id":"ref-for-websocket\u2466"},{"id":"ref-for-websocket\u2467"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-websocket\u2468"},{"id":"ref-for-websocket\u2460\u24ea"},{"id":"ref-for-websocket\u2460\u2460"},{"id":"ref-for-websocket\u2460\u2461"},{"id":"ref-for-websocket\u2460\u2462"},{"id":"ref-for-websocket\u2460\u2463"},{"id":"ref-for-websocket\u2460\u2464"}],"title":"4. Feedback from the protocol"},{"refs":[{"id":"ref-for-websocket\u2460\u2465"}],"title":"6. The CloseEvent interface"},{"refs":[{"id":"ref-for-websocket\u2460\u2466"},{"id":"ref-for-websocket\u2460\u2467"},{"id":"ref-for-websocket\u2460\u2468"},{"id":"ref-for-websocket\u2461\u24ea"},{"id":"ref-for-websocket\u2461\u2460"},{"id":"ref-for-websocket\u2461\u2461"}],"title":"7. Garbage collection"}],"url":"#websocket"}, "websocket-binary-type": {"dfnID":"websocket-binary-type","dfnText":"binary type","external":false,"refSections":[{"refs":[{"id":"ref-for-websocket-binary-type"},{"id":"ref-for-websocket-binary-type\u2460"},{"id":"ref-for-websocket-binary-type\u2461"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-websocket-binary-type\u2462"},{"id":"ref-for-websocket-binary-type\u2463"},{"id":"ref-for-websocket-binary-type\u2464"},{"id":"ref-for-websocket-binary-type\u2465"},{"id":"ref-for-websocket-binary-type\u2466"}],"title":"4. Feedback from the protocol"}],"url":"#websocket-binary-type"}, "websocket-internal-url": {"dfnID":"websocket-internal-url","dfnText":"url","external":false,"refSections":[{"refs":[{"id":"ref-for-websocket-internal-url"},{"id":"ref-for-websocket-internal-url\u2460"}],"title":"3.1. Interface definition"}],"url":"#websocket-internal-url"}, "websocket-ready-state": {"dfnID":"websocket-ready-state","dfnText":"ready state","external":false,"refSections":[{"refs":[{"id":"ref-for-websocket-ready-state"},{"id":"ref-for-websocket-ready-state\u2460"},{"id":"ref-for-websocket-ready-state\u2461"},{"id":"ref-for-websocket-ready-state\u2462"},{"id":"ref-for-websocket-ready-state\u2463"},{"id":"ref-for-websocket-ready-state\u2464"}],"title":"3.1. Interface definition"},{"refs":[{"id":"ref-for-websocket-ready-state\u2465"},{"id":"ref-for-websocket-ready-state\u2466"},{"id":"ref-for-websocket-ready-state\u2467"},{"id":"ref-for-websocket-ready-state\u2468"},{"id":"ref-for-websocket-ready-state\u2460\u24ea"}],"title":"4. Feedback from the protocol"},{"refs":[{"id":"ref-for-websocket-ready-state\u2460\u2460"},{"id":"ref-for-websocket-ready-state\u2460\u2461"},{"id":"ref-for-websocket-ready-state\u2460\u2462"}],"title":"7. Garbage collection"}],"url":"#websocket-ready-state"}, "websocket-task-source": {"dfnID":"websocket-task-source","dfnText":"WebSocket task source","external":false,"refSections":[],"url":"#websocket-task-source"}, }; document.addEventListener("DOMContentLoaded", ()=>{ genAllDfnPanels(); document.body.addEventListener("click", (e) => { // If not handled already, just hide all dfn panels. hideAllDfnPanels(); }); }); window.addEventListener("resize", () => { // Pin any visible dfn panel queryAll(".dfn-panel.on, .dfn-panel.activated").forEach(el=>positionDfnPanel(el)); }); function genAllDfnPanels() { for(const panelData of Object.values(dfnPanelData)) { const dfnID = panelData.dfnID; const dfn = document.getElementById(dfnID); if(!dfn) { console.log(`Can't find dfn#${dfnID}.`, panelData); continue; } dfn.panelData = panelData; insertDfnPopupAction(dfn); } } function genDfnPanel(dfn, { dfnID, url, dfnText, refSections, external }) { const dfnPanel = mk.aside({ class: "dfn-panel on", id: `infopanel-for-${dfnID}`, "data-for": dfnID, "aria-labelled-by":`infopaneltitle-for-${dfnID}`, }, mk.span({id:`infopaneltitle-for-${dfnID}`, style:"display:none"}, `Info about the '${dfnText}' ${external?"external":""} reference.`), mk.a({href:url, class:"dfn-link"}, url), refSections.length == 0 ? [] : mk.b({}, "Referenced in:"), mk.ul({}, ...refSections.map(section=> mk.li({}, ...section.refs.map((ref, refI)=> [ mk.a({ href: `#${ref.id}` }, (refI == 0) ? section.title : `(${refI + 1})` ), " ", ] ), ), ), ), genLinkingSyntaxes(dfn), ); dfnPanel.addEventListener('click', (event) => { if (event.target.nodeName == 'A') { scrollToTargetAndHighlight(event); pinDfnPanel(dfnPanel); } event.stopPropagation(); refocusOnTarget(event); }); dfnPanel.addEventListener('keydown', (event) => { if(event.keyCode == 27) { // Escape key hideDfnPanel({dfnPanel}); event.stopPropagation(); event.preventDefault(); } }); dfnPanel.dfn = dfn; dfn.dfnPanel = dfnPanel; return dfnPanel; } function hideAllDfnPanels() { // Delete the currently-active dfn panel. queryAll(".dfn-panel").forEach(dfnPanel=>hideDfnPanel({dfnPanel})); } function showDfnPanel(dfn) { hideAllDfnPanels(); // Only display one at a time. dfn.setAttribute("aria-expanded", "true"); const dfnPanel = genDfnPanel(dfn, dfn.panelData); // Give the dfn a unique tabindex, and then // give all the tabbable panel bits successive indexes. let tabIndex = 100; dfn.tabIndex = tabIndex++; const tabbable = dfnPanel.querySelectorAll(":is(a, button)"); for (const el of tabbable) { el.tabIndex = tabIndex++; } append(document.body, dfnPanel); positionDfnPanel(dfnPanel); } function positionDfnPanel(dfnPanel) { const dfn = dfnPanel.dfn; const dfnPos = getRootLevelAbsolutePosition(dfn); dfnPanel.style.top = dfnPos.bottom + "px"; dfnPanel.style.left = dfnPos.left + "px"; const panelPos = dfnPanel.getBoundingClientRect(); const panelMargin = 8; const maxRight = document.body.parentNode.clientWidth - panelMargin; if (panelPos.right > maxRight) { const overflowAmount = panelPos.right - maxRight; const newLeft = Math.max(panelMargin, dfnPos.left - overflowAmount); dfnPanel.style.left = newLeft + "px"; } } function pinDfnPanel(dfnPanel) { // Switch it to "activated" state, which pins it. dfnPanel.classList.add("activated"); dfnPanel.style.position = "fixed"; dfnPanel.style.left = null; dfnPanel.style.top = null; } function hideDfnPanel({dfn, dfnPanel}) { if(!dfnPanel) dfnPanel = dfn.dfnPanel; if(!dfn) dfn = dfnPanel.dfn; dfn.dfnPanel = undefined; dfnPanel.dfn = undefined; dfn.setAttribute("aria-expanded", "false"); dfn.tabIndex = undefined; dfnPanel.remove() } function toggleDfnPanel(dfn) { if(dfn.dfnPanel) { hideDfnPanel(dfn); } else { showDfnPanel(dfn); } } function insertDfnPopupAction(dfn) { dfn.setAttribute('role', 'button'); dfn.setAttribute('aria-expanded', 'false') dfn.tabIndex = 0; dfn.classList.add('has-dfn-panel'); dfn.addEventListener('click', (event) => { toggleDfnPanel(dfn); event.stopPropagation(); }); dfn.addEventListener('keypress', (event) => { const kc = event.keyCode; // 32->Space, 13->Enter if(kc == 32 || kc == 13) { toggleDfnPanel(dfn); event.stopPropagation(); event.preventDefault(); } }); } function refocusOnTarget(event) { const target = event.target; setTimeout(() => { // Refocus on the event.target element. // This is needed after browser scrolls to the destination. target.focus(); }); } // Returns the root-level absolute position {left and top} of element. function getRootLevelAbsolutePosition(el) { const boundsRect = el.getBoundingClientRect(); let xPos = 0; let yPos = 0; while (el) { let xScroll = el.scrollLeft; let yScroll = el.scrollTop; // Ignore scrolling of body. if (el.tagName === "BODY") { xScroll = 0; yScroll = 0; } xPos += (el.offsetLeft - xScroll + el.clientLeft); yPos += (el.offsetTop - yScroll + el.clientTop); el = el.offsetParent; } return { left: xPos, top: yPos, right: xPos + boundsRect.width, bottom: yPos + boundsRect.height, }; } function scrolledIntoView(element) { const rect = element.getBoundingClientRect(); return ( rect.top > 0 && rect.bottom < window.innerHeight ); } function scrollToTargetAndHighlight(event) { let hash = event.target.hash; if (hash) { hash = decodeURIComponent(hash.substring(1)); const dest = document.getElementById(hash); if (dest) { // Maybe prevent default scroll. if (scrolledIntoView(dest)) { event.preventDefault(); } dest.classList.add('highlighted'); setTimeout(() => dest.classList.remove('highlighted'), 1000); } } } // Functions, divided by link type, that wrap an autolink's // contents with the appropriate outer syntax. // Alternately, a string naming another type they format // the same as. function needsFor(type) { switch(type) { case "descriptor": case "value": case "element-attr": case "attr-value": case "element-state": case "method": case "constructor": case "argument": case "attribute": case "const": case "dict-member": case "event": case "enum-value": case "stringifier": case "serializer": case "iterator": case "maplike": case "setlike": case "state": case "mode": case "context": case "facet": return true; default: return false; } } function refusesFor(type) { switch(type) { case "property": case "element": case "interface": case "namespace": case "callback": case "dictionary": case "enum": case "exception": case "typedef": case "http-header": case "permission": return true; default: return false; } } function linkFormatterFromType(type) { switch(type) { case 'scheme': case 'permission': case 'dfn': return (text) => `[=${text}=]`; case 'abstract-op': return (text) => `[\$${text}\$]`; case 'function': case 'at-rule': case 'selector': case 'value': return (text) => `''${text}''`; case 'http-header': return (text) => `[:${text}:]`; case 'interface': case 'constructor': case 'method': case 'argument': case 'attribute': case 'callback': case 'dictionary': case 'dict-member': case 'enum': case 'enum-value': case 'exception': case 'const': case 'typedef': case 'stringifier': case 'serializer': case 'iterator': case 'maplike': case 'setlike': case 'extended-attribute': case 'event': case 'idl': return (text) => `{{${text}}}`; case 'element-state': case 'element-attr': case 'attr-value': case 'element': return (element) => `<{${element}}>`; case 'grammar': return (text) => `${text} (within a <pre class=prod>)`; case 'type': return (text)=> `<<${text}>>`; case 'descriptor': case 'property': return (text) => `'${text}'`; default: return; }; }; function genLinkingSyntaxes(dfn) { if(dfn.tagName != "DFN") return; const type = dfn.getAttribute('data-dfn-type'); if(!type) { console.log(`<dfn> doesn't have a data-dfn-type:`, dfn); return []; } // Return a function that wraps link text based on the type const linkFormatter = linkFormatterFromType(type); if(!linkFormatter) { console.log(`<dfn> has an unknown data-dfn-type:`, dfn); return []; } let ltAlts; if(dfn.hasAttribute('data-lt')) { ltAlts = dfn.getAttribute('data-lt') .split("|") .map(x=>x.trim()); } else { ltAlts = [dfn.textContent.trim()]; } if(type == "type") { // lt of "<foo>", but "foo" is the interior; // <<foo/bar>> is how you write it with a for, // not <foo/<bar>> or whatever. for(var i = 0; i < ltAlts.length; i++) { const lt = ltAlts[i]; const match = /<(.*)>/.exec(lt); if(match) { ltAlts[i] = match[1]; } } } let forAlts; if(dfn.hasAttribute('data-dfn-for')) { forAlts = dfn.getAttribute('data-dfn-for') .split(",") .map(x=>x.trim()); } else { forAlts = ['']; } let linkingSyntaxes = []; if(!needsFor(type)) { for(const lt of ltAlts) { linkingSyntaxes.push(linkFormatter(lt)); } } if(!refusesFor(type)) { for(const f of forAlts) { linkingSyntaxes.push(linkFormatter(`${f}/${ltAlts[0]}`)) } } return [ mk.b({}, 'Possible linking syntaxes:'), mk.ul({}, ...linkingSyntaxes.map(link => { const copyLink = async () => await navigator.clipboard.writeText(link); return mk.li({}, mk.div({ class: 'link-item' }, mk.button({ class: 'copy-icon', title: 'Copy', type: 'button', _onclick: copyLink, tabindex: 0, }, mk.span({ class: 'icon' }) ), mk.span({}, link) ) ); }) ) ]; } } </script> <script>/* Boilerplate: script-position-annos */ "use strict"; { function repositionAnnoPanels(){ const panels = [...document.querySelectorAll("[data-anno-for]")]; hydratePanels(panels); let vSoFar = 0; for(const panel of panels.sort(cmpTops)) { if(panel.top < vSoFar) { panel.top = vSoFar; panel.style.top = vSoFar + "px"; } vSoFar = panel.top + panel.height + 15; } } function hydratePanels(panels) { const main = document.querySelector("main"); let mainRect; if(main) mainRect = main.getBoundingClientRect(); // First display them all, if they're not already visible. for(const panel of panels) { panel.classList.remove("unpositioned"); } // Measure them all for(const panel of panels) { const dfn = document.getElementById(panel.getAttribute("data-anno-for")); if(!dfn) { console.log("Can't find the annotation panel target:", panel); continue; } panel.dfn = dfn; panel.top = window.scrollY + dfn.getBoundingClientRect().top; let panelRect = panel.getBoundingClientRect(); panel.height = panelRect.height; if(main) { panel.overlappingMain = panelRect.left < mainRect.right; } else { panel.overlappingMain = false; } } // And finally position them for(const panel of panels) { const dfn = panel.dfn; if(!dfn) continue; panel.style.top = panel.top + "px"; panel.classList.toggle("overlapping-main", panel.overlappingMain); } } function cmpTops(a,b) { return a.top - b.top; } window.addEventListener("load", repositionAnnoPanels); window.addEventListener("resize", repositionAnnoPanels); } </script> <script>/* Boilerplate: script-ref-hints */ "use strict"; { let refsData = { "#closeevent": {"export":true,"for_":[],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"CloseEvent","type":"interface","url":"#closeevent"}, "#concept-websocket-connection-obtain": {"export":true,"for_":[],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"obtain a websocket connection","type":"dfn","url":"#concept-websocket-connection-obtain"}, "#concept-websocket-establish": {"export":true,"for_":[],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"establish a websocket connection","type":"dfn","url":"#concept-websocket-establish"}, "#dictdef-closeeventinit": {"export":true,"for_":[],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"CloseEventInit","type":"dictionary","url":"#dictdef-closeeventinit"}, "#dom-binarytype-arraybuffer": {"export":true,"for_":["BinaryType"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"\"arraybuffer\"","type":"enum-value","url":"#dom-binarytype-arraybuffer"}, "#dom-binarytype-blob": {"export":true,"for_":["BinaryType"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"\"blob\"","type":"enum-value","url":"#dom-binarytype-blob"}, "#dom-closeevent-code": {"export":true,"for_":["CloseEvent"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"code","type":"attribute","url":"#dom-closeevent-code"}, "#dom-closeevent-reason": {"export":true,"for_":["CloseEvent"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"reason","type":"attribute","url":"#dom-closeevent-reason"}, "#dom-closeevent-wasclean": {"export":true,"for_":["CloseEvent"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"wasClean","type":"attribute","url":"#dom-closeevent-wasclean"}, "#dom-websocket-binarytype": {"export":true,"for_":["WebSocket"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"binaryType","type":"attribute","url":"#dom-websocket-binarytype"}, "#dom-websocket-bufferedamount": {"export":true,"for_":["WebSocket"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"bufferedAmount","type":"attribute","url":"#dom-websocket-bufferedamount"}, "#dom-websocket-close": {"export":true,"for_":["WebSocket"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"close(code, reason)","type":"method","url":"#dom-websocket-close"}, "#dom-websocket-closed": {"export":true,"for_":["WebSocket"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"CLOSED","type":"const","url":"#dom-websocket-closed"}, "#dom-websocket-closing": {"export":true,"for_":["WebSocket"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"CLOSING","type":"const","url":"#dom-websocket-closing"}, "#dom-websocket-connecting": {"export":true,"for_":["WebSocket"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"CONNECTING","type":"const","url":"#dom-websocket-connecting"}, "#dom-websocket-extensions": {"export":true,"for_":["WebSocket"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"extensions","type":"attribute","url":"#dom-websocket-extensions"}, "#dom-websocket-onclose": {"export":true,"for_":["WebSocket"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"onclose","type":"attribute","url":"#dom-websocket-onclose"}, "#dom-websocket-onerror": {"export":true,"for_":["WebSocket"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"onerror","type":"attribute","url":"#dom-websocket-onerror"}, "#dom-websocket-onmessage": {"export":true,"for_":["WebSocket"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"onmessage","type":"attribute","url":"#dom-websocket-onmessage"}, "#dom-websocket-onopen": {"export":true,"for_":["WebSocket"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"onopen","type":"attribute","url":"#dom-websocket-onopen"}, "#dom-websocket-open": {"export":true,"for_":["WebSocket"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"OPEN","type":"const","url":"#dom-websocket-open"}, "#dom-websocket-protocol": {"export":true,"for_":["WebSocket"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"protocol","type":"attribute","url":"#dom-websocket-protocol"}, "#dom-websocket-readystate": {"export":true,"for_":["WebSocket"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"readyState","type":"attribute","url":"#dom-websocket-readystate"}, "#dom-websocket-send": {"export":true,"for_":["WebSocket"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"send(data)","type":"method","url":"#dom-websocket-send"}, "#dom-websocket-url": {"export":true,"for_":["WebSocket"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"url","type":"attribute","url":"#dom-websocket-url"}, "#dom-websocket-websocket": {"export":true,"for_":["WebSocket"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"WebSocket(url, protocols)","type":"constructor","url":"#dom-websocket-websocket"}, "#enumdef-binarytype": {"export":true,"for_":[],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"BinaryType","type":"enum","url":"#enumdef-binarytype"}, "#eventdef-websocket-close": {"export":true,"for_":["WebSocket"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"close","type":"event","url":"#eventdef-websocket-close"}, "#eventdef-websocket-error": {"export":true,"for_":["WebSocket"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"error","type":"event","url":"#eventdef-websocket-error"}, "#eventdef-websocket-message": {"export":true,"for_":["WebSocket"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"message","type":"event","url":"#eventdef-websocket-message"}, "#eventdef-websocket-open": {"export":true,"for_":["WebSocket"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"open","type":"event","url":"#eventdef-websocket-open"}, "#flagged-as-full": {"export":true,"for_":[],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"flagged as full","type":"dfn","url":"#flagged-as-full"}, "#websocket": {"export":true,"for_":[],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"WebSocket","type":"interface","url":"#websocket"}, "#websocket-binary-type": {"export":true,"for_":["WebSocket"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"binary type","type":"dfn","url":"#websocket-binary-type"}, "#websocket-internal-url": {"export":true,"for_":["WebSocket"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"internal-url","type":"dfn","url":"#websocket-internal-url"}, "#websocket-ready-state": {"export":true,"for_":["WebSocket"],"level":"","normative":true,"shortname":"websockets","spec":"websockets","status":"local","text":"ready state","type":"dfn","url":"#websocket-ready-state"}, "https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_Subprotocol%20In,Use_": {"export":true,"for_":[],"level":"","normative":true,"shortname":"rfc6455","spec":"rfc6455","status":"anchor-block","text":"subprotocol in use","type":"dfn","url":"https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_Subprotocol%20In,Use_"}, "https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and": {"export":true,"for_":[],"level":"","normative":true,"shortname":"rfc6455","spec":"rfc6455","status":"anchor-block","text":"the websocket connection is established","type":"dfn","url":"https://datatracker.ietf.org/doc/html/rfc6455#page-19:~:text=_The%20WebSocket%20Connection%20is%20Established_,-and"}, "https://datatracker.ietf.org/doc/html/rfc6455#page-41:~:text=closed-,_cleanly_.": {"export":true,"for_":[],"level":"","normative":true,"shortname":"rfc6455","spec":"rfc6455","status":"anchor-block","text":"cleanly","type":"dfn","url":"https://datatracker.ietf.org/doc/html/rfc6455#page-41:~:text=closed-,_cleanly_."}, "https://datatracker.ietf.org/doc/html/rfc6455#page-66:~:text=_A%20WebSocket%20Message%20Has%20Been%20Received_": {"export":true,"for_":[],"level":"","normative":true,"shortname":"rfc6455","spec":"rfc6455","status":"anchor-block","text":"a websocket message has been received","type":"dfn","url":"https://datatracker.ietf.org/doc/html/rfc6455#page-66:~:text=_A%20WebSocket%20Message%20Has%20Been%20Received_"}, "https://datatracker.ietf.org/doc/html/rfc6455#page-66:~:text=needs%20to-,_Send%20a%20WebSocket%20Message_": {"export":true,"for_":[],"level":"","normative":true,"shortname":"rfc6455","spec":"rfc6455","status":"anchor-block","text":"send a websocket message","type":"dfn","url":"https://datatracker.ietf.org/doc/html/rfc6455#page-66:~:text=needs%20to-,_Send%20a%20WebSocket%20Message_"}, "https://datatracker.ietf.org/doc/html/rfc6455#section-11.1.1": {"export":true,"for_":[],"level":"","normative":true,"shortname":"rfc6455","spec":"rfc6455","status":"anchor-block","text":"ws","type":"dfn","url":"https://datatracker.ietf.org/doc/html/rfc6455#section-11.1.1"}, "https://datatracker.ietf.org/doc/html/rfc6455#section-11.1.2": {"export":true,"for_":[],"level":"","normative":true,"shortname":"rfc6455","spec":"rfc6455","status":"anchor-block","text":"wss","type":"dfn","url":"https://datatracker.ietf.org/doc/html/rfc6455#section-11.1.2"}, "https://datatracker.ietf.org/doc/html/rfc6455#section-11.3.4": {"export":true,"for_":[],"level":"","normative":true,"shortname":"rfc6455","spec":"rfc6455","status":"anchor-block","text":"sec-websocket-protocol","type":"http-header","url":"https://datatracker.ietf.org/doc/html/rfc6455#section-11.3.4"}, "https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.1": {"export":true,"for_":[],"level":"","normative":true,"shortname":"rfc6455","spec":"rfc6455","status":"anchor-block","text":"close the websocket connection","type":"dfn","url":"https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.1"}, "https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.2": {"export":true,"for_":[],"level":"","normative":true,"shortname":"rfc6455","spec":"rfc6455","status":"anchor-block","text":"start the websocket closing handshake","type":"dfn","url":"https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.2"}, "https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.3": {"export":true,"for_":[],"level":"","normative":true,"shortname":"rfc6455","spec":"rfc6455","status":"anchor-block","text":"the websocket closing handshake is started","type":"dfn","url":"https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.3"}, "https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.4": {"export":true,"for_":[],"level":"","normative":true,"shortname":"rfc6455","spec":"rfc6455","status":"anchor-block","text":"the websocket connection is closed","type":"dfn","url":"https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.4"}, "https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.5": {"export":true,"for_":[],"level":"","normative":true,"shortname":"rfc6455","spec":"rfc6455","status":"anchor-block","text":"the websocket connection close code","type":"dfn","url":"https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.5"}, "https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.6": {"export":true,"for_":[],"level":"","normative":true,"shortname":"rfc6455","spec":"rfc6455","status":"anchor-block","text":"the websocket connection close reason","type":"dfn","url":"https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.6"}, "https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.7": {"export":true,"for_":[],"level":"","normative":true,"shortname":"rfc6455","spec":"rfc6455","status":"anchor-block","text":"fail the websocket connection","type":"dfn","url":"https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.7"}, "https://dom.spec.whatwg.org/#concept-event-fire": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"dom","spec":"dom","status":"current","text":"fire an event","type":"dfn","url":"https://dom.spec.whatwg.org/#concept-event-fire"}, "https://dom.spec.whatwg.org/#dictdef-eventinit": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"dom","spec":"dom","status":"current","text":"EventInit","type":"dictionary","url":"https://dom.spec.whatwg.org/#dictdef-eventinit"}, "https://dom.spec.whatwg.org/#document": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"dom","spec":"dom","status":"current","text":"Document","type":"interface","url":"https://dom.spec.whatwg.org/#document"}, "https://dom.spec.whatwg.org/#event": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"dom","spec":"dom","status":"current","text":"Event","type":"interface","url":"https://dom.spec.whatwg.org/#event"}, "https://dom.spec.whatwg.org/#eventtarget": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"dom","spec":"dom","status":"current","text":"EventTarget","type":"interface","url":"https://dom.spec.whatwg.org/#eventtarget"}, "https://encoding.spec.whatwg.org/#utf-8-decode-without-bom": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"encoding","spec":"encoding","status":"current","text":"utf-8 decode without bom","type":"dfn","url":"https://encoding.spec.whatwg.org/#utf-8-decode-without-bom"}, "https://encoding.spec.whatwg.org/#utf-8-encode": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"encoding","spec":"encoding","status":"current","text":"utf-8 encode","type":"dfn","url":"https://encoding.spec.whatwg.org/#utf-8-encode"}, "https://fetch.spec.whatwg.org/#concept-connection": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"fetch","spec":"fetch","status":"current","text":"connection","type":"dfn","url":"https://fetch.spec.whatwg.org/#concept-connection"}, "https://fetch.spec.whatwg.org/#concept-fetch": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"fetch","spec":"fetch","status":"current","text":"fetch","type":"dfn","url":"https://fetch.spec.whatwg.org/#concept-fetch"}, "https://fetch.spec.whatwg.org/#concept-header-list-append": {"export":true,"for_":["header list"],"level":"1","normative":true,"shortname":"fetch","spec":"fetch","status":"current","text":"append","type":"dfn","url":"https://fetch.spec.whatwg.org/#concept-header-list-append"}, "https://fetch.spec.whatwg.org/#concept-header-list-combine": {"export":true,"for_":["header list"],"level":"1","normative":true,"shortname":"fetch","spec":"fetch","status":"current","text":"combine","type":"dfn","url":"https://fetch.spec.whatwg.org/#concept-header-list-combine"}, "https://fetch.spec.whatwg.org/#concept-network-error": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"fetch","spec":"fetch","status":"current","text":"network error","type":"dfn","url":"https://fetch.spec.whatwg.org/#concept-network-error"}, "https://fetch.spec.whatwg.org/#concept-request": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"fetch","spec":"fetch","status":"current","text":"request","type":"dfn","url":"https://fetch.spec.whatwg.org/#concept-request"}, "https://fetch.spec.whatwg.org/#concept-request-cache-mode": {"export":true,"for_":["request"],"level":"1","normative":true,"shortname":"fetch","spec":"fetch","status":"current","text":"cache mode","type":"dfn","url":"https://fetch.spec.whatwg.org/#concept-request-cache-mode"}, "https://fetch.spec.whatwg.org/#concept-request-client": {"export":true,"for_":["request"],"level":"1","normative":true,"shortname":"fetch","spec":"fetch","status":"current","text":"client","type":"dfn","url":"https://fetch.spec.whatwg.org/#concept-request-client"}, "https://fetch.spec.whatwg.org/#concept-request-credentials-mode": {"export":true,"for_":["request"],"level":"1","normative":true,"shortname":"fetch","spec":"fetch","status":"current","text":"credentials mode","type":"dfn","url":"https://fetch.spec.whatwg.org/#concept-request-credentials-mode"}, "https://fetch.spec.whatwg.org/#concept-request-header-list": {"export":true,"for_":["request"],"level":"1","normative":true,"shortname":"fetch","spec":"fetch","status":"current","text":"header list","type":"dfn","url":"https://fetch.spec.whatwg.org/#concept-request-header-list"}, "https://fetch.spec.whatwg.org/#concept-request-mode": {"export":true,"for_":["request"],"level":"1","normative":true,"shortname":"fetch","spec":"fetch","status":"current","text":"mode","type":"dfn","url":"https://fetch.spec.whatwg.org/#concept-request-mode"}, "https://fetch.spec.whatwg.org/#concept-request-redirect-mode": {"export":true,"for_":["request"],"level":"1","normative":true,"shortname":"fetch","spec":"fetch","status":"current","text":"redirect mode","type":"dfn","url":"https://fetch.spec.whatwg.org/#concept-request-redirect-mode"}, "https://fetch.spec.whatwg.org/#concept-request-referrer": {"export":true,"for_":["request"],"level":"1","normative":true,"shortname":"fetch","spec":"fetch","status":"current","text":"referrer","type":"dfn","url":"https://fetch.spec.whatwg.org/#concept-request-referrer"}, "https://fetch.spec.whatwg.org/#concept-request-url": {"export":true,"for_":["request"],"level":"1","normative":true,"shortname":"fetch","spec":"fetch","status":"current","text":"url","type":"dfn","url":"https://fetch.spec.whatwg.org/#concept-request-url"}, "https://fetch.spec.whatwg.org/#concept-response-status": {"export":true,"for_":["response"],"level":"1","normative":true,"shortname":"fetch","spec":"fetch","status":"current","text":"status","type":"dfn","url":"https://fetch.spec.whatwg.org/#concept-response-status"}, "https://fetch.spec.whatwg.org/#extract-header-list-values": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"fetch","spec":"fetch","status":"current","text":"extracting header list values","type":"dfn","url":"https://fetch.spec.whatwg.org/#extract-header-list-values"}, "https://fetch.spec.whatwg.org/#fetch-useparallelqueue": {"export":true,"for_":["fetch"],"level":"1","normative":true,"shortname":"fetch","spec":"fetch","status":"current","text":"useparallelqueue","type":"dfn","url":"https://fetch.spec.whatwg.org/#fetch-useparallelqueue"}, "https://fetch.spec.whatwg.org/#header-value": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"fetch","spec":"fetch","status":"current","text":"header value","type":"dfn","url":"https://fetch.spec.whatwg.org/#header-value"}, "https://fetch.spec.whatwg.org/#process-response": {"export":true,"for_":["fetch"],"level":"1","normative":true,"shortname":"fetch","spec":"fetch","status":"current","text":"processresponse","type":"dfn","url":"https://fetch.spec.whatwg.org/#process-response"}, "https://fetch.spec.whatwg.org/#request-service-workers-mode": {"export":true,"for_":["request"],"level":"1","normative":true,"shortname":"fetch","spec":"fetch","status":"current","text":"service-workers mode","type":"dfn","url":"https://fetch.spec.whatwg.org/#request-service-workers-mode"}, "https://html.spec.whatwg.org/multipage/comms.html#dom-messageevent-data": {"export":true,"for_":["MessageEvent"],"level":"1","normative":true,"shortname":"html","spec":"html","status":"current","text":"data","type":"attribute","url":"https://html.spec.whatwg.org/multipage/comms.html#dom-messageevent-data"}, "https://html.spec.whatwg.org/multipage/comms.html#dom-messageevent-origin": {"export":true,"for_":["MessageEvent"],"level":"1","normative":true,"shortname":"html","spec":"html","status":"current","text":"origin","type":"attribute","url":"https://html.spec.whatwg.org/multipage/comms.html#dom-messageevent-origin"}, "https://html.spec.whatwg.org/multipage/comms.html#messageevent": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"html","spec":"html","status":"current","text":"MessageEvent","type":"interface","url":"https://html.spec.whatwg.org/multipage/comms.html#messageevent"}, "https://html.spec.whatwg.org/multipage/infrastructure.html#in-parallel": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"html","spec":"html","status":"current","text":"in parallel","type":"dfn","url":"https://html.spec.whatwg.org/multipage/infrastructure.html#in-parallel"}, "https://html.spec.whatwg.org/multipage/webappapis.html#api-base-url": {"export":true,"for_":["environment settings object"],"level":"1","normative":true,"shortname":"html","spec":"html","status":"current","text":"api base url","type":"dfn","url":"https://html.spec.whatwg.org/multipage/webappapis.html#api-base-url"}, "https://html.spec.whatwg.org/multipage/webappapis.html#concept-relevant-realm": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"html","spec":"html","status":"current","text":"relevant realm","type":"dfn","url":"https://html.spec.whatwg.org/multipage/webappapis.html#concept-relevant-realm"}, "https://html.spec.whatwg.org/multipage/webappapis.html#concept-task": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"html","spec":"html","status":"current","text":"task","type":"dfn","url":"https://html.spec.whatwg.org/multipage/webappapis.html#concept-task"}, "https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-event-type": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"html","spec":"html","status":"current","text":"event handler event type","type":"dfn","url":"https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-event-type"}, "https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-idl-attributes": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"html","spec":"html","status":"current","text":"event handler idl attribute","type":"dfn","url":"https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-idl-attributes"}, "https://html.spec.whatwg.org/multipage/webappapis.html#event-handlers": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"html","spec":"html","status":"current","text":"event handler","type":"dfn","url":"https://html.spec.whatwg.org/multipage/webappapis.html#event-handlers"}, "https://html.spec.whatwg.org/multipage/webappapis.html#event-loop": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"html","spec":"html","status":"current","text":"event loop","type":"dfn","url":"https://html.spec.whatwg.org/multipage/webappapis.html#event-loop"}, "https://html.spec.whatwg.org/multipage/webappapis.html#eventhandler": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"html","spec":"html","status":"current","text":"EventHandler","type":"typedef","url":"https://html.spec.whatwg.org/multipage/webappapis.html#eventhandler"}, "https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"html","spec":"html","status":"current","text":"queue a task","type":"dfn","url":"https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task"}, "https://html.spec.whatwg.org/multipage/webappapis.html#relevant-settings-object": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"html","spec":"html","status":"current","text":"relevant settings object","type":"dfn","url":"https://html.spec.whatwg.org/multipage/webappapis.html#relevant-settings-object"}, "https://html.spec.whatwg.org/multipage/webappapis.html#step1": {"export":true,"for_":["event loop"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"step 1","type":"dfn","url":"https://html.spec.whatwg.org/multipage/webappapis.html#step1"}, "https://html.spec.whatwg.org/multipage/webappapis.html#task-queue": {"export":false,"for_":[],"level":"1","normative":true,"shortname":"html","spec":"html","status":"current","text":"task queues","type":"dfn","url":"https://html.spec.whatwg.org/multipage/webappapis.html#task-queue"}, "https://html.spec.whatwg.org/multipage/webappapis.html#task-source": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"html","spec":"html","status":"current","text":"task source","type":"dfn","url":"https://html.spec.whatwg.org/multipage/webappapis.html#task-source"}, "https://infra.spec.whatwg.org/#forgiving-base64-encode": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"infra","spec":"infra","status":"current","text":"forgiving-base64 encode","type":"dfn","url":"https://infra.spec.whatwg.org/#forgiving-base64-encode"}, "https://infra.spec.whatwg.org/#isomorphic-encode": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"infra","spec":"infra","status":"current","text":"isomorphic encode","type":"dfn","url":"https://infra.spec.whatwg.org/#isomorphic-encode"}, "https://url.spec.whatwg.org/#concept-url": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"url","spec":"url","status":"current","text":"url record","type":"dfn","url":"https://url.spec.whatwg.org/#concept-url"}, "https://url.spec.whatwg.org/#concept-url-fragment": {"export":true,"for_":["url"],"level":"1","normative":true,"shortname":"url","spec":"url","status":"current","text":"fragment","type":"dfn","url":"https://url.spec.whatwg.org/#concept-url-fragment"}, "https://url.spec.whatwg.org/#concept-url-host": {"export":true,"for_":["url"],"level":"1","normative":true,"shortname":"url","spec":"url","status":"current","text":"host","type":"dfn","url":"https://url.spec.whatwg.org/#concept-url-host"}, "https://url.spec.whatwg.org/#concept-url-origin": {"export":true,"for_":["url"],"level":"1","normative":true,"shortname":"url","spec":"url","status":"current","text":"origin","type":"dfn","url":"https://url.spec.whatwg.org/#concept-url-origin"}, "https://url.spec.whatwg.org/#concept-url-parser": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"url","spec":"url","status":"current","text":"url parser","type":"dfn","url":"https://url.spec.whatwg.org/#concept-url-parser"}, "https://url.spec.whatwg.org/#concept-url-path": {"export":true,"for_":["url"],"level":"1","normative":true,"shortname":"url","spec":"url","status":"current","text":"path","type":"dfn","url":"https://url.spec.whatwg.org/#concept-url-path"}, "https://url.spec.whatwg.org/#concept-url-port": {"export":true,"for_":["url"],"level":"1","normative":true,"shortname":"url","spec":"url","status":"current","text":"port","type":"dfn","url":"https://url.spec.whatwg.org/#concept-url-port"}, "https://url.spec.whatwg.org/#concept-url-query": {"export":true,"for_":["url"],"level":"1","normative":true,"shortname":"url","spec":"url","status":"current","text":"query","type":"dfn","url":"https://url.spec.whatwg.org/#concept-url-query"}, "https://url.spec.whatwg.org/#concept-url-scheme": {"export":true,"for_":["url"],"level":"1","normative":true,"shortname":"url","spec":"url","status":"current","text":"scheme","type":"dfn","url":"https://url.spec.whatwg.org/#concept-url-scheme"}, "https://url.spec.whatwg.org/#concept-url-serializer": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"url","spec":"url","status":"current","text":"url serializer","type":"dfn","url":"https://url.spec.whatwg.org/#concept-url-serializer"}, "https://w3c.github.io/FileAPI/#dfn-Blob": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"fileapi","spec":"fileapi","status":"current","text":"Blob","type":"interface","url":"https://w3c.github.io/FileAPI/#dfn-Blob"}, "https://webidl.spec.whatwg.org/#ArrayBufferView": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"webidl","spec":"webidl","status":"current","text":"ArrayBufferView","type":"typedef","url":"https://webidl.spec.whatwg.org/#ArrayBufferView"}, "https://webidl.spec.whatwg.org/#BufferSource": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"webidl","spec":"webidl","status":"current","text":"BufferSource","type":"typedef","url":"https://webidl.spec.whatwg.org/#BufferSource"}, "https://webidl.spec.whatwg.org/#Clamp": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"webidl","spec":"webidl","status":"current","text":"Clamp","type":"extended-attribute","url":"https://webidl.spec.whatwg.org/#Clamp"}, "https://webidl.spec.whatwg.org/#Exposed": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"webidl","spec":"webidl","status":"current","text":"Exposed","type":"extended-attribute","url":"https://webidl.spec.whatwg.org/#Exposed"}, "https://webidl.spec.whatwg.org/#idl-ArrayBuffer": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"webidl","spec":"webidl","status":"current","text":"ArrayBuffer","type":"interface","url":"https://webidl.spec.whatwg.org/#idl-ArrayBuffer"}, "https://webidl.spec.whatwg.org/#idl-DOMException": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"webidl","spec":"webidl","status":"current","text":"DOMException","type":"interface","url":"https://webidl.spec.whatwg.org/#idl-DOMException"}, "https://webidl.spec.whatwg.org/#idl-DOMString": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"webidl","spec":"webidl","status":"current","text":"DOMString","type":"interface","url":"https://webidl.spec.whatwg.org/#idl-DOMString"}, "https://webidl.spec.whatwg.org/#idl-USVString": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"webidl","spec":"webidl","status":"current","text":"USVString","type":"interface","url":"https://webidl.spec.whatwg.org/#idl-USVString"}, "https://webidl.spec.whatwg.org/#idl-boolean": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"webidl","spec":"webidl","status":"current","text":"boolean","type":"interface","url":"https://webidl.spec.whatwg.org/#idl-boolean"}, "https://webidl.spec.whatwg.org/#idl-sequence": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"webidl","spec":"webidl","status":"current","text":"sequence","type":"dfn","url":"https://webidl.spec.whatwg.org/#idl-sequence"}, "https://webidl.spec.whatwg.org/#idl-undefined": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"webidl","spec":"webidl","status":"current","text":"undefined","type":"interface","url":"https://webidl.spec.whatwg.org/#idl-undefined"}, "https://webidl.spec.whatwg.org/#idl-unsigned-long-long": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"webidl","spec":"webidl","status":"current","text":"unsigned long long","type":"interface","url":"https://webidl.spec.whatwg.org/#idl-unsigned-long-long"}, "https://webidl.spec.whatwg.org/#idl-unsigned-short": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"webidl","spec":"webidl","status":"current","text":"unsigned short","type":"interface","url":"https://webidl.spec.whatwg.org/#idl-unsigned-short"}, "https://webidl.spec.whatwg.org/#invalidaccesserror": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"webidl","spec":"webidl","status":"current","text":"InvalidAccessError","type":"exception","url":"https://webidl.spec.whatwg.org/#invalidaccesserror"}, "https://webidl.spec.whatwg.org/#invalidstateerror": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"webidl","spec":"webidl","status":"current","text":"InvalidStateError","type":"exception","url":"https://webidl.spec.whatwg.org/#invalidstateerror"}, "https://webidl.spec.whatwg.org/#syntaxerror": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"webidl","spec":"webidl","status":"current","text":"SyntaxError","type":"exception","url":"https://webidl.spec.whatwg.org/#syntaxerror"}, "https://webidl.spec.whatwg.org/#the-given-value": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"webidl","spec":"webidl","status":"current","text":"the given value","type":"dfn","url":"https://webidl.spec.whatwg.org/#the-given-value"}, "https://webidl.spec.whatwg.org/#this": {"export":true,"for_":[],"level":"1","normative":true,"shortname":"webidl","spec":"webidl","status":"current","text":"this","type":"dfn","url":"https://webidl.spec.whatwg.org/#this"}, }; function mkRefHint(link, ref) { const linkText = link.textContent; let dfnTextElements = ''; if (ref.text != linkText) { dfnTextElements = mk.li({}, mk.b({}, "Term: "), mk.span({}, ref.text) ); } const forList = ref.for_; let forListElements; if(forList.length == 0) { forListElements = []; } else if(forList.length == 1) { forListElements = mk.li({}, mk.b({}, "For: "), mk.span({}, forList[0]), ); } else { forListElements = mk.li({}, mk.b({}, "For: "), mk.ul({}, ...forList.map(forItem => mk.li({}, mk.span({}, forItem) ), ), ), ); } const url = ref.url; const safeUrl = encodeURIComponent(url); const hintPanel = mk.aside({ class: "ref-hint", id: `ref-hint-for-${safeUrl}`, "data-for": url, "aria-labelled-by": `ref-hint-for-${safeUrl}`, }, mk.ul({}, dfnTextElements, mk.li({}, mk.b({}, "URL: "), mk.a({ href: url, class: "ref" }, url), ), mk.li({}, mk.b({}, "Type: "), mk.span({}, `${ref.type}`), ), mk.li({}, mk.b({}, "Spec: "), mk.span({}, `${ref.spec ? ref.spec : ''}`), ), forListElements ), ); hintPanel.forLink = link; setupRefHintEventListeners(link, hintPanel); return hintPanel; } function hideAllRefHints() { queryAll(".ref-hint").forEach(el=>hideRefHint(el)); } function hideRefHint(refHint) { const link = refHint.forLink; link.setAttribute("aria-expanded", "false"); if(refHint.teardownEventListeners) { refHint.teardownEventListeners(); } refHint.remove(); } function showRefHint(link) { if(link.classList.contains("dfn-link")) return; const url = link.getAttribute("href"); const ref = refsData[url]; if(!ref) return; hideAllRefHints(); // Only display one at this time. const refHint = mkRefHint(link, ref); append(document.body, refHint); link.setAttribute("aria-expanded", "true"); positionRefHint(refHint); } function setupRefHintEventListeners(link, refHint) { if (refHint.teardownEventListeners) return; // Add event handlers to hide the refHint after the user moves away // from both the link and refHint, if not hovering either within one second. let timeout = null; const startHidingRefHint = (event) => { if (timeout) { clearTimeout(timeout); } timeout = setTimeout(() => { hideRefHint(refHint); }, 1000); } const resetHidingRefHint = (event) => { if (timeout) clearTimeout(timeout); timeout = null; }; link.addEventListener("mouseleave", startHidingRefHint); link.addEventListener("mouseenter", resetHidingRefHint); link.addEventListener("blur", startHidingRefHint); link.addEventListener("focus", resetHidingRefHint); refHint.addEventListener("mouseleave", startHidingRefHint); refHint.addEventListener("mouseenter", resetHidingRefHint); refHint.addEventListener("blur", startHidingRefHint); refHint.addEventListener("focus", resetHidingRefHint); refHint.teardownEventListeners = () => { // remove event listeners resetHidingRefHint(); link.removeEventListener("mouseleave", startHidingRefHint); link.removeEventListener("mouseenter", resetHidingRefHint); link.removeEventListener("blur", startHidingRefHint); link.removeEventListener("focus", resetHidingRefHint); refHint.removeEventListener("mouseleave", startHidingRefHint); refHint.removeEventListener("mouseenter", resetHidingRefHint); refHint.removeEventListener("blur", startHidingRefHint); refHint.removeEventListener("focus", resetHidingRefHint); }; } function positionRefHint(refHint) { const link = refHint.forLink; const linkPos = getRootLevelAbsolutePosition(link); refHint.style.top = linkPos.bottom + "px"; refHint.style.left = linkPos.left + "px"; const panelPos = refHint.getBoundingClientRect(); const panelMargin = 8; const maxRight = document.body.parentNode.clientWidth - panelMargin; if (panelPos.right > maxRight) { const overflowAmount = panelPos.right - maxRight; const newLeft = Math.max(panelMargin, linkPos.left - overflowAmount); refHint.style.left = newLeft + "px"; } } // TODO: shared util // Returns the root-level absolute position {left and top} of element. function getRootLevelAbsolutePosition(el) { const boundsRect = el.getBoundingClientRect(); let xPos = 0; let yPos = 0; while (el) { let xScroll = el.scrollLeft; let yScroll = el.scrollTop; // Ignore scrolling of body. if (el.tagName === "BODY") { xScroll = 0; yScroll = 0; } xPos += (el.offsetLeft - xScroll + el.clientLeft); yPos += (el.offsetTop - yScroll + el.clientTop); el = el.offsetParent; } return { left: xPos, top: yPos, right: xPos + boundsRect.width, bottom: yPos + boundsRect.height, }; } document.addEventListener("DOMContentLoaded", () => { document.body.addEventListener("mouseover", e=>{ let link = e.target.closest("a"); if(link) showRefHint(link); }); document.body.addEventListener("focus", e=>{ let link = e.target.closest("a"); if(link) showRefHint(link); }); document.body.addEventListener("click", (e) => { // If not handled already, just hide all link panels. hideAllRefHints(); }); }); window.addEventListener("resize", () => { // Hide any open ref hint. hideAllRefHints(); }); } </script> <script>/* Boilerplate: script-var-click-highlighting */ "use strict"; { /* Color-choosing design: * Colors are ordered by goodness. * On clicking a var, give it the earliest color with the lowest usage in the algorithm. * On re-clicking, re-use the var's most recent color if that's not currently being used elsewhere. */ const COLOR_COUNT = 7; document.addEventListener("click", e=>{ if(e.target.nodeName == "VAR") { highlightSameAlgoVars(e.target); } }); function highlightSameAlgoVars(v) { // Find the algorithm container. let algoContainer = findAlgoContainer(v); // Not highlighting document-global vars, // too likely to be unrelated. if(algoContainer == null) return; const varName = nameFromVar(v); if(!v.hasAttribute("data-var-color")) { const newColor = chooseHighlightColor(algoContainer, v); for(const el of algoContainer.querySelectorAll("var")) { if(nameFromVar(el) == varName) { el.setAttribute("data-var-color", newColor); el.setAttribute("data-var-last-color", newColor); } } } else { for(const el of algoContainer.querySelectorAll("var")) { if(nameFromVar(el) == varName) { el.removeAttribute("data-var-color"); } } } } function findAlgoContainer(el) { while(el != document.body) { if(el.hasAttribute("data-algorithm")) return el; el = el.parentNode; } return null; } function nameFromVar(el) { return el.textContent.replace(/(\s|\xa0)+/, " ").trim(); } function colorCountsFromContainer(container) { const namesFromColor = Array.from({length:COLOR_COUNT}, x=>new Set()); for(let v of container.querySelectorAll("var[data-var-color]")) { let color = +v.getAttribute("data-var-color"); namesFromColor[color].add(nameFromVar(v)); } return namesFromColor.map(x=>x.size); } function leastUsedColor(colors) { // Find the earliest color with the lowest count. let minCount = Infinity; let minColor = null; for(var i = 0; i < colors.length; i++) { if(colors[i] < minCount) { minColor = i; minCount = colors[i]; } } return minColor; } function chooseHighlightColor(container, v) { const colorCounts = colorCountsFromContainer(container); if(v.hasAttribute("data-var-last-color")) { let color = +v.getAttribute("data-var-last-color"); if(colorCounts[color] == 0) return color; } return leastUsedColor(colorCounts); } } </script>

Pages: 1 2 3 4 5 6 7 8 9 10