Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
paopao
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
cocktail-party
paopao
Commits
9f99317e
提交
9f99317e
authored
4月 02, 2026
作者:
lidongxu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
封版2.0
上级
9a27f2a4
显示空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
57 行增加
和
6 行删除
+57
-6
socket.js
big-screen/src/socket.js
+5
-1
screens.js
server/src/routes/screens.js
+9
-0
roomHandler.js
server/src/socket/roomHandler.js
+26
-5
screenHandler.js
server/src/socket/screenHandler.js
+17
-0
没有找到文件。
big-screen/src/socket.js
浏览文件 @
9f99317e
...
...
@@ -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
}
...
...
server/src/routes/screens.js
浏览文件 @
9f99317e
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
);
...
...
server/src/socket/roomHandler.js
浏览文件 @
9f99317e
...
...
@@ -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
};
server/src/socket/screenHandler.js
浏览文件 @
9f99317e
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
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论