fix: 优化 WebSocket 连接和游戏重连逻辑,并改进回合计时器同步及用户操作反馈。
This commit is contained in:
parent
413f7557f1
commit
75b6ef7809
@ -615,6 +615,9 @@ export default {
|
|||||||
|
|
||||||
// 自动重连
|
// 自动重连
|
||||||
try {
|
try {
|
||||||
|
if (this._isReconnecting) return;
|
||||||
|
this._isReconnecting = true;
|
||||||
|
|
||||||
console.log('[重连] 开始重新连接...');
|
console.log('[重连] 开始重新连接...');
|
||||||
const session = await nakamaManager.authenticateWithGameToken(this.gameToken, this.stableUserId);
|
const session = await nakamaManager.authenticateWithGameToken(this.gameToken, this.stableUserId);
|
||||||
this.myUserId = session.user_id;
|
this.myUserId = session.user_id;
|
||||||
@ -636,6 +639,8 @@ export default {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('[重连] 失败:', e);
|
console.error('[重连] 失败:', e);
|
||||||
this.addLog('system', `❌ 重连失败: ${e.message}`);
|
this.addLog('system', `❌ 重连失败: ${e.message}`);
|
||||||
|
} finally {
|
||||||
|
this._isReconnecting = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -666,6 +671,8 @@ export default {
|
|||||||
|
|
||||||
if (opCode === 1) {
|
if (opCode === 1) {
|
||||||
this.gameState = data;
|
this.gameState = data;
|
||||||
|
const limit = data.turnDuration || 15;
|
||||||
|
this.resetTurnTimer(limit, limit);
|
||||||
this.addLog('system', '战局开始,准备翻格!');
|
this.addLog('system', '战局开始,准备翻格!');
|
||||||
} else if (opCode === 2) {
|
} else if (opCode === 2) {
|
||||||
// 状态更新 - 检测 HP 变化触发特效
|
// 状态更新 - 检测 HP 变化触发特效
|
||||||
@ -691,10 +698,13 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.gameState = data;
|
// 收到状态更新时重置计时器(使用服务器时间校准)
|
||||||
// 收到状态更新时重置计时器(处理重连场景)
|
|
||||||
if (data.gameStarted) {
|
if (data.gameStarted) {
|
||||||
this.resetTurnTimer();
|
const serverTime = data.serverTime || Math.floor(Date.now() / 1000);
|
||||||
|
const elapsed = serverTime - (data.lastMoveTimestamp || serverTime);
|
||||||
|
const limit = data.turnDuration || 15;
|
||||||
|
const remaining = Math.max(0, limit - elapsed);
|
||||||
|
this.resetTurnTimer(remaining, limit);
|
||||||
}
|
}
|
||||||
} else if (opCode === 5) {
|
} else if (opCode === 5) {
|
||||||
this.handleEvent(data);
|
this.handleEvent(data);
|
||||||
@ -817,9 +827,15 @@ export default {
|
|||||||
handleCellClick(idx) {
|
handleCellClick(idx) {
|
||||||
// 前置条件检查
|
// 前置条件检查
|
||||||
if (this.isSpectator) return;
|
if (this.isSpectator) return;
|
||||||
if (!this.gameState?.gameStarted) return;
|
if (!this.gameState?.gameStarted) {
|
||||||
|
uni.showToast({ title: '游戏尚未开始', icon: 'none' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (this.showResultModal || this.showSettlement) return;
|
if (this.showResultModal || this.showSettlement) return;
|
||||||
if (!this.isMyTurn) return;
|
if (!this.isMyTurn) {
|
||||||
|
uni.showToast({ title: '等待对方行动...', icon: 'none' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (this.gameState.grid[idx].revealed) return;
|
if (this.gameState.grid[idx].revealed) return;
|
||||||
|
|
||||||
// 发送移动指令
|
// 发送移动指令
|
||||||
@ -832,8 +848,9 @@ export default {
|
|||||||
closeResultModal() {
|
closeResultModal() {
|
||||||
this.showResultModal = false;
|
this.showResultModal = false;
|
||||||
},
|
},
|
||||||
resetTurnTimer() {
|
resetTurnTimer(initialTime, limit) {
|
||||||
this.turnTimer = 15;
|
const turnLimit = limit || (this.gameState?.turnDuration) || 15;
|
||||||
|
this.turnTimer = Math.floor(initialTime !== undefined ? initialTime : turnLimit);
|
||||||
clearInterval(this.turnInterval);
|
clearInterval(this.turnInterval);
|
||||||
this.turnInterval = setInterval(() => {
|
this.turnInterval = setInterval(() => {
|
||||||
if (this.turnTimer > 0) this.turnTimer--;
|
if (this.turnTimer > 0) this.turnTimer--;
|
||||||
|
|||||||
@ -15,6 +15,7 @@ class NakamaManager {
|
|||||||
this.gameToken = null;
|
this.gameToken = null;
|
||||||
this.socketTask = null;
|
this.socketTask = null;
|
||||||
this.isConnected = false;
|
this.isConnected = false;
|
||||||
|
this.isConnecting = false; // 正在连接标志位
|
||||||
|
|
||||||
// 消息 ID 和待处理的 Promise
|
// 消息 ID 和待处理的 Promise
|
||||||
this.nextCid = 1;
|
this.nextCid = 1;
|
||||||
@ -132,7 +133,24 @@ class NakamaManager {
|
|||||||
* 建立 WebSocket 连接
|
* 建立 WebSocket 连接
|
||||||
*/
|
*/
|
||||||
_connectWebSocket() {
|
_connectWebSocket() {
|
||||||
|
if (this.isConnecting) {
|
||||||
|
console.log('[Nakama] Already connecting, skipping...');
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
// 确保清理旧连接
|
||||||
|
if (this.socketTask) {
|
||||||
|
console.log('[Nakama] Closing existing socket before new connection');
|
||||||
|
try {
|
||||||
|
this.socketTask.close();
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('[Nakama] Error closing old socket:', e);
|
||||||
|
}
|
||||||
|
this.socketTask = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isConnecting = true;
|
||||||
const scheme = this.useSSL ? 'wss://' : 'ws://';
|
const scheme = this.useSSL ? 'wss://' : 'ws://';
|
||||||
const portSuffix = (this.useSSL && this.port === '443') || (!this.useSSL && this.port === '80') ? '' : `:${this.port}`;
|
const portSuffix = (this.useSSL && this.port === '443') || (!this.useSSL && this.port === '80') ? '' : `:${this.port}`;
|
||||||
const wsUrl = `${scheme}${this.host}${portSuffix}/ws?lang=en&status=true&token=${encodeURIComponent(this.session.token)}`;
|
const wsUrl = `${scheme}${this.host}${portSuffix}/ws?lang=en&status=true&token=${encodeURIComponent(this.session.token)}`;
|
||||||
@ -151,6 +169,7 @@ class NakamaManager {
|
|||||||
this.socketTask.onOpen(() => {
|
this.socketTask.onOpen(() => {
|
||||||
clearTimeout(connectTimeout);
|
clearTimeout(connectTimeout);
|
||||||
this.isConnected = true;
|
this.isConnected = true;
|
||||||
|
this.isConnecting = false;
|
||||||
console.log('[Nakama] WebSocket connected');
|
console.log('[Nakama] WebSocket connected');
|
||||||
this._startHeartbeat();
|
this._startHeartbeat();
|
||||||
resolve();
|
resolve();
|
||||||
@ -169,6 +188,7 @@ class NakamaManager {
|
|||||||
clearTimeout(connectTimeout);
|
clearTimeout(connectTimeout);
|
||||||
console.error('[Nakama] WebSocket error:', err);
|
console.error('[Nakama] WebSocket error:', err);
|
||||||
this.isConnected = false;
|
this.isConnected = false;
|
||||||
|
this.isConnecting = false;
|
||||||
if (this.listeners.onerror) {
|
if (this.listeners.onerror) {
|
||||||
this.listeners.onerror(err);
|
this.listeners.onerror(err);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user