提交 9f99317e authored 作者: lidongxu's avatar lidongxu

封版2.0

上级 9a27f2a4
......@@ -188,7 +188,7 @@ function _dispatch(event, data) {
case 'room:gameStart': {
console.log('[Socket] room:gameStart')
clearCountdown()
setRoomTimer(data?.gameDuration ?? 0)
setRoomTimer(data?.gameDuration ?? 0, data?.startAtMs ?? Date.now())
break
}
......@@ -205,6 +205,10 @@ function _dispatch(event, data) {
case 'screen:joined': {
console.log('[Socket] 大屏注册成功:', data)
clearCountdown()
clearRoomTimer()
setCurrentRoom(data?.currentRoomId ?? null)
if (!data?.currentRoomId) clearGameState()
break
}
......
const express = require('express');
const { sendToScreen, joinRoom, leaveAllRooms, screenSockets } = require('../socket');
const { getRoomTimerSnapshot } = require('../socket/roomHandler');
const router = express.Router();
const prisma = require('../prisma/client');
......@@ -41,6 +42,14 @@ router.post('/:screenId/bindRoom', async (req, res, next) => {
if (roomId) joinRoom(targetWs, roomId);
// 通知大屏
targetWs.sendEvent('screen:roomChanged', { roomId: roomId || null });
const timerSnapshot = getRoomTimerSnapshot(roomId);
if (timerSnapshot) {
targetWs.sendEvent('room:gameStart', {
roomId: timerSnapshot.roomId,
gameDuration: timerSnapshot.durationSec,
startAtMs: timerSnapshot.startAtMs,
});
}
}
res.json(screen);
......
......@@ -457,12 +457,13 @@ function _startGameCountdown(roomId, gameDuration, sessionId, broadcastToRoom) {
// 倒计时结束,广播 room:gameStart
clearInterval(timer);
countdownTimers.delete(roomId);
broadcastToRoom(roomId, 'room:gameStart', { roomId, sessionId, gameDuration });
const startAtMs = Date.now();
broadcastToRoom(roomId, 'room:gameStart', { roomId, sessionId, gameDuration, startAtMs });
console.log(`[Room] 房间 ${roomId} 倒计时结束,游戏开始`);
// 游戏正式开始后才启动游戏时长计时器
if (gameDuration > 0) {
_startRoomTimer(roomId, gameDuration, sessionId, broadcastToRoom);
_startRoomTimer(roomId, gameDuration, sessionId, broadcastToRoom, startAtMs);
}
}
}, 1000);
......@@ -485,11 +486,11 @@ function _clearGameCountdown(roomId) {
* 启动房间服务端倒计时
* 时间到后广播 room:timeUp 给房间内所有人(小游戏 + 大屏)
*/
function _startRoomTimer(roomId, durationSec, sessionId, broadcastToRoom) {
function _startRoomTimer(roomId, durationSec, sessionId, broadcastToRoom, startAtMs = Date.now()) {
// 清理旧计时器
_clearRoomTimer(roomId);
const startTime = Date.now();
const startTime = startAtMs;
const timer = setTimeout(async () => {
console.log(`[Room] 房间 ${roomId} 时间到,广播 room:timeUp`);
......@@ -536,6 +537,26 @@ function _clearRoomTimer(roomId) {
}
}
function getRoomTimerSnapshot(roomId, now = Date.now()) {
const entry = roomTimers.get(String(roomId));
if (!entry) return null;
const durationSec = Number(entry.durationSec) || 0;
const startAtMs = Number(entry.startTime) || 0;
if (durationSec <= 0 || startAtMs <= 0) return null;
const elapsedSec = Math.max(0, Math.floor((now - startAtMs) / 1000));
const remainingSec = Math.max(0, durationSec - elapsedSec);
if (remainingSec <= 0) return null;
return {
roomId: String(roomId),
durationSec,
startAtMs,
remainingSec,
};
}
/**
* 查询等待中房间的队伍人数情况
* @param {string} roomId
......@@ -553,4 +574,4 @@ function getWaitingRoomTeamInfo(roomId) {
return { teamA, teamB, totalSeats: waiting.totalSeats, perTeamSeats };
}
module.exports = { registerRoomHandlers, onRoomEmpty, getWaitingRoomTeamInfo };
module.exports = { registerRoomHandlers, onRoomEmpty, getWaitingRoomTeamInfo, getRoomTimerSnapshot };
const prisma = require('../prisma/client');
const { getRoomTimerSnapshot } = require('./roomHandler');
/**
* 注册大屏相关 WebSocket 事件处理
......@@ -49,6 +50,14 @@ function registerScreenHandlers(ws, { sendToScreen, joinRoom, leaveAllRooms, scr
screenName,
currentRoomId: screenConfig.currentRoomId,
});
const timerSnapshot = getRoomTimerSnapshot(screenConfig.currentRoomId);
if (timerSnapshot) {
ws.sendEvent('room:gameStart', {
roomId: timerSnapshot.roomId,
gameDuration: timerSnapshot.durationSec,
startAtMs: timerSnapshot.startAtMs,
});
}
} catch (err) {
console.error('[screen:join] 错误:', err);
ws.sendEvent('error', { message: '大屏注册失败' });
......@@ -80,6 +89,14 @@ function registerScreenHandlers(ws, { sendToScreen, joinRoom, leaveAllRooms, scr
}
// 通知大屏切换房间
targetWs.sendEvent('screen:roomChanged', { roomId: roomId || null });
const timerSnapshot = getRoomTimerSnapshot(roomId);
if (timerSnapshot) {
targetWs.sendEvent('room:gameStart', {
roomId: timerSnapshot.roomId,
gameDuration: timerSnapshot.durationSec,
startAtMs: timerSnapshot.startAtMs,
});
}
}
console.log(`[Screen] 绑定大屏 ${screenName} → 房间 ${roomId || '无'}`);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论