WebSockets

H3 内置了跨平台 WebSocket 和服务器发送事件的实用程序。¥H3 has built-in utilities for cross platform WebSocket and Server-Sent Events.

你可以使用 🔌 CrossWS 为 H3 服务器添加跨平台 WebSocket 支持。

¥You can add cross platform WebSocket support to H3 servers using 🔌 CrossWS.

H3 版本中对 WebSockets 的内置支持仍在开发中。¥!IMPORTANT Built-in support of WebSockets in h3 version is WIP.

用法

¥Usage

WebSocket 处理程序可以使用 defineWebSocketHandler() 实用程序定义,并像事件处理程序一样注册到任何路由。

¥WebSocket handlers can be defined using the defineWebSocketHandler() utility and registered to any route like event handlers.

你需要在 serve 函数中将 CrossWS 注册为服务器插件,并提供 resolve 函数来解析路由中的正确钩子。

¥You need to register CrossWS as a server plugin in the serve function and provide a resolve function to resolve the correct hooks from the route.

import { H3, serve, defineWebSocketHandler } from "h3";

import { plugin as ws } from "crossws/server";

const app = new H3();

app.get("/_ws", defineWebSocketHandler({ message: console.log }));

serve(app, {
  plugins: [ws({ resolve: async (req) => (await app.fetch(req)).crossws })],
});

完整示例:

¥Full example:

websocket.mjs
import { H3, serve, defineWebSocketHandler } from "h3";
import { plugin as ws } from "crossws/server";

export const app = new H3();

const demoURL =
  "https://raw.githubusercontent.com/h3js/crossws/refs/heads/main/playground/public/index.html";

app.get("/", () =>
  fetch(demoURL).then(
    (res) =>
      new Response(res.body, { headers: { "Content-Type": "text/html" } }),
  ),
);

app.get(
  "/_ws",
  defineWebSocketHandler({
    // upgrade(req) {},
    open(peer) {
      console.log("[open]", peer);

      // Send welcome to the new client
      peer.send("Welcome to the server!");

      // Join new client to the "chat" channel
      peer.subscribe("chat");

      // Notify every other connected client
      peer.publish("chat", `[system] ${peer} joined!`);
    },

    message(peer, message) {
      console.log("[message]", peer);

      if (message.text() === "ping") {
        // Reply to the client with a ping response
        peer.send("pong");
        return;
      }

      // The server re-broadcasts incoming messages to everyone
      peer.publish("chat", `[${peer}] ${message}`);

      // Echo the message back to the sender
      peer.send(message);
    },

    close(peer) {
      console.log("[close]", peer);
      peer.publish("chat", `[system] ${peer} has left the chat!`);
      peer.unsubscribe("chat");
    },
  }),
);

serve(app, {
  plugins: [ws({ resolve: async (req) => (await app.fetch(req)).crossws })],
});

服务器发送事件 (SSE)

¥Server-Sent Events (SSE)

作为 WebSockets 的替代方案,你可以使用 服务器发送事件

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

H3 内置 API,可使用 createEventStream(event) 实用程序创建服务器发送事件。

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

示例

¥Example

server-sent-events.mjs
import { H3, serve, createEventStream } from "h3";

export const app = new H3();

app.get("/", (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(() => {
    console.log("Connection closed");
    clearInterval(interval);
  });

  return eventStream.send();
});

serve(app);