|
|
@@ -4619,18 +4619,18 @@ const createWebSocketConnection = async (type = 1) => {
|
|
|
const isReplay = subType === 1
|
|
|
const timerTypes = ['timer_start', 'timer_pause', 'timer_reset', 'timer_stop', 'timer_finish', 'timer_update']
|
|
|
const writingBoardTypes = ['writing_board_update', 'writing_board_close', 'writing_board_blackboard']
|
|
|
- for (const obj of objs) {
|
|
|
- // 过滤掉不带业务字段的
|
|
|
- if (!obj.type && obj.slideIndex === undefined) continue
|
|
|
- // mId 过滤,跳过自己发的
|
|
|
- if (obj.mId && obj.mId === mId.value) continue
|
|
|
- // 历史重放的计时器消息直接跳过(学生刷新时服务器会把旧的 timer_stop 一起重放)
|
|
|
- if (isReplay && typeof obj.type === 'string' && obj.type.startsWith('timer_')) continue
|
|
|
-
|
|
|
- console.log('📨 解析业务消息:', obj)
|
|
|
- // 简化判断逻辑:writingBoard 类型永远跳过 getMessages;
|
|
|
- // timer 类型仅在非创建人时才走 getMessages;其余类型一律走 getMessages
|
|
|
- getMessages(obj)
|
|
|
+ // 过滤出有效业务消息:不带业务字段的、自己发的、历史重放的 timer_* 全部剔除
|
|
|
+ const validObjs = objs.filter((obj: Record<string, any>) => {
|
|
|
+ if (!obj.type && obj.slideIndex === undefined) return false
|
|
|
+ if (obj.mId && obj.mId === mId.value) return false
|
|
|
+ if (isReplay && typeof obj.type === 'string' && obj.type.startsWith('timer_')) return false
|
|
|
+ return true
|
|
|
+ })
|
|
|
+ // 一次 update 可能带多个 struct(同一 Map 多次 set),只取最后一条处理
|
|
|
+ const lastObj = validObjs[validObjs.length - 1]
|
|
|
+ if (lastObj) {
|
|
|
+ console.log('📨 解析业务消息:', lastObj)
|
|
|
+ getMessages(lastObj)
|
|
|
}
|
|
|
|
|
|
// ★ 消息处理后检查特殊消息数组长度,超出则清理(替代 observe 里的清理逻辑)
|