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

封版2.0

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