// 房间行为助手 import { EVENT, CODEMEG } from "../../enum/index.js"; import { updateUser, removeRoomAllUsers, getAllRoomUsers, updateRoomUser } from "../../service/userService.js"; import { setRoomConfig, getRoomConfig } from "../../service/roomConfigService.js"; import { subClient } from "../../connection/redis.js"; export class RoomAssistant { constructor(socket, redis, room) { this.socket = socket; this.redis = redis; this.roomId = null; this.room = room; } async prepearRoom(roomSessionId, roomId) { const uRoomId = await this.redis.get(roomSessionId); const mergeRoomId = uRoomId || roomId; this.roomId = mergeRoomId; console.log("prepearRoom", roomSessionId, this.roomId); await this.redis.set(roomSessionId, mergeRoomId); return Promise.resolve(this.roomId); } async destoryRoom(roomSessionId, roomConfigId) { console.log("destoryRoom", roomSessionId, roomConfigId); await this.redis.del(roomSessionId); await this.redis.del(roomConfigId); this.disconnect(); return Promise.resolve(true); } /** * kickPersion LEADER or assistant 房主或助手 */ async kickPersion(roomId, userId) { const hasJoin = await this.redis.HVALS(roomId, userId); if (hasJoin.length > 0) { await this.redis.hDel(roomId, userId); } } /** * 创建房间 LEADER or assistant 房主或助手 * @param {*string} roomId * @param {*string} userId * @param {*Object} user */ async buildRoom(roomId, userId, user) { const hasJoin = await this.redis.HVALS(roomId, userId); if (hasJoin.length === 0) { this.room.logger.info("buildRoom", { roomId }); await this.redis.hSet(roomId, userId, JSON.stringify(user)); } } /** * 关闭房间 * @param {*} roomId */ async removeRoom(roomId) { this.room.logger.info("removeRoom", { roomId }); await this.redis.del(roomId); } // /** // * 加入房间 // * @param {*} roomId // * @param {*} userId // * @param {*} user // */ // async joinRoom(roomId, userId, user) { // this.room.logger.info("joinRoom", { roomId }); // try { // const hasRoom = await this.redis.exists(roomId); // if (hasRoom) { // await this.redis.hSet(roomId, userId, JSON.stringify(user)); // } else { // this.room.logger.info("no room join"); // } // return Promise.resolve(); // } catch (error) { // this.room.logger.error(error); // return Promise.reject(error); // } // } /** * 加入房间 * @param {*} roomId * @param {*} userId * @param {*} user */ async joinRoom(roomId, userId, user) { const hasRoom = await this.redis.exists(roomId); const isJoinRoom = await this.redis.hExists(roomId, userId); if (hasRoom) { await this.redis.hSet(roomId, userId, JSON.stringify(user)); } else { this.room.logger.error("不存在房间", roomId); } if (!isJoinRoom) { this.room.logger.info("加入房间 :", { userId, roomId, user }); this.socket.join(roomId); const AllRoomUsers = await getAllRoomUsers(roomId); const roomConfig = await getRoomConfig(roomId); this.socket.broadcast.emit(EVENT.roomIn, { user, roomsPerson: AllRoomUsers, roomsConfig: roomConfig, }); } else { this.room.logger.info(`已加入房间 :`, { userId }); } } /** * 离开房间 * @param {*} roomId * @param {*} userId * @param {*} user */ async leaveRoom(roomId, userId, user) { try { await this.redis.hDel(roomId, userId); this.room.logger.info("离开房间", userId, AllRoomUsers); const AllRoomUsers = await getAllRoomUsers(roomId); const roomConfig = await getRoomConfig(roomId); this.socket.broadcast.to(roomId).emit(EVENT.roomOut, { user, roomsPerson: AllRoomUsers, roomsConfig: roomConfig, }); this.socket.broadcast.to(roomId).emit(EVENT.someOneLeaveRoom, { user, roomsPerson: AllRoomUsers, }); await this.socket.leave(roomId); } catch (error) { console.log("leaveRoom::error", error); } } /** * 房主关闭房间 * @param {*} clientRoom * @param {*} userUniqueId * @param {*} roomUniqueId */ async closeRoom(roomId, userId, user) { try { this.room.logger.info("房主关闭房间", userId); console.log("isInRoom", this.socket.rooms.has(roomId)); this.socket.broadcast.to(roomId).emit(EVENT.roomClose, { code: 3002, msg: CODEMEG[3002] }); await removeRoomAllUsers(roomId); this.socket.leave(roomId); } catch (error) { this.room.logger.error("RoomAssistant::closeRoom", error); } } /** * 呼叫房间 * @param {*} roomId * @param {*} userId * @param {*} user */ async startCall(roomId, userId, user) { try { if (!this.room.isHoster(user.role)) { this.room.logger.info("不是房主", JSON.stringify(user)); await this.joinRoom(roomId, userId, user); } else { const hasRoom = await this.redis.hVals(roomId); if (hasRoom.length === 0) { this.room.logger.info("房主主动创建房间 :", { roomId, userId }); await this.buildRoom(roomId, userId, user); } else { this.room.logger.info("房主已存在房间 :", { roomId, userId }); } } user.isInRoom = true; const AllRoomUsers = await getAllRoomUsers(roomId); const roomConfig = await getRoomConfig(roomId); await updateRoomUser(roomId, userId, user); this.room.logger.info("roomId", roomId); this.room.logger.info("AllRoomUsers", AllRoomUsers.length); this.socket.emit(EVENT.roomIn, { user, roomsPerson: AllRoomUsers, roomsConfig: roomConfig, }); this.socket.broadcast.to(roomId).emit(EVENT.someOneInRoom, { user, roomsPerson: AllRoomUsers, }); } catch (error) { this.room.logger.error("assistant::startCall:", error); } } /** * 关闭呼叫房间 * @param {*} roomId * @param {*} userId * @param {*} user */ stopCall(roomId, userId, user) { if (!this.room.isHoster(user.role)) { this.leaveRoom(roomId, userId, user); } else { this.closeRoom(roomId, userId, user); } } // 主动断开 async disconnect() { const syncId = this.room.syncId; const roomId = this.room.roomId; const userId = this.room.userId; this.socket.leave(syncId); this.socket.leave(roomId); await this.redis.del(syncId); await this.redis.del(userId); } // RoomSessionId 房间有效时间 setRoomUnlimit(roomSessionId) { return this.redis.expire(roomSessionId, -1); } setRoomAvailableBySeconds(roomSessionId, seconds) { return this.redis.expire(roomSessionId, seconds); } setRoomAvailableByHours(roomSessionId, hours) { return this.redis.expire(roomSessionId, 60 * 60 * hours); } watchRoomExpired(callback) { subClient.subscribe("__keyevent@0__:expired", this.watchRoomExpiredFn); } async watchRoomExpiredFn(key) { console.log("key=> ", key); } unWatchRoomExpired() { subClient.unsubscribe("__keyevent@0__:expired", this.watchRoomExpiredFn); } }