diff --git a/files/en-us/web/api/closeevent/code/index.md b/files/en-us/web/api/closeevent/code/index.md index 50f222f3e4c4d89..dd80a8d6f92fcc5 100644 --- a/files/en-us/web/api/closeevent/code/index.md +++ b/files/en-us/web/api/closeevent/code/index.md @@ -8,11 +8,11 @@ browser-compat: api.CloseEvent.code {{APIRef("Websockets API")}} -The **`code`** read-only property of the {{domxref("CloseEvent")}} interface returns a [WebSocket connection close code](https://www.rfc-editor.org/rfc/rfc6455.html#section-7.1.5) indicating the reason the server gave for closing the connection. +The **`code`** read-only property of the {{domxref("CloseEvent")}} interface returns a [WebSocket connection close code](https://www.rfc-editor.org/rfc/rfc6455.html#section-7.1.5) indicating the reason the connection was closed. ## Value -An integer [WebSocket connection close code](https://www.rfc-editor.org/rfc/rfc6455.html#section-7.1.5) in the range `1000` - `4999`, indicating the reason the server gave for closing the connection. +An integer [WebSocket connection close code](https://www.rfc-editor.org/rfc/rfc6455.html#section-7.1.5) in the range `1000` - `4999`, indicating the reason the connection was closed. diff --git a/files/en-us/web/api/closeevent/index.md b/files/en-us/web/api/closeevent/index.md index 237ddd3b628cdbf..2800eb565cadec7 100644 --- a/files/en-us/web/api/closeevent/index.md +++ b/files/en-us/web/api/closeevent/index.md @@ -21,7 +21,7 @@ A `CloseEvent` is sent to clients using {{Glossary("WebSockets")}} when the conn _This interface also inherits properties from its parent, {{domxref("Event")}}._ - {{domxref("CloseEvent.code")}} {{ReadOnlyInline}} - - : Returns an `unsigned short` containing the close code sent by the server. + - : Returns an `unsigned short` containing the close code. - {{domxref("CloseEvent.reason")}} {{ReadOnlyInline}} - : Returns a string indicating the reason the server closed the connection. This is specific to the particular server and sub-protocol. - {{domxref("CloseEvent.wasClean")}} {{ReadOnlyInline}} diff --git a/files/en-us/web/api/websocket/index.md b/files/en-us/web/api/websocket/index.md index d0c8e80d7505f93..48e06a3f1c1a89e 100644 --- a/files/en-us/web/api/websocket/index.md +++ b/files/en-us/web/api/websocket/index.md @@ -11,6 +11,9 @@ The `WebSocket` object provides the API for creating and managing a [WebSocket]( To construct a `WebSocket`, use the [`WebSocket()`](/en-US/docs/Web/API/WebSocket/WebSocket) constructor. +> [!NOTE] +> The `WebSocket` API has no way to apply [backpressure](/en-US/docs/Web/API/Streams_API/Concepts#backpressure), therefore when messages arrive faster than the application can process them, the application will either fill up the device's memory by buffering those messages, become unresponsive due to 100% CPU usage, or both. For an alternative that provides backpressure automatically, see {{domxref("WebSocketStream")}}. + {{InheritanceDiagram}} ## Constructor diff --git a/files/en-us/web/api/websockets_api/index.md b/files/en-us/web/api/websockets_api/index.md index e74539a819187ac..0afe1654332b5ad 100644 --- a/files/en-us/web/api/websockets_api/index.md +++ b/files/en-us/web/api/websockets_api/index.md @@ -2,12 +2,21 @@ title: The WebSocket API (WebSockets) slug: Web/API/WebSockets_API page-type: web-api-overview -browser-compat: api.WebSocket +browser-compat: + - api.WebSocket + - api.WebSocketStream --- {{DefaultAPISidebar("WebSockets API")}} -The **WebSocket API** is an advanced technology that makes it possible to open a two-way interactive communication session between the user's browser and a server. With this API, you can send messages to a server and receive event-driven responses without having to poll the server for a reply. +The **WebSocket API** makes it possible to open a two-way interactive communication session between the user's browser and a server. With this API, you can send messages to a server and receive responses without having to poll the server for a reply. + +The WebSocket API provides two alternative mechanisms for creating and using web socket connections: the {{domxref("WebSocket")}} interface and the {{domxref("WebSocketStream")}} interface. + +- The `WebSocket` interface is stable and has good browser and server support. However it doesn't support [backpressure](/en-US/docs/Web/API/Streams_API/Concepts#backpressure). As a result, when messages arrive faster than the application can process them it will either fill up the device's memory by buffering those messages, become unresponsive due to 100% CPU usage, or both. +- The `WebSocketStream` is a {{jsxref("Promise")}}-based alternative to `WebSocket`. It uses the [Streams API](/en-US/docs/Web/API/Streams_API) to handle receiving and sending messages, meaning that socket connections can take advantage of stream backpressure automatically, regulating the speed of reading or writing to avoid bottlenecks in the application. However, `WebSocketSteam` is non-standard and currently only supported in one rendering engine. + +Additionally, the [WebTransport API](/en-US/docs/Web/API/WebTransport_API) is expected to replace the WebSocket API for many applications. WebTransport is a versatile, low-level API that provides backpressure and many other features not supported by either `WebSocket` or `WebSocketStream`, such as unidirectional streams, out-of-order delivery, and unreliable data transmission via datagrams. WebTransport is more complex to use than WebSockets and its cross-browser support is not as wide, but it enables the implementation of sophisticated solutions. If standard WebSocket connections are a good fit for your use case and you need wide browser compatibility, you should employ the WebSockets API to get up and running quickly. However, if your application requires a non-standard custom solution, then you should use the WebTransport API. > [!NOTE] > While a WebSocket connection is functionally somewhat similar to standard Unix-style sockets, they are not related. @@ -16,6 +25,8 @@ The **WebSocket API** is an advanced technology that makes it possible to open a - [`WebSocket`](/en-US/docs/Web/API/WebSocket) - : The primary interface for connecting to a WebSocket server and then sending and receiving data on the connection. +- [`WebSocketStream`](/en-US/docs/Web/API/WebSocketStream) {{non-standard_inline}} + - : Promise-based interface for connecting to a WebSocket server; uses [streams](/en-US/docs/Web/API/Streams_API) to send and receive data on the connection. - [`CloseEvent`](/en-US/docs/Web/API/CloseEvent) - : The event sent by the WebSocket object when the connection closes. - [`MessageEvent`](/en-US/docs/Web/API/MessageEvent) @@ -28,28 +39,26 @@ The **WebSocket API** is an advanced technology that makes it possible to open a - [Writing a WebSocket server in C#](/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_server) - [Writing a WebSocket server in Java](/en-US/docs/Web/API/WebSockets_API/Writing_a_WebSocket_server_in_Java) - [Writing a WebSocket server in JavaScript (Deno)](/en-US/docs/Web/API/WebSockets_API/Writing_a_WebSocket_server_in_JavaScript_Deno) +- [Using WebSocketStream to write a client](/en-US/docs/Web/API/WebSockets_API/Using_WebSocketStream) ## Tools - [AsyncAPI](https://www.asyncapi.com/): A specification for describing event-driven architectures based on protocols like WebSocket. You can use it to describe WebSocket-based APIs just as you would describe REST APIs with the OpenAPI specification. Learn [why you should consider using AsyncAPI with WebSocket](https://www.asyncapi.com/blog/websocket-part1) and [how to do so](https://www.asyncapi.com/blog/websocket-part2). -- [HumbleNet](https://hacks.mozilla.org/2017/06/introducing-humblenet-a-cross-platform-networking-library-that-works-in-the-browser/): A cross-platform networking library that works in the browser. It consists of a C wrapper around WebSockets and WebRTC that abstracts away cross-browser differences, facilitating the creation of multi-user networking functionality for games and other apps. - [µWebSockets](https://github.com/uNetworking/uWebSockets): Highly scalable WebSocket server and client implementation for [C++11](https://isocpp.org/) and [Node.js](https://nodejs.org/). - [Socket.IO](https://socket.io/): A long polling/WebSocket based third party transfer protocol for [Node.js](https://nodejs.org/). - [SocketCluster](https://socketcluster.io/): A pub/sub WebSocket framework for [Node.js](https://nodejs.org/) with a focus on scalability. - [WebSocket-Node](https://github.com/theturtle32/WebSocket-Node): A WebSocket server API implementation for [Node.js](https://nodejs.org/). - [Total.js](https://www.totaljs.com/): Web application framework for [Node.js](https://nodejs.org/en) (Example: [WebSocket chat](https://github.com/totaljs/examples/tree/master/websocket)) -- [Faye](https://www.npmjs.com/package/faye-websocket): A {{DOMxRef("WebSocket")}} (two-ways connections) and [EventSource](/en-US/docs/Web/API/EventSource) (one-way connections) for [Node.js](https://nodejs.org/) Server and Client. - [SignalR](https://dotnet.microsoft.com/en-us/apps/aspnet/signalr): SignalR will use WebSockets under the covers when it's available, and gracefully fallback to other techniques and technologies when it isn't, while your application code stays the same. - [Caddy](https://caddyserver.com/): A web server capable of proxying arbitrary commands (stdin/stdout) as a websocket. - [ws](https://github.com/websockets/ws): a popular WebSocket client & server library for [Node.js](https://nodejs.org/en). -- [jsonrpc-bidirectional](https://github.com/bigstepinc/jsonrpc-bidirectional): Asynchronous RPC which, on a single connection, may have functions exported on the server and, and the same time, on the client (client may call server, server may also call client). - [cowboy](https://github.com/ninenines/cowboy): Cowboy is a small, fast and modern HTTP server for Erlang/OTP with WebSocket support. - [ZeroMQ](https://zeromq.org/): ZeroMQ is embeddable networking library that carries messages across in-process, IPC, TCP, UDP, TIPC, multicast and WebSocket. - [WebSocket King](https://websocketking.com/): A client tool to help develop, test and work with WebSocket servers. - [PHP WebSocket Server](https://github.com/napengam/phpWebSocketServer): Server written in PHP to handle connections via websockets `wss://` or `ws://` and normal sockets over `ssl://`, `tcp://` -- [Channels](https://channels.readthedocs.io/en/stable/index.html): Django library that adds support for WebSockets (and other protocols that require long running asynchronous connections). -- [Channels](https://hexdocs.pm/phoenix/channels.html): Scalable real-time communication using WebSocket in Elixir Phoenix framework. -- [LiveView](https://github.com/phoenixframework/phoenix_live_view): Real-time interactive web experiences through WebSocket in Elixir Phoenix framework. +- [Django Channels](https://channels.readthedocs.io/en/stable/index.html): Django library that adds support for WebSockets (and other protocols that require long running asynchronous connections). +- [(Phoenix) Channels](https://hexdocs.pm/phoenix/channels.html): Scalable real-time communication using WebSocket in Elixir Phoenix framework. +- [Phoenix LiveView](https://github.com/phoenixframework/phoenix_live_view): Real-time interactive web experiences through WebSocket in Elixir Phoenix framework. - [Flask-SocketIO](https://flask-socketio.readthedocs.io/en/latest/): gives Flask applications access to low latency bi-directional communications between the clients and the server. - [Gorilla WebSocket](https://pkg.go.dev/github.com/gorilla/websocket): Gorilla WebSocket is a [Go](https://go.dev/) implementation of the WebSocket protocol. diff --git a/files/en-us/web/api/websockets_api/using_websocketstream/index.md b/files/en-us/web/api/websockets_api/using_websocketstream/index.md new file mode 100644 index 000000000000000..2ed559edbdbdbda --- /dev/null +++ b/files/en-us/web/api/websockets_api/using_websocketstream/index.md @@ -0,0 +1,303 @@ +--- +title: Using WebSocketStream to write a client +slug: Web/API/WebSockets_API/Using_WebSocketStream +page-type: guide +status: + - experimental + - non-standard +--- + +{{DefaultAPISidebar("WebSockets API")}}{{non-standard_header}} + +The {{domxref("WebSocketStream")}} API is a {{jsxref("Promise")}}-based alternative to {{domxref("WebSocket")}} for creating and using client-side WebSocket connections. `WebSocketStream` uses the [Streams API](/en-US/docs/Web/API/Streams_API) to handle receiving and sending messages, meaning that socket connections can take advantage of stream [backpressure](/en-US/docs/Web/API/Streams_API/Concepts#backpressure) automatically (no additional action required by the developer), regulating the speed of reading or writing to avoid bottlenecks in the application. + +This article explains how to use the {{domxref("WebSocketStream")}} API to create a WebSocket client. + +## Feature detection + +To check whether the `WebSocketStream` API is supported, you can use the following: + +```js +if ("WebSocketStream" in self) { + // WebSocketStream is supported +} +``` + +## Creating a WebSocketStream object + +To create a WebSocket client, you first need to create a new `WebSocketStream` instance using the {{domxref("WebSocketStream.WebSocketStream", "WebSocketStream()")}} constructor. In its simplest form, it takes the URL of the WebSocket server as an argument: + +```js +const wss = new WebSocketStream("wss://example.com/wss"); +``` + +It can also take an options object containing custom protocols and/or an {{domxref("AbortSignal")}} (see [Closing the connection](#closing_the_connection)): + +```js +const controller = new AbortController(); +const chatWSS = new WebSocketStream("wss://example.com/chat", { + protocols: ["chat", "chatv2"], + signal: controller.signal, +}); +``` + +## Sending and receiving data + +The `WebSocketStream` instance has an {{domxref("WebSocketStream.opened", "opened")}} property — this returns a promise that fulfills with an object containing a {{domxref("ReadableStream")}} and a {{domxref("WritableStream")}} instance once the WebSocket connection is opened successfully: + +```js +const { readable, writable } = await wss.opened; +``` + +Calling {{domxref("ReadableStream.getReader", "getReader()")}} and {{domxref("WritableStream.getWriter", "getWriter()")}} on these objects provides us with a {{domxref("ReadableStreamDefaultReader")}} and a {{domxref("WritableStreamDefaultWriter")}} respectively, which can be used to read from and write to the socket connection: + +```js +const reader = readable.getReader(); +const writer = writable.getWriter(); +``` + +To write data to the socket, you can use {{domxref("WritableStreamDefaultWriter.write()")}}: + +```js +writer.write("My message"); +``` + +To read data from the socket, you can continuously call {{domxref("ReadableStreamDefaultReader.read()")}} until the stream has finished, which is indicated by `done` being `true`: + +```js +while (true) { + const { value, done } = await reader.read(); + if (done) { + break; + } + + // Process value in some way +} +``` + +The browser automatically controls the rate at which the client receives and sends data by applying backpressure when needed. If data is arriving faster than the client can `read()` it, the underlying Streams API exerts backpressure on the server. In addition, `write()` operations will only proceed if it is safe to do so. + +## Closing the connection + +With `WebSocketStream`, the information previously available via the `WebSocket` {{domxref("WebSocket.close_event", "close")}} and {{domxref("WebSocket.error_event", "error")}} events is now available via the {{domxref("WebSocketStream.closed", "closed")}} property — this returns a promise that fulfills with an object containing the closing code (see the full list of [`CloseEvent` status codes](/en-US/docs/Web/API/CloseEvent/code#value)) and reason indicating why the server closed the connection: + +```js +const { code, reason } = await wss.closed; +``` + +As mentioned earlier, the WebSocket connection can be closed using an {{domxref("AbortController")}}. The necessary {{domxref("AbortSignal")}} is passed to the `WebSocketStream` constructor during creation, and {{domxref("AbortController.abort()")}} can then be called when required: + +```js +const controller = new AbortController(); +const wss = new WebSocketStream("wss://example.com/wss", { + signal: controller.signal, +}); + +// some time later + +controller.abort(); +``` + +Alternatively you can use the {{domxref("WebSocketStream.close()")}} method to close a connection. This is mainly used if you wish to specify a custom code and/or reason: + +```js +wss.close({ + code: 4000, + reason: "Night draws to a close", +}); +``` + +> [!NOTE] +> Depending on the server setup and status code you use, the server may choose to ignore a custom code in favor of a valid code that is correct for the closing reason. + +## A complete sample client + +To demonstrate basic usage of `WebSocketStream`, we've created a sample client. You can see the [full listing](#full_listing) at the bottom of the article, and follow along with the explanation below. + +> [!NOTE] +> To get the example working, you'll also need a server component. We wrote our client to work along with the Deno server explained in [Writing a WebSocket server in JavaScript (Deno)](/en-US/docs/Web/API/WebSockets_API/Writing_a_WebSocket_server_in_JavaScript_Deno), but any compatible server will do. + +The HTML for the demo is as follows. It includes informational [`

`](/en-US/docs/Web/HTML/Element/Heading_Elements) and {{htmlelement("p")}} elements, a {{htmlelement("button")}} to close the WebSocket connection that is initially disabled, and a {{htmlelement("div")}} for us to write output messages into. + +```html +

WebSocketStream Test

+

Sends a ping every five seconds

+ +
+``` + +Now on to the JavaScript. First we grab references to the output `
` and the close ` +
+ + + +``` diff --git a/files/en-us/web/api/websocketstream/close/index.md b/files/en-us/web/api/websocketstream/close/index.md new file mode 100644 index 000000000000000..e5da648f510653a --- /dev/null +++ b/files/en-us/web/api/websocketstream/close/index.md @@ -0,0 +1,71 @@ +--- +title: "WebSocketStream: close() method" +short-title: close() +slug: Web/API/WebSocketStream/close +page-type: web-api-instance-method +status: + - experimental + - non-standard +browser-compat: api.WebSocketStream.close +--- + +{{APIRef("WebSockets API")}}{{non-standard_header}} + +The **`close()`** method of the +{{domxref("WebSocketStream")}} interface closes the WebSocket connection. The method optionally accepts an object containing a custom code and/or reason indicating why the connection was closed. + +An alternative mechanism for closing a `WebSocketStream` is to specify an {{domxref("AbortSignal")}} in the [`signal`](/en-US/docs/Web/API/WebSocketStream/WebSocketStream#signal) option of the constructor upon creation. The associated {{domxref("AbortController")}} can then be used to close the WebSocket connection. This is generally the preferred mechanism. However, `close()` can be used if you wish to specify a custom code and/or reason. + +## Syntax + +```js-nolint +close() +close(options) +``` + +### Parameters + +- `options` {{optional_inline}} + - : An options object containing the following properties: + - `closeCode` {{optional_inline}} + - : A number representing the closing code (see the full list of [`CloseEvent` status codes](/en-US/docs/Web/API/CloseEvent/code#value)). + - `reason` {{optional_inline}} + - : A string representing a human-readable description of the reason why the socket connection is closed. The maximum allowed length for a `reason` string is 123 bytes. The string is automatically encoded as UTF-8 when the function is invoked. + +> [!NOTE] +> Depending on the server setup and status code you use, the server may choose to ignore a custom code in favor of a valid code that is correct for the closing reason. Valid codes are 1000, and any code within the range 3000 to 4999, inclusive. + +### Return value + +None (`undefined`). + +### Exceptions + +- `SyntaxError` {{domxref("DOMException")}} + - : Thrown if the provided `reason` is longer than the maximum allowed length of 123 bytes. + +## Examples + +```js +const wsURL = "wss://127.0.0.1/"; +const wss = new WebSocketStream(wsURL); + +setTimeout(() => { + wss.close({ + code: 1000, + reason: "That's all folks", + }); +}, 10000); +``` + +## Specifications + +Not currently a part of any specification. See https://github.com/whatwg/websockets/pull/48 for standardization progress. + +## Browser compatibility + +{{Compat}} + +## See also + +- [WebSocketStream: integrating streams with the WebSocket API](https://developer.chrome.com/docs/capabilities/web-apis/websocketstream), developer.chrome.com (2020) diff --git a/files/en-us/web/api/websocketstream/closed/index.md b/files/en-us/web/api/websocketstream/closed/index.md new file mode 100644 index 000000000000000..333fd2cd9ff3861 --- /dev/null +++ b/files/en-us/web/api/websocketstream/closed/index.md @@ -0,0 +1,54 @@ +--- +title: "WebSocketStream: closed property" +short-title: closed +slug: Web/API/WebSocketStream/closed +page-type: web-api-instance-property +status: + - experimental + - non-standard +browser-compat: api.WebSocketStream.closed +--- + +{{APIRef("WebSockets API")}}{{non-standard_header}} + +The **`closed`** read-only property of the +{{domxref("WebSocketStream")}} interface returns a {{jsxref("Promise")}} that fulfills with an object once the socket connection is closed. The object contains the closing code and reason. + +## Value + +A promise, which fulfills with an object containing the following properties: + +- `closeCode` + - : A number representing the closing code (see the full list of [`CloseEvent` status codes](/en-US/docs/Web/API/CloseEvent/code#value)). +- `reason` + - : A string representing a human-readable description of the reason why the socket connection was closed. + +The promise rejects if the WebSocket connection did not close cleanly (for a clean close, the associated TCP connection must be closed _after_ the WebSocket closing handshake is completed). + +## Examples + +```js +const wsURL = "wss://127.0.0.1/"; +const wss = new WebSocketStream(wsURL); + +wss.closed.then((result) => { + writeToScreen( + `DISCONNECTED: code ${result.closeCode}, message "${result.reason}"`, + ); + console.log("Socket closed", result.closeCode, result.reason); +}); +``` + +See [Using WebSocketStream to write a client](/en-US/docs/Web/API/WebSockets_API/Using_WebSocketStream) for a complete example with full explanation. + +## Specifications + +Not currently a part of any specification. See https://github.com/whatwg/websockets/pull/48 for standardization progress. + +## Browser compatibility + +{{Compat}} + +## See also + +- [WebSocketStream: integrating streams with the WebSocket API](https://developer.chrome.com/docs/capabilities/web-apis/websocketstream), developer.chrome.com (2020) diff --git a/files/en-us/web/api/websocketstream/index.md b/files/en-us/web/api/websocketstream/index.md new file mode 100644 index 000000000000000..462c2f47157b75e --- /dev/null +++ b/files/en-us/web/api/websocketstream/index.md @@ -0,0 +1,95 @@ +--- +title: WebSocketStream +slug: Web/API/WebSocketStream +page-type: web-api-interface +status: + - experimental + - non-standard +browser-compat: api.WebSocketStream +--- + +{{APIRef("WebSockets API")}}{{non-standard_header}} + +The **`WebSocketStream`** interface of the {{domxref("WebSockets API", "WebSockets API", "", "nocode")}} is a promise-based API for connecting to a WebSocket server. It uses [streams](/en-US/docs/Web/API/Streams_API) to send and receive data on the connection, and can therefore take advantage of stream [backpressure](/en-US/docs/Web/API/Streams_API/Concepts#backpressure) automatically, regulating the speed of reading or writing to avoid bottlenecks in the application. + +{{InheritanceDiagram}} + +## Constructor + +- {{domxref("WebSocketStream.WebSocketStream", "WebSocketStream()")}} + - : Creates a new `WebSocketStream` object instance. + +## Instance properties + +- {{domxref("WebSocketStream.url", "url")}} {{ReadOnlyInline}} + - : Returns the URL of the WebSocket server that the `WebSocketStream` instance was created with. +- {{domxref("WebSocketStream.closed", "closed")}} {{ReadOnlyInline}} + - : Returns a {{jsxref("Promise")}} that fulfills with an object once the socket connection is closed. The object contains the closing code and reason as sent by the server. +- {{domxref("WebSocketStream.opened", "opened")}} {{ReadOnlyInline}} + - : Returns a {{jsxref("Promise")}} that fulfills with an object once the socket connection is successfully opened. Among other features, this object contains a {{domxref("ReadableStream")}} and a {{domxref("WritableStream")}} instance for receiving and sending data on the connection. + +## Instance methods + +- {{domxref("WebSocketStream.close", "close()")}} + - : Closes the WebSocket connection. + +## Examples + +```js +const output = document.querySelector("#output"); + +function writeToScreen(message) { + const pElem = document.createElement("p"); + pElem.textContent = message; + output.appendChild(pElem); +} + +if (!("WebSocketStream" in self)) { + writeToScreen("Your browser does not support WebSocketStream"); +} else { + const wsURL = "ws://127.0.0.1/"; + const wss = new WebSocketStream(wsURL); + + console.log(wss.url); + + async function start() { + const { readable, writable, extensions, protocol } = await wss.opened; + writeToScreen("CONNECTED"); + closeBtn.disabled = false; + const reader = readable.getReader(); + const writer = writable.getWriter(); + + writer.write("ping"); + writeToScreen("SENT: ping"); + + while (true) { + const { value, done } = await reader.read(); + writeToScreen(`RECEIVED: ${value}`); + if (done) { + break; + } + + setTimeout(() => { + writer.write("ping"); + writeToScreen("SENT: ping"); + }, 5000); + } + } + + start(); +} +``` + +See [Using WebSocketStream to write a client](/en-US/docs/Web/API/WebSockets_API/Using_WebSocketStream) for a complete example with full explanation. + +## Specifications + +Not currently a part of any specification. See https://github.com/whatwg/websockets/pull/48 for standardization progress. + +## Browser compatibility + +{{Compat}} + +## See also + +- [WebSocketStream: integrating streams with the WebSocket API](https://developer.chrome.com/docs/capabilities/web-apis/websocketstream), developer.chrome.com (2020) diff --git a/files/en-us/web/api/websocketstream/opened/index.md b/files/en-us/web/api/websocketstream/opened/index.md new file mode 100644 index 000000000000000..7526f783c11a5d5 --- /dev/null +++ b/files/en-us/web/api/websocketstream/opened/index.md @@ -0,0 +1,71 @@ +--- +title: "WebSocketStream: opened property" +short-title: opened +slug: Web/API/WebSocketStream/opened +page-type: web-api-instance-property +status: + - experimental + - non-standard +browser-compat: api.WebSocketStream.opened +--- + +{{APIRef("WebSockets API")}}{{non-standard_header}} + +The **`opened`** read-only property of the +{{domxref("WebSocketStream")}} interface returns a {{jsxref("Promise")}} that fulfills with an object once the socket connection is successfully opened. Among other features, this object contains a {{domxref("ReadableStream")}} and a {{domxref("WritableStream")}} instance for receiving and sending data on the connection. + +## Value + +A promise, which fulfills with an object containing the following properties: + +- `extensions` + - : A string representing any extensions applied to the `WebSocketStream`. Such extensions are not currently defined, but may be in the future. Currently returns an empty string. +- `protocol` + - : A string representing the sub-protocol used to open the current WebSocket connection (chosen from the options specified in the [`protocols`](/en-US/docs/Web/API/WebSocketStream/WebSocketStream#protocols) option of the `WebSocketStream()` constructor). Returns an empty string if no sub-protocol has been used to open the connection (i.e. no sub-protocol options were included in the constructor call). +- `readable` + - : A {{domxref("ReadableStream")}} instance. Call {{domxref("ReadableStream.getReader()")}} on it to obtain a {{domxref("ReadableStreamDefaultReader")}} instance that can be used to read incoming WebSocket data. +- `writable` + - : A {{domxref("WritableStream")}} instance. Call {{domxref("WritableStream.getWriter()")}} on it to obtain a {{domxref("WritableStreamDefaultWriter")}} instance that can be used to write data to the WebSocket connection. + +The promise rejects if the WebSocket connection fails. + +## Examples + +```js +const wsURL = "wss://127.0.0.1/"; +const wss = new WebSocketStream(wsURL); + +async function start() { + const { readable, writable, extensions, protocol } = await wss.opened; + + const reader = readable.getReader(); + const writer = writable.getWriter(); + + writer.write("ping"); + + while (true) { + const { value, done } = await reader.read(); + if (done) { + break; + } + + setTimeout(() => { + writer.write("ping"); + }, 5000); + } +} +``` + +See [Using WebSocketStream to write a client](/en-US/docs/Web/API/WebSockets_API/Using_WebSocketStream) for a complete example with full explanation. + +## Specifications + +Not currently a part of any specification. See https://github.com/whatwg/websockets/pull/48 for standardization progress. + +## Browser compatibility + +{{Compat}} + +## See also + +- [WebSocketStream: integrating streams with the WebSocket API](https://developer.chrome.com/docs/capabilities/web-apis/websocketstream), developer.chrome.com (2020) diff --git a/files/en-us/web/api/websocketstream/url/index.md b/files/en-us/web/api/websocketstream/url/index.md new file mode 100644 index 000000000000000..3761d3d14627ea9 --- /dev/null +++ b/files/en-us/web/api/websocketstream/url/index.md @@ -0,0 +1,40 @@ +--- +title: "WebSocketStream: url property" +short-title: url +slug: Web/API/WebSocketStream/url +page-type: web-api-instance-property +status: + - experimental + - non-standard +browser-compat: api.WebSocketStream.url +--- + +{{APIRef("WebSockets API")}}{{non-standard_header}} + +The **`url`** read-only property of the +{{domxref("WebSocketStream")}} interface returns the URL of the WebSocket server that the `WebSocketStream` instance was created with. + +## Value + +A string. + +## Examples + +```js +const wss = new WebSocketStream("wss://example.com/wss"); + +// Logs "example.com/wss" to the console +console.log(wss.url); +``` + +## Specifications + +Not currently a part of any specification. See https://github.com/whatwg/websockets/pull/48 for standardization progress. + +## Browser compatibility + +{{Compat}} + +## See also + +- [WebSocketStream: integrating streams with the WebSocket API](https://developer.chrome.com/docs/capabilities/web-apis/websocketstream), developer.chrome.com (2020) diff --git a/files/en-us/web/api/websocketstream/websocketstream/index.md b/files/en-us/web/api/websocketstream/websocketstream/index.md new file mode 100644 index 000000000000000..d73e1a642ab8a66 --- /dev/null +++ b/files/en-us/web/api/websocketstream/websocketstream/index.md @@ -0,0 +1,78 @@ +--- +title: "WebSocketStream: WebSocketStream() constructor" +short-title: WebSocketStream() +slug: Web/API/WebSocketStream/WebSocketStream +page-type: web-api-constructor +status: + - experimental + - non-standard +browser-compat: api.WebSocketStream.WebSocketStream +--- + +{{APIRef("WebSockets API")}}{{non-standard_header}} + +The **`WebSocketStream()`** constructor creates a new +{{domxref("WebSocketStream")}} object instance. + +## Syntax + +```js-nolint +new WebSocketStream(url) +new WebSocketStream(url, options) +``` + +### Parameters + +- `url` + - : A string representing the URL of the WebSocket server you want to connect to with this `WebSocketStream` instance. Allowed URL schemes are `"ws"`, `"wss"`, `"http"`, and `"https"`. +- `options` {{optional_inline}} + - : An object that can contain the following properties: + - `protocols` {{optional_inline}} + - : A single string or an array of strings representing the sub-protocol(s) that the client would like to use, for example `"chat"` or `"chatv2"`. Subprotocols may be selected from the [IANA WebSocket Subprotocol Name Registry](https://www.iana.org/assignments/websocket/websocket.xml#subprotocol-name) or may be custom names jointly understood by the client and the server. A single server can implement multiple WebSocket sub-protocols, and handle different types of interactions depending on the specified value. If it is omitted, an empty array is used by default. If `protocols` is included, the connection will only be established if the server reports that it has selected one of these sub-protocols. + - `signal` {{optional_inline}} + - : An {{domxref("AbortSignal")}} belonging to an {{domxref("AbortController")}} that you want to use to close the WebSocket connection. + +### Exceptions + +- `SyntaxError` {{domxref("DOMException")}} + - : Thrown if the URL scheme is not one of `"ws"`, `"wss"`, `"http"`, or `"https"`. + +## Examples + +The most basic example takes the URL of a WebSocket server as an argument: + +```js +const wss = new WebSocketStream("wss://example.com/wss"); +``` + +A more advanced example could also include an options object containing custom protocols and/or an {{domxref("AbortSignal")}}: + +```js +const controller = new AbortController(); +const chatWSS = new WebSocketStream("wss://example.com/chat", { + protocols: ["chat", "chatv2"], + signal: controller.signal, +}); +``` + +At a later time, {{domxref("AbortController.abort()")}} can be called when required to close the connection: + +```js +controller.abort(); +``` + +Alternatively, you can use the {{domxref("WebSocketStream.close()")}} method to close a connection, however this is mainly needed if you wish to specify a custom code and/or reason for the server to report. + +See [Using WebSocketStream to write a client](/en-US/docs/Web/API/WebSockets_API/Using_WebSocketStream) for a complete example with full explanation. + +## Specifications + +Not currently a part of any specification. See https://github.com/whatwg/websockets/pull/48 for standardization progress. + +## Browser compatibility + +{{Compat}} + +## See also + +- [WebSocketStream: integrating streams with the WebSocket API](https://developer.chrome.com/docs/capabilities/web-apis/websocketstream), developer.chrome.com (2020) diff --git a/files/jsondata/GroupData.json b/files/jsondata/GroupData.json index 2488184fcb57c9f..1bd627d2a20efb0 100644 --- a/files/jsondata/GroupData.json +++ b/files/jsondata/GroupData.json @@ -2251,9 +2251,15 @@ "/docs/Web/API/WebSockets_API/Writing_WebSocket_servers", "/docs/Web/API/WebSockets_API/Writing_WebSocket_server", "/docs/Web/API/WebSockets_API/Writing_a_WebSocket_server_in_Java", - "/docs/Web/API/WebSockets_API/Writing_a_WebSocket_server_in_JavaScript_Deno" + "/docs/Web/API/WebSockets_API/Writing_a_WebSocket_server_in_JavaScript_Deno", + "/docs/Web/API/WebSockets_API/Using_WebSocketStream" + ], + "interfaces": [ + "WebSocket", + "WebSocketStream", + "CloseEvent", + "MessageEvent" ], - "interfaces": ["WebSocket", "CloseEvent", "MessageEvent"], "methods": [], "properties": [], "events": []