docs/1.guide/6.websocket.md
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.
<!-- automd:file code src="../../examples/websocket.ts" -->[!TIP] You can use
npx listhen --ws -w websocket.tsto run this example
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!` });
},
}),
);
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.
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();
}),
);