观影室增加屏幕共享
This commit is contained in:
@@ -16,6 +16,8 @@ export class WatchRoomServer {
|
||||
private rooms: Map<string, Room> = new Map();
|
||||
private members: Map<string, Map<string, Member>> = new Map(); // roomId -> userId -> Member
|
||||
private socketToRoom: Map<string, RoomMemberInfo> = new Map(); // socketId -> RoomMemberInfo
|
||||
private screenHelpers: Map<string, string> = new Map(); // roomId -> helperSocketId
|
||||
private helperToRoom: Map<string, string> = new Map(); // helperSocketId -> roomId
|
||||
private cleanupInterval: NodeJS.Timeout | null = null;
|
||||
|
||||
constructor(private io: SocketIOServer<ClientToServerEvents, ServerToClientEvents>) {
|
||||
@@ -40,6 +42,7 @@ export class WatchRoomServer {
|
||||
description: data.description,
|
||||
password: data.password,
|
||||
isPublic: data.isPublic,
|
||||
roomType: data.roomType || 'sync',
|
||||
ownerId: userId,
|
||||
ownerName: data.userName,
|
||||
ownerToken: ownerToken, // 保存房主令牌
|
||||
@@ -199,6 +202,111 @@ export class WatchRoomServer {
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('screen:helper-register', (data, callback) => {
|
||||
try {
|
||||
const room = this.rooms.get(data.roomId);
|
||||
if (!room) {
|
||||
callback({ success: false, error: '房间不存在' });
|
||||
return;
|
||||
}
|
||||
|
||||
if (room.ownerToken !== data.ownerToken) {
|
||||
callback({ success: false, error: '房主身份验证失败' });
|
||||
return;
|
||||
}
|
||||
|
||||
const oldHelperSocketId = this.screenHelpers.get(data.roomId);
|
||||
if (oldHelperSocketId && oldHelperSocketId !== socket.id) {
|
||||
this.helperToRoom.delete(oldHelperSocketId);
|
||||
}
|
||||
|
||||
this.screenHelpers.set(data.roomId, socket.id);
|
||||
this.helperToRoom.set(socket.id, data.roomId);
|
||||
callback({ success: true });
|
||||
} catch (error) {
|
||||
console.error('[WatchRoom] Error registering screen helper:', error);
|
||||
callback({ success: false, error: '注册共享控制窗口失败' });
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('screen:start', (state) => {
|
||||
const roomInfo = this.socketToRoom.get(socket.id);
|
||||
const helperRoomId = this.helperToRoom.get(socket.id);
|
||||
const roomId = roomInfo?.roomId || helperRoomId;
|
||||
if (!roomId) return;
|
||||
if (helperRoomId && this.screenHelpers.get(helperRoomId) !== socket.id) return;
|
||||
if (roomInfo && !roomInfo.isOwner) return;
|
||||
|
||||
const room = this.rooms.get(roomId);
|
||||
if (room) {
|
||||
room.currentState = state;
|
||||
this.rooms.set(roomId, room);
|
||||
this.io.to(roomId).emit('screen:start', state);
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('screen:stop', () => {
|
||||
const roomInfo = this.socketToRoom.get(socket.id);
|
||||
const helperRoomId = this.helperToRoom.get(socket.id);
|
||||
const roomId = roomInfo?.roomId || helperRoomId;
|
||||
if (!roomId) return;
|
||||
if (helperRoomId && this.screenHelpers.get(helperRoomId) !== socket.id) return;
|
||||
if (roomInfo && !roomInfo.isOwner) return;
|
||||
|
||||
const room = this.rooms.get(roomId);
|
||||
if (room) {
|
||||
room.currentState = null;
|
||||
this.rooms.set(roomId, room);
|
||||
this.io.to(roomId).emit('screen:stop');
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('screen:viewer-ready', () => {
|
||||
const roomInfo = this.socketToRoom.get(socket.id);
|
||||
if (!roomInfo) return;
|
||||
|
||||
const room = this.rooms.get(roomInfo.roomId);
|
||||
if (!room || roomInfo.isOwner || room.currentState?.type !== 'screen') return;
|
||||
|
||||
const targetSocketId = this.screenHelpers.get(roomInfo.roomId) || room.ownerId;
|
||||
this.io.to(targetSocketId).emit('screen:viewer-ready', {
|
||||
userId: socket.id,
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('screen:offer', (data) => {
|
||||
const roomInfo = this.socketToRoom.get(socket.id);
|
||||
const helperRoomId = this.helperToRoom.get(socket.id);
|
||||
if (!roomInfo && !helperRoomId) return;
|
||||
|
||||
this.io.to(data.targetUserId).emit('screen:offer', {
|
||||
userId: socket.id,
|
||||
offer: data.offer,
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('screen:answer', (data) => {
|
||||
const roomInfo = this.socketToRoom.get(socket.id);
|
||||
const helperRoomId = this.helperToRoom.get(socket.id);
|
||||
if (!roomInfo && !helperRoomId) return;
|
||||
|
||||
this.io.to(data.targetUserId).emit('screen:answer', {
|
||||
userId: socket.id,
|
||||
answer: data.answer,
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('screen:ice', (data) => {
|
||||
const roomInfo = this.socketToRoom.get(socket.id);
|
||||
const helperRoomId = this.helperToRoom.get(socket.id);
|
||||
if (!roomInfo && !helperRoomId) return;
|
||||
|
||||
this.io.to(data.targetUserId).emit('screen:ice', {
|
||||
userId: socket.id,
|
||||
candidate: data.candidate,
|
||||
});
|
||||
});
|
||||
|
||||
// 聊天消息
|
||||
socket.on('chat:message', (data) => {
|
||||
const roomInfo = this.socketToRoom.get(socket.id);
|
||||
@@ -303,6 +411,19 @@ export class WatchRoomServer {
|
||||
// 断开连接
|
||||
socket.on('disconnect', () => {
|
||||
console.log(`[WatchRoom] Client disconnected: ${socket.id}`);
|
||||
const helperRoomId = this.helperToRoom.get(socket.id);
|
||||
if (helperRoomId) {
|
||||
this.helperToRoom.delete(socket.id);
|
||||
if (this.screenHelpers.get(helperRoomId) === socket.id) {
|
||||
this.screenHelpers.delete(helperRoomId);
|
||||
const room = this.rooms.get(helperRoomId);
|
||||
if (room && room.currentState?.type === 'screen') {
|
||||
room.currentState = null;
|
||||
this.rooms.set(helperRoomId, room);
|
||||
this.io.to(helperRoomId).emit('screen:stop');
|
||||
}
|
||||
}
|
||||
}
|
||||
this.handleLeaveRoom(socket);
|
||||
});
|
||||
});
|
||||
@@ -348,6 +469,11 @@ export class WatchRoomServer {
|
||||
this.io.to(roomId).emit('room:deleted');
|
||||
this.rooms.delete(roomId);
|
||||
this.members.delete(roomId);
|
||||
const helperSocketId = this.screenHelpers.get(roomId);
|
||||
if (helperSocketId) {
|
||||
this.helperToRoom.delete(helperSocketId);
|
||||
this.screenHelpers.delete(roomId);
|
||||
}
|
||||
}
|
||||
|
||||
// 定时清理房间(房主断开5分钟后删除)
|
||||
|
||||
Reference in New Issue
Block a user