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} を受信しました`);
},
},
});接続中のクライアントを識別するために、受信リクエストからクッキーやヘッダーを読み取るのが一般的です。
ts
type WebSocketData = {
createdAt: number;
token: string;
userId: string;
};
Bun.serve({
async fetch(req, server) {
// ライブラリを使用してクッキーを解析
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,
});
},
},
});