134 lines
3.7 KiB
JavaScript
Executable File
134 lines
3.7 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
/**
|
|
* Reconnect 测试脚本
|
|
* 1. 连接玩家
|
|
* 2. 加入匹配
|
|
* 3. 等待匹配完成后,模拟断线并重新连接,使用相同的 game_token 重新加入同一场比赛
|
|
*/
|
|
|
|
const WebSocket = require('ws');
|
|
|
|
// 请根据实际情况修改以下配置
|
|
const NAKAMA_HOST = 'ws://127.0.0.1:7350/ws'; // 本地 Nakama 地址
|
|
const NUM_PLAYERS = 2; // 只测试 2 人即可
|
|
|
|
// 这里需要填入真实的 Nakama 认证 token 和 game_token
|
|
const NAKAMA_TOKENS = [
|
|
'YOUR_NAKAMA_TOKEN_1',
|
|
'YOUR_NAKAMA_TOKEN_2',
|
|
];
|
|
const GAME_TOKENS = [
|
|
'YOUR_GAME_TOKEN_1',
|
|
'YOUR_GAME_TOKEN_2',
|
|
];
|
|
|
|
class TestPlayer {
|
|
constructor(id, nakamaToken, gameToken) {
|
|
this.id = id;
|
|
this.nakamaToken = nakamaToken;
|
|
this.gameToken = gameToken;
|
|
this.ws = null;
|
|
this.matchId = null;
|
|
}
|
|
|
|
connect() {
|
|
return new Promise((resolve, reject) => {
|
|
const url = `${NAKAMA_HOST}?token=${this.nakamaToken}&format=json`;
|
|
this.ws = new WebSocket(url);
|
|
this.ws.on('open', () => {
|
|
console.log(`[${this.id}] ✅ WS connected`);
|
|
resolve();
|
|
});
|
|
this.ws.on('message', (data) => this.handleMessage(JSON.parse(data)));
|
|
this.ws.on('error', (e) => reject(e));
|
|
});
|
|
}
|
|
|
|
handleMessage(msg) {
|
|
if (msg.matchmaker_matched) {
|
|
this.matchId = msg.matchmaker_matched.match_id;
|
|
console.log(`[${this.id}] 🎮 Matched, matchId=${this.matchId}`);
|
|
// 自动加入
|
|
setTimeout(() => this.joinMatch(this.matchId), 100);
|
|
}
|
|
if (msg.match) {
|
|
console.log(`[${this.id}] ✅ Joined match ${msg.match.match_id}`);
|
|
}
|
|
if (msg.error) {
|
|
console.error(`[${this.id}] ❌ Error: ${msg.error.message}`);
|
|
}
|
|
}
|
|
|
|
addToMatchmaker() {
|
|
const req = {
|
|
cid: `${this.id}_mm`,
|
|
matchmaker_add: {
|
|
min_count: NUM_PLAYERS,
|
|
max_count: NUM_PLAYERS,
|
|
query: '*',
|
|
string_properties: { game_token: this.gameToken },
|
|
},
|
|
};
|
|
this.ws.send(JSON.stringify(req));
|
|
console.log(`[${this.id}] 🔍 Added to matchmaker`);
|
|
}
|
|
|
|
joinMatch(matchId) {
|
|
const req = {
|
|
cid: `${this.id}_join`,
|
|
match_join: {
|
|
match_id: matchId,
|
|
metadata: { game_token: this.gameToken },
|
|
},
|
|
};
|
|
this.ws.send(JSON.stringify(req));
|
|
console.log(`[${this.id}] 🚪 Joining match ${matchId}`);
|
|
}
|
|
|
|
disconnect() {
|
|
if (this.ws) {
|
|
this.ws.close();
|
|
this.ws = null;
|
|
}
|
|
console.log(`[${this.id}] 🔌 Disconnected`);
|
|
}
|
|
}
|
|
|
|
async function sleep(ms) { return new Promise(r => setTimeout(r, ms)); }
|
|
|
|
(async () => {
|
|
const players = [];
|
|
for (let i = 0; i < NUM_PLAYERS; i++) {
|
|
players.push(new TestPlayer(i + 1, NAKAMA_TOKENS[i], GAME_TOKENS[i]));
|
|
}
|
|
|
|
// 1. 连接
|
|
await Promise.all(players.map(p => p.connect()));
|
|
|
|
// 2. 加入匹配队列
|
|
players.forEach(p => p.addToMatchmaker());
|
|
|
|
// 等待匹配完成
|
|
await sleep(15000);
|
|
|
|
// 3. 模拟断线并重连(只对第一个玩家演示)
|
|
const p = players[0];
|
|
console.log(`\n🔌 模拟玩家 ${p.id} 断线`);
|
|
const oldMatchId = p.matchId;
|
|
p.disconnect();
|
|
await sleep(2000);
|
|
console.log(`🔁 重新连接玩家 ${p.id}`);
|
|
await p.connect();
|
|
// 使用相同的 game_token 重新加入同一场比赛
|
|
if (oldMatchId) {
|
|
p.joinMatch(oldMatchId);
|
|
}
|
|
|
|
// 等待几秒观察结果
|
|
await sleep(10000);
|
|
|
|
// 清理
|
|
players.forEach(p => p.disconnect());
|
|
console.log('✅ 测试结束');
|
|
})();
|