Back to H3

WebSockets

docs/1.guide/6.websocket.md

1.15.112.8 KB
Original Source

WebSockets

H3 has built-in support for cross platform WebSocket and SSE.

H3 natively supports runtime agnostic WebSocket API using CrossWS.

::tip You can define WebSocket handlers in your existing Event Handlers to define multiple websocket handlers, dynamically matched with your same route definitions! ::

:read-more{title="WebSocket in MDN" to="https://developer.mozilla.org/en-US/docs/Web/API/WebSocket"}

:read-more{title="CrossWS" to="https://crossws.unjs.io/"}

[!IMPORTANT] WebSockets support is currently experimental and available in nightly channel.

Usage

Example

[!TIP] You can use npx listhen --ws -w websocket.ts to run this example

<!-- automd:file code src="../../examples/websocket.ts" -->
ts
import { createApp, defineEventHandler, defineWebSocketHandler } from "h3";

export const app = createApp();

app.use(
  defineEventHandler(async () => await import("./_ws").then((m) => m.default)),
);

app.use(
  "/_ws",
  defineWebSocketHandler({
    open(peer) {
      peer.send({ user: "server", message: `Welcome ${peer}!` });
      peer.publish("chat", { user: "server", message: `${peer} joined!` });
      peer.subscribe("chat");
    },
    message(peer, message) {
      if (message.text().includes("ping")) {
        peer.send({ user: "server", message: "pong" });
      } else {
        const msg = {
          user: peer.toString(),
          message: message.toString(),
        };
        peer.send(msg); // echo
        peer.publish("chat", msg);
      }
    },
    close(peer) {
      peer.publish("chat", { user: "server", message: `${peer} left!` });
    },
  }),
);
<!-- /automd -->

Server Sent Events (SSE)

As an alternative to WebSockets, you can use Server-sent events.

H3 has a built-in API to create server-sent events using createEventStream(event) utility.

[!IMPORTANT] SSE support is currently experimental and available in nightly channel.

Example

<!-- automd:file code src="../../examples/server-sent-events.ts" -->
ts
import { createApp, createRouter, eventHandler, createEventStream } from "h3";

export const app = createApp();

const router = createRouter();
app.use(router);

router.get(
  "/",
  eventHandler((event) => {
    const eventStream = createEventStream(event);

    // Send a message every second
    const interval = setInterval(async () => {
      await eventStream.push("Hello world");
    }, 1000);

    // cleanup the interval when the connection is terminated or the writer is closed
    eventStream.onClosed(() => {
      clearInterval(interval);
    });

    return eventStream.send();
  }),
);
<!-- /automd -->