執行環境套件管理器打包器測試執行器程式碼檢查格式化指南參考部落格意見回饋

在 WebSocket 上設定每個 socket 的上下文資料

WebSocket 伺服器通常需要為每個已連線的客戶端儲存一些標識資訊或上下文。

使用 Bun.serve(),在升級連線時向 server.upgrade() 傳遞 data 引數,以設定這些“上下文資料”。

server.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) {
      // the contextual data is available as the `data` property
      // on the WebSocket instance
      console.log(`Received ${message} from ${ws.data.socketId}`);
    },
  },
});

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

server.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,
      });
    },
  },
});