快速開始:跑通第一局
本指南用兩個瀏覽器視窗跑通一局兩人對戰:你的服務端建房並簽發票據,alice 和 bob 在 Web 客戶端加入、準備、互相看到對方的操作,最後你的服務端結束房間並收到結算回撥。概念和規則見遊戲房間概述。
1. 確認已開通
在控制台選好租戶和應用,開啟應用的「遊戲房間」頁。看到「接入」頁和可用大區,說明已經可以使用;看到「當前套餐不含遊戲房間」「遊戲房間暫未開放」等提示時,按開通處理。

換取 App Token、建立使用者和獲取登入憑證的步驟同傳送第一條訊息。下文的 $IM_API、$ORG、$APP、$APP_TOKEN 含義見服務端接入概述。
2. 建房
在你的服務端執行:
curl -X PUT "$IM_API/$ORG/$APP/game/rooms/demo-match-1" \
-H "Authorization: Bearer $APP_TOKEN" -H "Content-Type: application/json" \
-d '{"name":"第一局","max_players":2,"start_mode":"all_ready","tick_rate":20}'返回 201 和房間,room.status 為 open,room.region 是分到的大區。房間的全部引數見建立房間。
3. 簽發加入票據
假設 alice 和 bob 已經是本應用的使用者:
curl -X POST "$IM_API/$ORG/$APP/game/rooms/demo-match-1/tickets" \
-H "Authorization: Bearer $APP_TOKEN" -H "Content-Type: application/json" \
-d '{"users":[{"username":"alice","seat":0},{"username":"bob","seat":1}],"ttl_seconds":120}'響應的 tickets 裡每人一張 ticket。通過你自己的、已鑑權的業務介面分別交給 alice 和 bob,不要交給其他人,也不要寫進日誌。票據 120 秒內有效,過期或丟了直接再籤一次。
4. 玩家加入並對戰
先按 Web 快速整合安裝 @deeprespond/im-web(1.1.0 及以上)並登入。下面的程式碼在 alice 和 bob 的頁面裡各執行一次,ticketFromBusinessServer 是第 3 步交給這個玩家的票據:
const room = await im.game.join('demo-match-1', { ticket: ticketFromBusinessServer });
console.log('我的座位', room.seat, '成员', room.members);
// 每一帧:按帧号顺序收到所有座位这一帧的操作
room.onFrame((frame) => {
for (const input of frame.inputs) {
console.log(`第 ${frame.frame} 帧,座位 ${input.seat}:`, input.data);
}
});
room.onRoomState((e) => {
if (e.state === 'started') console.log('开局,从第', e.startFrame, '帧开始');
});
room.onClose((e) => console.log('对局结束', e.reason, e.result));
// 两个人都准备后开局(start_mode 为 all_ready)
room.ready();
// 开局后每帧发送本地操作(这里用一个字节代表按键)
setInterval(() => room.sendInput(new Uint8Array([room.seat === 0 ? 1 : 2])), 50);兩個頁面都準備後,控制台輸出 开局,之後每幀都能看到雙方的操作。關掉其中一個頁面的網路再開啟,它會自動重連回到原座位,缺的幀按順序補齊。
5. 結束對局
在你的服務端執行:
curl -X POST "$IM_API/$ORG/$APP/game/rooms/demo-match-1/close" \
-H "Authorization: Bearer $APP_TOKEN" -H "Content-Type: application/json" \
-d '{"reason":"对局结束","result":{"winner":"alice"}}'返回 202。兩個頁面的 onClose 收到 reason 為 room_closed、result 為 { winner: 'alice' },SDK 不再重連。
6. 接收結算回撥
在控制台「回撥」頁新增你的回撥地址,訂閱 game_room.closed。房間結束後幾秒內你會收到這樣的事件(只列出主要欄位):

{
"type": "game_room.closed",
"data": {
"room_id": "demo-match-1",
"close_reason": "closed_by_server",
"duration_ms": 95000,
"result": { "winner": "alice" },
"members": [
{ "username": "alice", "seat": 0, "connected_ms": 98000, "billable_minutes": 2, "leave_reason": "room_closed" },
{ "username": "bob", "seat": 1, "connected_ms": 97000, "billable_minutes": 2, "leave_reason": "room_closed" }
]
}
}加入失敗時
先看 im.game.errorKind(err) 的分類,再按這個順序檢查:
| 分類 | 先查什麼 |
|---|---|
game_disabled | 套餐是否包含遊戲房間、平臺是否開放、應用是否被單獨關閉 |
ticket_invalid | 票據是否給了正確的使用者、是否過期或已經用過;讓你的服務端重新簽發 |
room_closed | 房間 ID 是否正確,房間是否已經結束 |
room_full、joined_on_other_device | 座位是否已滿,這個使用者是否已在別的裝置上加入 |
node_unavailable、network | 稍後重試;仍然失敗時記下錯誤碼和請求 ID 聯絡我們 |
完整的錯誤表見 Web 客戶端接入。
