WebSockets WebSockets

H3 内置对跨平台 WebSocket 和 SSE 的支持。

H3 原生支持使用 CrossWS 的运行时无关的 WebSocket API。

您可以在现有的 事件处理程序 中定义 WebSocket 处理程序,以定义多个 websocket 处理程序,并与相同的路由定义动态匹配!

相关阅读:MDN 中的 WebSocket
相关阅读:CrossWS

!IMPORTANT WebSockets 支持目前处于实验阶段,可在 nightly 频道 中使用。

用法

示例

!TIP 您可以使用 npx listhen --ws -w websocket.ts 来运行此示例

websocket.ts
ts
import { createApp, defineEventHandler, defineWebSocketHandler } from 'h3'

export const app = createApp()

app.use(
  defineEventHandler(() =>
    fetch(
      'https://raw.githubusercontent.com/unjs/crossws/main/examples/h3/public/index.html',
    ).then(r => r.text()),
  ),
)

app.use(
  '/_ws',
  defineWebSocketHandler({
    open(peer) {
      console.log('[ws] open', peer)
    },

    message(peer, message) {
      console.log('[ws] message', peer, message)
      if (message.text().includes('ping')) {
        peer.send('pong')
      }
    },

    close(peer, event) {
      console.log('[ws] close', peer, event)
    },

    error(peer, error) {
      console.log('[ws] error', peer, error)
    },
  }),
)

服务器发送事件 (SSE)

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

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

!IMPORTANT SSE 支持目前处于实验阶段,可在 nightly 频道 中使用。

示例

server-sent-events.ts
ts
import { createApp, createEventStream, createRouter, eventHandler } from 'h3'

export const app = createApp()

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

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

    // 每秒发送一条消息
    const interval = setInterval(async () => {
      await eventStream.push('Hello world')
    }, 1000)

    // 连接终止或写入器关闭时清理间隔
    eventStream.onClosed(() => {
      clearInterval(interval)
    })

    return eventStream.send()
  }),
)