feat(api): collab 房间管理与 Yjs 帧转发
accept 时按库里的 adminType 复核身份,房间以学生为键。 服务端只按房间转发二进制帧,不解析内容。 老师掉线请求退回排队,学生掉线请求随人清除。 顺带处理三项 Task 2 评审遗留: - TEACHER_ROLES 去重,handler.ts 改为从 routes/helpers.ts 导入,不再自留一份 - 补全学生排队中断线(尚未进房间)的清理分支,避免陈旧请求卡死在列表里 - 修正 websocket.ts 里一处过期注释:username/adminType 是三种 kind 都会填, 不是只有 collab 才填 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K1d8B3f4SXJwDvUY625eQd
This commit is contained in:
@@ -76,8 +76,38 @@ export function teacherSockets() {
|
||||
return teachers
|
||||
}
|
||||
|
||||
export interface Room {
|
||||
/** 房主 = 学生。房间以学生为键,因为学生的代码是内容源 */
|
||||
studentId: number
|
||||
teacherId: number
|
||||
studentSocket: CollabSocket
|
||||
teacherSocket: CollabSocket
|
||||
problemId: string
|
||||
}
|
||||
|
||||
const rooms = new Map<number, Room>()
|
||||
|
||||
export function openRoom(room: Room) {
|
||||
rooms.set(room.studentId, room)
|
||||
}
|
||||
|
||||
export function getRoom(studentId: number) {
|
||||
return rooms.get(studentId)
|
||||
}
|
||||
|
||||
export function closeRoom(studentId: number) {
|
||||
return rooms.delete(studentId)
|
||||
}
|
||||
|
||||
/** 这条连接当前所在的房间。ws.data.roomOwnerId 是房主(学生)的 id */
|
||||
export function roomOf(ws: CollabSocket) {
|
||||
const ownerId = ws.data.roomOwnerId
|
||||
return ownerId === undefined ? undefined : rooms.get(ownerId)
|
||||
}
|
||||
|
||||
/** 仅供进程退出或测试用,正常路径不该调 */
|
||||
export function resetCollabState() {
|
||||
requests.clear()
|
||||
teachers.clear()
|
||||
rooms.clear()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user