WebSocket
创建 .ws.ts 路由,在服务端与已连接的客户端之间发送带类型的消息。每个路由实例拥有自己的 Durable Object 用于共享状态。
预计阅读 1 分钟
每个路由实例拥有自己的 Cloudflare Durable Object 用于共享状态,WebSocket 路由需要 Cloudflare 部署目标。例如 /rooms/[id] 会为每个聊天室分配一个独立实例,可用于聊天、在线状态、协同文档或通知。
路由文件
在 routes/ 中使用 .ws.ts 后缀创建 WebSocket 路由:
├── chat/
│ └── [room].ws.ts
└── notifications.ws.ts
文件命名规则与常规服务端路由一致:
index.ws.ts变为父级路径[id].ws.ts变为:id[...slug].ws.ts变为 catch-all- 路由组如
(marketing)/chat.ws.ts不出现在 URL 中 chat.dev.ws.ts/chat.prod.ws.ts把路由限制在某个环境
defineRoom
当客户端应当共享一个由路由标识的房间或文档时,使用 defineRoom():
import * as v from 'valibot';
import { defineRoom } from 'void/ws';
const ClientMessage = v.variant('type', [
v.object({ type: v.literal('chat.message'), text: v.string() }),
]);
const ServerMessage = v.variant('type', [
v.object({
type: v.literal('chat.message'),
id: v.string(),
text: v.string(),
userId: v.string(),
}),
v.object({ type: v.literal('chat.joined'), userId: v.string() }),
]);
export default defineRoom({
messages: {
client: ClientMessage,
server: ServerMessage,
},
});
消息 schema 使用 Standard Schema 校验器编写,因此可以用 Valibot、Zod 或 ArkType。客户端与服务端的方向都有完整类型,非法消息在到达你的处理器之前就会被拒绝。