Skip to content

在構建 WebSocket 服務器時,通常需要存儲一些與每個連接的客戶端相關聯的標識信息或上下文。

使用 Bun.serve(),當連接最初升級時,通過在 server.upgrade() 調用中傳遞 data 參數來設置這個"上下文數據"。

ts
Bun.serve({
  fetch(req, server) {
    const success = server.upgrade(req, {
      data: {
        socketId: Math.random(),
      },
    });
    if (success) return undefined;

    // 正常處理 HTTP 請求
    // ...
  },
  websocket: {
    // TypeScript: 像這樣指定 ws.data 的類型
    data: {} as { socketId: number },

    // 定義 websocket 處理函數
    async message(ws, message) {
      // 上下文數據可作為 WebSocket 實例的 `data` 屬性使用
      console.log(`收到來自 ${ws.data.socketId} 的 ${message}`);
    },
  },
});

通常可以從傳入請求中讀取 cookies/headers 來識別連接的客戶端。

ts
type WebSocketData = {
  createdAt: number;
  token: string;
  userId: string;
};

Bun.serve({
  async fetch(req, server) {
    // 使用庫來解析 cookies
    const cookies = parseCookies(req.headers.get("Cookie"));
    const token = cookies["X-Token"];
    const user = await getUserFromToken(token);

    const upgraded = server.upgrade(req, {
      data: {
        createdAt: Date.now(),
        token: cookies["X-Token"],
        userId: user.id,
      },
    });

    if (upgraded) return undefined;
  },
  websocket: {
    // TypeScript: 像這樣指定 ws.data 的類型
    data: {} as WebSocketData,

    async message(ws, message) {
      // 將消息保存到數據庫
      await saveMessageToDatabase({
        message: String(message),
        userId: ws.data.userId,
      });
    },
  },
});

Bun學習網由www.bunjs.com.cn整理維護