fix(collab): room_closed 无条件归位、断线重连补状态、学生 socket 重连迁移
Critical:room_closed 不再按 reason 挑着重置 helpStatus——学生自己的 socket 发送失败时服务端删了请求却发不出任何纠正帧,store 会卡在陈旧的 active/pending 上出不来。现在一律先归 idle,老师掉线那条路径服务端会紧跟着补一条 help_status:pending,同一条连接消息严格按序到达,不会被这次重置抢跑。 Critical:断线重连没有补状态。前端 CollabWebSocket 加 onConnected 钩子, 每次连接建立(含重连)都清空本地 requests/helpStatus/room,等服务端补发; 后端 handleCollabOpen 对非老师的重连方,如果这个账号名下还有请求, 补发对应的 help_status(pending 带重算的 queueAhead,active 带 teacherName)。 Critical:重连后请求仍绑在旧 socket 上,导致 handleHelpCancel 的归属校验 认不出新连接、后续通知也写进死连接。handleCollabOpen 里把请求和(如果有) 房间迁移到新 socket,并清掉旧 socket 的 roomOwnerId,防止它稍后的 close 反过来拆掉刚迁移出去的房间。 Minor:disconnect() 补齐 queueAhead/teacherName/notice 的重置,不留陈旧值。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K1d8B3f4SXJwDvUY625eQd
This commit is contained in:
@@ -63,6 +63,32 @@ export function handleCollabOpen(ws: CollabSocket) {
|
||||
ws.send(
|
||||
JSON.stringify({ type: "requests", list: listRequests().map(serializeRequest) }),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// 学生(重)连:如果这个账号名下已经有一条请求(掉线重连回来,或者干脆是
|
||||
// 同账号第二个标签页),把它迁移到这条新连接上,并把当前状态补发回去 ——
|
||||
// 前端 onConnected 时会先把本地状态清空等着这条补发,不发的话就永远卡在
|
||||
// idle;不迁移 socket 归属的话,旧连接一断,handleHelpCancel 的
|
||||
// `request.socket === ws` 校验就会认不出这条新连接发起的取消
|
||||
const request = getRequest(ws.data.userId)
|
||||
if (!request) return
|
||||
request.socket = ws
|
||||
|
||||
const room = getRoom(ws.data.userId)
|
||||
if (room && room.studentSocket !== ws) {
|
||||
// 旧 socket 不再是这间房的主人:清掉它的 roomOwnerId,不然它稍后触发的
|
||||
// close 会经 roomOf 认出这间刚刚转移出去的房间,把它拆了——一条早该
|
||||
// 死透的连接反而有权拆掉正在用的新连接的房间
|
||||
room.studentSocket.data.roomOwnerId = undefined
|
||||
room.studentSocket = ws
|
||||
ws.data.roomOwnerId = ws.data.userId
|
||||
}
|
||||
|
||||
if (request.status === "pending") {
|
||||
sendHelpStatus(ws, "pending", { queueAhead: queueAheadOf(ws.data.userId) })
|
||||
} else if (request.status === "active") {
|
||||
sendHelpStatus(ws, "active", { teacherName: request.teacherName ?? "" })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user