|
@@ -1,375 +1,381 @@
|
|
-// 房间行为助手
|
|
|
|
-import { EVENT, CODEMEG, FROMTYPE } from "../../enum/index.js";
|
|
|
|
-import { getCurrentUser, updateUser, removeRoomAllUsers, getAllRoomUsers, updateRoomUser, removeRoomUser } from "../../service/userService.js";
|
|
|
|
-import { setRoomConfig, getRoomConfig, isRoomMaster } from "../../service/roomConfigService.js";
|
|
|
|
-import { subClient } from "../../connection/redis.js";
|
|
|
|
-
|
|
|
|
-const prefix = process.env.REDIS_PREFIX || "chat";
|
|
|
|
-const getInKey = (realKey) => {
|
|
|
|
- return `${prefix}:${realKey}`;
|
|
|
|
-};
|
|
|
|
-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(getInKey(roomSessionId));
|
|
|
|
- const mergeRoomId = uRoomId || roomId;
|
|
|
|
- this.roomId = mergeRoomId;
|
|
|
|
- this.room.logger.info("prepearRoom", roomSessionId, this.roomId);
|
|
|
|
- await this.redis.set(getInKey(roomSessionId), mergeRoomId);
|
|
|
|
- return Promise.resolve(this.roomId);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- async destoryRoom(roomSessionId, roomConfigId) {
|
|
|
|
- this.room.logger.info("destoryRoom", roomSessionId, roomConfigId);
|
|
|
|
- await this.redis.del(getInKey(roomSessionId));
|
|
|
|
- await this.redis.del(getInKey(roomConfigId));
|
|
|
|
- this.disconnect();
|
|
|
|
- return Promise.resolve(true);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * kickPersion LEADER or assistant 房主或助手
|
|
|
|
- */
|
|
|
|
- async kickPersion(roomId, userId) {
|
|
|
|
- console.log("kickPersion", roomId, userId);
|
|
|
|
- getInKey(roomId);
|
|
|
|
- try {
|
|
|
|
- const hasJoin = await this.redis.HVALS(getInKey(roomId), userId);
|
|
|
|
- // const blackListId = ""
|
|
|
|
- if (hasJoin.length > 0) {
|
|
|
|
- await this.redis.hDel(getInKey(roomId), userId);
|
|
|
|
- return Promise.resolve(true);
|
|
|
|
- } else {
|
|
|
|
- return Promise.resolve(false);
|
|
|
|
- }
|
|
|
|
- } catch (error) {
|
|
|
|
- return Promise.resolve(false);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 设置助手 LEADER(权限) 房主或助手
|
|
|
|
- * @param {*} roomId
|
|
|
|
- * @param {*} userId
|
|
|
|
- */
|
|
|
|
- async setAssistant(roomId, userId, cancel) {
|
|
|
|
- try {
|
|
|
|
- const userRes = await getCurrentUser(roomId, userId, FROMTYPE.MiniAPP);
|
|
|
|
- const user = JSON.parse(userRes);
|
|
|
|
- const roomConfigRes = await getRoomConfig(roomId);
|
|
|
|
- if (this.room.userId == userId) {
|
|
|
|
- console.log("不能设置自己为助理!");
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- const role = cancel ? "customer" : "assistant";
|
|
|
|
- // assistant是助手,customer是普通角色,操作role会好些
|
|
|
|
- const userObj = Object.assign({}, user, { role: role, order: 1 });
|
|
|
|
- const roomObj = Object.assign({}, roomConfigRes, { assistantId: user.userId });
|
|
|
|
- // console.log("setAssistant", userObj, roomObj);
|
|
|
|
- // console.error("roomObj", roomObj);
|
|
|
|
- await updateRoomUser(roomId, userId, userObj);
|
|
|
|
- // // 更新roomConfig 设置助手id
|
|
|
|
- await setRoomConfig(roomId, roomObj);
|
|
|
|
- const AllRoomUsers = await getAllRoomUsers(roomId);
|
|
|
|
-
|
|
|
|
- // 同房间的其他人重置
|
|
|
|
- const resetOther = Array.from(AllRoomUsers)
|
|
|
|
- .filter((i) => i.role !== "leader" && i.userId !== userObj.userId)
|
|
|
|
- .map((roomer) => {
|
|
|
|
- const userKey = `user:${roomer.userId}`;
|
|
|
|
- const unsetUserObj = Object.assign({}, roomer, { role: "customer", order: 2 });
|
|
|
|
- // console.log("同房间的其他人重置", userKey, unsetUserObj);
|
|
|
|
- return updateRoomUser(roomId, userKey, unsetUserObj);
|
|
|
|
- });
|
|
|
|
- //总处理完成
|
|
|
|
-
|
|
|
|
- Promise.all(resetOther).then(() => {
|
|
|
|
- this.room.notify.notifyBeAssistant(roomId, userObj, this.room.userId);
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- // console.log("AllRoomUsers", AllRoomUsers);
|
|
|
|
- // callback(user);
|
|
|
|
- } catch (error) {
|
|
|
|
- this.room.logger.error("setAssistant:error", error);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- /**
|
|
|
|
- * 设置MIC权 LEADER(权限) 房主或助手
|
|
|
|
- * 主要
|
|
|
|
- * @param {*} roomId
|
|
|
|
- * @param {*} userId
|
|
|
|
- */
|
|
|
|
- async setMicRight(roomId, userId, isAllowMic) {
|
|
|
|
- try {
|
|
|
|
- const userRes = await getCurrentUser(roomId, userId, FROMTYPE.MiniAPP);
|
|
|
|
- const user = JSON.parse(userRes);
|
|
|
|
- const roomConfigRes = await getRoomConfig(roomId);
|
|
|
|
- // if (this.room.userId == userId && this.room.isHoster(this.room.user.role)) {
|
|
|
|
- // console.log("房主不用设置自己的MIC!");
|
|
|
|
- // return;
|
|
|
|
- // }
|
|
|
|
- const reveseMic = Number(isAllowMic) === 0 ? 1 : 0;
|
|
|
|
- console.log("设置MIC权当前用户:: %s 新MIC权", user.userId, reveseMic);
|
|
|
|
- const userObj = Object.assign({}, user, { isAllowMic: reveseMic });
|
|
|
|
- const roomObj = Object.assign({}, roomConfigRes, { allowMicId: user.userId });
|
|
|
|
-
|
|
|
|
- await updateRoomUser(roomId, userId, userObj);
|
|
|
|
- await setRoomConfig(roomId, roomObj);
|
|
|
|
- const AllRoomUsers = await getAllRoomUsers(roomId);
|
|
|
|
- // 已存在的设置为false
|
|
|
|
-
|
|
|
|
- const resetOther = Array.from(AllRoomUsers)
|
|
|
|
- .filter((i) => i.role !== "leader" && i.userId !== userObj.userId)
|
|
|
|
- .map((roomer) => {
|
|
|
|
- const userKey = `user:${roomer.userId}`;
|
|
|
|
- const unsetUserObj = Object.assign({}, roomer, { isAllowMic: 0 });
|
|
|
|
- return updateRoomUser(roomId, userKey, unsetUserObj);
|
|
|
|
- });
|
|
|
|
- Promise.all(resetOther).then(() => {
|
|
|
|
- this.room.notify.notifyBeHasMic(roomId, userObj, this.room.userId);
|
|
|
|
- });
|
|
|
|
- } catch (error) {
|
|
|
|
- this.room.logger.error("setMicRight::error", error);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 创建房间 LEADER or assistant 房主或助手
|
|
|
|
- * @param {*string} roomId
|
|
|
|
- * @param {*string} userId
|
|
|
|
- * @param {*Object} user
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
- async buildRoom(roomId, userId, user) {
|
|
|
|
- const hasJoin = await this.redis.HVALS(getInKey(roomId), userId);
|
|
|
|
- if (hasJoin.length === 0) {
|
|
|
|
- await this.redis.hSet(getInKey(roomId), userId, JSON.stringify(user));
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 关闭房间
|
|
|
|
- * @param {*} roomId
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
- async removeRoom(roomId) {
|
|
|
|
- this.room.logger.info("removeRoom", { roomId });
|
|
|
|
- await this.redis.del(getInKey(roomId));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 加入房间
|
|
|
|
- * @param {*} roomId
|
|
|
|
- * @param {*} userId
|
|
|
|
- * @param {*} user
|
|
|
|
- */
|
|
|
|
- async joinRoom(roomId, userId, user) {
|
|
|
|
- const hasRoom = await this.redis.exists(getInKey(roomId));
|
|
|
|
- const isJoinRoom = await this.redis.hExists(getInKey(roomId), userId);
|
|
|
|
- if (hasRoom) {
|
|
|
|
- await this.redis.hSet(getInKey(roomId), userId, JSON.stringify(user));
|
|
|
|
- } else {
|
|
|
|
- await buildRoom(roomId, userId, user);
|
|
|
|
- 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(getInKey(roomId), userId);
|
|
|
|
- await removeRoomUser(roomId, userId);
|
|
|
|
- const AllRoomUsers = await getAllRoomUsers(roomId);
|
|
|
|
- const roomConfig = await getRoomConfig(roomId);
|
|
|
|
-
|
|
|
|
- this.room.logger.info("离开房间", userId, AllRoomUsers);
|
|
|
|
-
|
|
|
|
- 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(getInKey(roomId));
|
|
|
|
- if (hasRoom.length === 0) {
|
|
|
|
- this.room.logger.info("房主主动创建房间 :", { roomId, userId });
|
|
|
|
- await this.buildRoom(roomId, userId, user);
|
|
|
|
- } else {
|
|
|
|
- //TODO
|
|
|
|
- const checkIsRoomMaster = await isRoomMaster(roomId, userId);
|
|
|
|
- console.log("isRoomMaster", checkIsRoomMaster);
|
|
|
|
- if (checkIsRoomMaster) {
|
|
|
|
- this.room.logger.info("房主已存在房间 :", { roomId, userId, from: user.from });
|
|
|
|
- await this.joinRoom(roomId, userId, user);
|
|
|
|
- // this.notifyUserJitter(roomId);
|
|
|
|
- } else {
|
|
|
|
- this.room.logger.error("存在非法房主", 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);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- async notifyUserJitter(roomId, userId) {
|
|
|
|
- const AllRoomUsers = await getAllRoomUsers(roomId);
|
|
|
|
- const roomConfig = await getRoomConfig(roomId);
|
|
|
|
- const currentUser = await getCurrentUser(userId, FROMTYPE.MiniAPP);
|
|
|
|
- const user = JSON.parse(currentUser);
|
|
|
|
- await updateRoomUser(roomId, userId, user);
|
|
|
|
- this.room.logger.info("notifyUserJitter", roomId, AllRoomUsers.length);
|
|
|
|
- this.socket.emit(EVENT.roomIn, {
|
|
|
|
- user,
|
|
|
|
- roomsPerson: AllRoomUsers,
|
|
|
|
- roomsConfig: roomConfig,
|
|
|
|
- });
|
|
|
|
- this.socket.broadcast.to(roomId).emit(EVENT.someOneInRoom, {
|
|
|
|
- user,
|
|
|
|
- roomsPerson: AllRoomUsers,
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- /**
|
|
|
|
- * 通知房间人员变动
|
|
|
|
- */
|
|
|
|
- async notifyUsersChange(roomId, user, inter = true) {
|
|
|
|
- const AllRoomUsers = await getAllRoomUsers(roomId);
|
|
|
|
- // const roomConfig = await getRoomConfig(roomId);
|
|
|
|
- this.room.logger.info("notifyUsersChange", roomId, AllRoomUsers.length);
|
|
|
|
- const actionName = inter ? "inRoom" : "outRoom";
|
|
|
|
- this.socket.broadcast.to(roomId).emit(EVENT.roomPersonChange, {
|
|
|
|
- user: user,
|
|
|
|
- actionName: actionName,
|
|
|
|
- roomsPerson: AllRoomUsers,
|
|
|
|
- });
|
|
|
|
- }
|
|
|
|
- /**
|
|
|
|
- * 关闭呼叫房间
|
|
|
|
- * @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() {
|
|
|
|
- try {
|
|
|
|
- const syncId = this.room.syncId;
|
|
|
|
- const roomId = this.room.roomId;
|
|
|
|
- const userId = this.room.userId;
|
|
|
|
- this.socket.leave(syncId);
|
|
|
|
- this.socket.leave(roomId);
|
|
|
|
- await removeRoomUser(roomId, userId);
|
|
|
|
- await this.redis.del(getInKey(syncId));
|
|
|
|
- await this.redis.del(getInKey(userId));
|
|
|
|
- this.notifyUsersChange(roomId, this.room.user, false);
|
|
|
|
- } catch (error) {
|
|
|
|
- console.log("disconnect::error", error);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- // RoomSessionId 房间有效时间
|
|
|
|
- setRoomUnlimit(roomSessionId) {
|
|
|
|
- return this.redis.expire(getInKey(roomSessionId), -1);
|
|
|
|
- }
|
|
|
|
- setRoomAvailableBySeconds(roomSessionId, seconds) {
|
|
|
|
- return this.redis.expire(getInKey(roomSessionId), seconds);
|
|
|
|
- }
|
|
|
|
- setRoomAvailableByHours(roomSessionId, hours) {
|
|
|
|
- return this.redis.expire(getInKey(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);
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
|
|
+// 房间行为助手
|
|
|
|
+import { EVENT, CODEMEG, FROMTYPE } from "../../enum/index.js";
|
|
|
|
+import { getCurrentUser, updateUser, removeRoomAllUsers, getAllRoomUsers, updateRoomUser, removeRoomUser } from "../../service/userService.js";
|
|
|
|
+import { setRoomConfig, getRoomConfig, isRoomMaster } from "../../service/roomConfigService.js";
|
|
|
|
+import { subClient } from "../../connection/redis.js";
|
|
|
|
+
|
|
|
|
+const prefix = process.env.REDIS_PREFIX || "chat";
|
|
|
|
+const getInKey = (realKey) => {
|
|
|
|
+ return `${prefix}:${realKey}`;
|
|
|
|
+};
|
|
|
|
+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(getInKey(roomSessionId));
|
|
|
|
+ const mergeRoomId = uRoomId || roomId;
|
|
|
|
+ this.roomId = mergeRoomId;
|
|
|
|
+ this.room.logger.info("prepearRoom", roomSessionId, this.roomId);
|
|
|
|
+ await this.redis.set(getInKey(roomSessionId), mergeRoomId);
|
|
|
|
+ return Promise.resolve(this.roomId);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ async destoryRoom(roomSessionId, roomConfigId) {
|
|
|
|
+ this.room.logger.info("destoryRoom", roomSessionId, roomConfigId);
|
|
|
|
+ await this.redis.del(getInKey(roomSessionId));
|
|
|
|
+ await this.redis.del(getInKey(roomConfigId));
|
|
|
|
+ this.disconnect();
|
|
|
|
+ return Promise.resolve(true);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * kickPersion LEADER or assistant 房主或助手
|
|
|
|
+ */
|
|
|
|
+ async kickPersion(roomId, userId) {
|
|
|
|
+ console.log("kickPersion", roomId, userId);
|
|
|
|
+ getInKey(roomId);
|
|
|
|
+ try {
|
|
|
|
+ const hasJoin = await this.redis.HVALS(getInKey(roomId), userId);
|
|
|
|
+ // const blackListId = ""
|
|
|
|
+ if (hasJoin.length > 0) {
|
|
|
|
+ await this.redis.hDel(getInKey(roomId), userId);
|
|
|
|
+ return Promise.resolve(true);
|
|
|
|
+ } else {
|
|
|
|
+ return Promise.resolve(false);
|
|
|
|
+ }
|
|
|
|
+ } catch (error) {
|
|
|
|
+ return Promise.resolve(false);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 设置助手 LEADER(权限) 房主或助手
|
|
|
|
+ * @param {*} roomId
|
|
|
|
+ * @param {*} userId
|
|
|
|
+ */
|
|
|
|
+ async setAssistant(roomId, userId, cancel) {
|
|
|
|
+ try {
|
|
|
|
+ const userRes = await getCurrentUser(roomId, userId, FROMTYPE.MiniAPP);
|
|
|
|
+ const user = JSON.parse(userRes);
|
|
|
|
+ const roomConfigRes = await getRoomConfig(roomId);
|
|
|
|
+ if (this.room.userId == userId) {
|
|
|
|
+ console.log("不能设置自己为助理!");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ const role = cancel ? "customer" : "assistant";
|
|
|
|
+ // assistant是助手,customer是普通角色,操作role会好些
|
|
|
|
+ const userObj = Object.assign({}, user, { role: role, order: 1 });
|
|
|
|
+ const roomObj = Object.assign({}, roomConfigRes, { assistantId: user.userId });
|
|
|
|
+ // console.log("setAssistant", userObj, roomObj);
|
|
|
|
+ // console.error("roomObj", roomObj);
|
|
|
|
+ await updateRoomUser(roomId, userId, userObj);
|
|
|
|
+ // // 更新roomConfig 设置助手id
|
|
|
|
+ await setRoomConfig(roomId, roomObj);
|
|
|
|
+ const AllRoomUsers = await getAllRoomUsers(roomId);
|
|
|
|
+
|
|
|
|
+ // 同房间的其他人重置
|
|
|
|
+ const resetOther = Array.from(AllRoomUsers)
|
|
|
|
+ .filter((i) => i.role !== "leader" && i.userId !== userObj.userId)
|
|
|
|
+ .map((roomer) => {
|
|
|
|
+ const userKey = `user:${roomer.userId}`;
|
|
|
|
+ const unsetUserObj = Object.assign({}, roomer, { role: "customer", order: 2 });
|
|
|
|
+ // console.log("同房间的其他人重置", userKey, unsetUserObj);
|
|
|
|
+ return updateRoomUser(roomId, userKey, unsetUserObj);
|
|
|
|
+ });
|
|
|
|
+ //总处理完成
|
|
|
|
+
|
|
|
|
+ Promise.all(resetOther).then(() => {
|
|
|
|
+ this.room.notify.notifyBeAssistant(roomId, userObj, this.room.userId);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ // console.log("AllRoomUsers", AllRoomUsers);
|
|
|
|
+ // callback(user);
|
|
|
|
+ } catch (error) {
|
|
|
|
+ this.room.logger.error("setAssistant:error", error);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ /**
|
|
|
|
+ * 设置MIC权 LEADER(权限) 房主或助手
|
|
|
|
+ * 主要
|
|
|
|
+ * @param {*} roomId
|
|
|
|
+ * @param {*} userId
|
|
|
|
+ */
|
|
|
|
+ async setMicRight(roomId, userId, isAllowMic) {
|
|
|
|
+ try {
|
|
|
|
+ const userRes = await getCurrentUser(roomId, userId, FROMTYPE.MiniAPP);
|
|
|
|
+ const user = JSON.parse(userRes);
|
|
|
|
+ const roomConfigRes = await getRoomConfig(roomId);
|
|
|
|
+ // if (this.room.userId == userId && this.room.isHoster(this.room.user.role)) {
|
|
|
|
+ // console.log("房主不用设置自己的MIC!");
|
|
|
|
+ // return;
|
|
|
|
+ // }
|
|
|
|
+ const reveseMic = Number(isAllowMic) === 0 ? 1 : 0;
|
|
|
|
+ console.log("设置MIC权当前用户:: %s 新MIC权", user.userId, reveseMic);
|
|
|
|
+ const userObj = Object.assign({}, user, { isAllowMic: reveseMic });
|
|
|
|
+ const roomObj = Object.assign({}, roomConfigRes, { allowMicId: user.userId });
|
|
|
|
+
|
|
|
|
+ await updateRoomUser(roomId, userId, userObj);
|
|
|
|
+ await setRoomConfig(roomId, roomObj);
|
|
|
|
+ const AllRoomUsers = await getAllRoomUsers(roomId);
|
|
|
|
+ // 已存在的设置为false
|
|
|
|
+
|
|
|
|
+ const resetOther = Array.from(AllRoomUsers)
|
|
|
|
+ .filter((i) => i.role !== "leader" && i.userId !== userObj.userId)
|
|
|
|
+ .map((roomer) => {
|
|
|
|
+ const userKey = `user:${roomer.userId}`;
|
|
|
|
+ const unsetUserObj = Object.assign({}, roomer, { isAllowMic: 0 });
|
|
|
|
+ return updateRoomUser(roomId, userKey, unsetUserObj);
|
|
|
|
+ });
|
|
|
|
+ Promise.all(resetOther).then(() => {
|
|
|
|
+ this.room.notify.notifyBeHasMic(roomId, userObj, this.room.userId);
|
|
|
|
+ });
|
|
|
|
+ } catch (error) {
|
|
|
|
+ this.room.logger.error("setMicRight::error", error);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 创建房间 LEADER or assistant 房主或助手
|
|
|
|
+ * @param {*string} roomId
|
|
|
|
+ * @param {*string} userId
|
|
|
|
+ * @param {*Object} user
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ async buildRoom(roomId, userId, user) {
|
|
|
|
+ const hasJoin = await this.redis.HVALS(getInKey(roomId), userId);
|
|
|
|
+ if (hasJoin.length === 0) {
|
|
|
|
+ await this.redis.hSet(getInKey(roomId), userId, JSON.stringify(user));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 关闭房间
|
|
|
|
+ * @param {*} roomId
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ async removeRoom(roomId) {
|
|
|
|
+ this.room.logger.info("removeRoom", { roomId });
|
|
|
|
+ await this.redis.del(getInKey(roomId));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 加入房间
|
|
|
|
+ * @param {*} roomId
|
|
|
|
+ * @param {*} userId
|
|
|
|
+ * @param {*} user
|
|
|
|
+ */
|
|
|
|
+ async joinRoom(roomId, userId, user) {
|
|
|
|
+ const hasRoom = await this.redis.exists(getInKey(roomId));
|
|
|
|
+ const isJoinRoom = await this.redis.hExists(getInKey(roomId), userId);
|
|
|
|
+ if (hasRoom) {
|
|
|
|
+ await this.redis.hSet(getInKey(roomId), userId, JSON.stringify(user));
|
|
|
|
+ } else {
|
|
|
|
+ await buildRoom(roomId, userId, user);
|
|
|
|
+ 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(getInKey(roomId), userId);
|
|
|
|
+ await removeRoomUser(roomId, userId);
|
|
|
|
+ const AllRoomUsers = await getAllRoomUsers(roomId);
|
|
|
|
+ const roomConfig = await getRoomConfig(roomId);
|
|
|
|
+
|
|
|
|
+ this.room.logger.info("离开房间", userId, AllRoomUsers);
|
|
|
|
+
|
|
|
|
+ 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(getInKey(roomId));
|
|
|
|
+ if (hasRoom.length === 0) {
|
|
|
|
+ this.room.logger.info("房主主动创建房间 :", { roomId, userId });
|
|
|
|
+ await this.buildRoom(roomId, userId, user);
|
|
|
|
+ } else {
|
|
|
|
+ //TODO
|
|
|
|
+ const checkIsRoomMaster = await isRoomMaster(roomId, userId);
|
|
|
|
+ console.log("isRoomMaster", checkIsRoomMaster);
|
|
|
|
+ if (checkIsRoomMaster) {
|
|
|
|
+ this.room.logger.info("房主已存在房间 :", { roomId, userId, from: user.from });
|
|
|
|
+ await this.joinRoom(roomId, userId, user);
|
|
|
|
+ // this.notifyUserJitter(roomId);
|
|
|
|
+ } else {
|
|
|
|
+ this.room.logger.error("存在非法房主", 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);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ async notifyUserJitter(roomId, userId) {
|
|
|
|
+ const AllRoomUsers = await getAllRoomUsers(roomId);
|
|
|
|
+ const roomConfig = await getRoomConfig(roomId);
|
|
|
|
+ const currentUser = await getCurrentUser(userId, FROMTYPE.MiniAPP);
|
|
|
|
+ const user = JSON.parse(currentUser);
|
|
|
|
+ await updateRoomUser(roomId, userId, user);
|
|
|
|
+ this.room.logger.info("notifyUserJitter", roomId, AllRoomUsers.length);
|
|
|
|
+ this.socket.emit(EVENT.roomIn, {
|
|
|
|
+ user,
|
|
|
|
+ roomsPerson: AllRoomUsers,
|
|
|
|
+ roomsConfig: roomConfig,
|
|
|
|
+ });
|
|
|
|
+ this.socket.broadcast.to(roomId).emit(EVENT.someOneInRoom, {
|
|
|
|
+ user,
|
|
|
|
+ roomsPerson: AllRoomUsers,
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ /**
|
|
|
|
+ * 通知房间人员变动
|
|
|
|
+ */
|
|
|
|
+ async notifyUsersChange(roomId, user, inter = true) {
|
|
|
|
+ const AllRoomUsers = await getAllRoomUsers(roomId);
|
|
|
|
+ // const roomConfig = await getRoomConfig(roomId);
|
|
|
|
+ this.room.logger.info("notifyUsersChange", roomId, AllRoomUsers.length);
|
|
|
|
+ const actionName = inter ? "inRoom" : "outRoom";
|
|
|
|
+ this.socket.broadcast.to(roomId).emit(EVENT.roomPersonChange, {
|
|
|
|
+ user: user,
|
|
|
|
+ actionName: actionName,
|
|
|
|
+ roomsPerson: AllRoomUsers,
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ /**
|
|
|
|
+ * 关闭呼叫房间
|
|
|
|
+ * @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);
|
|
|
|
+ }
|
|
|
|
+ this.removeRoomSession(this.room.sessionId);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ removeRoomSession(roomSessionId) {
|
|
|
|
+ await this.redis.del(getInKey(roomSessionId));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 主动断开
|
|
|
|
+ async disconnect() {
|
|
|
|
+ try {
|
|
|
|
+ const syncId = this.room.syncId;
|
|
|
|
+ const roomId = this.room.roomId;
|
|
|
|
+ const userId = this.room.userId;
|
|
|
|
+ this.socket.leave(syncId);
|
|
|
|
+ this.socket.leave(roomId);
|
|
|
|
+ await removeRoomUser(roomId, userId);
|
|
|
|
+ await this.redis.del(getInKey(syncId));
|
|
|
|
+ await this.redis.del(getInKey(userId));
|
|
|
|
+ this.notifyUsersChange(roomId, this.room.user, false);
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.log("disconnect::error", error);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // RoomSessionId 房间有效时间
|
|
|
|
+ setRoomUnlimit(roomSessionId) {
|
|
|
|
+ return this.redis.expire(getInKey(roomSessionId), -1);
|
|
|
|
+ }
|
|
|
|
+ setRoomAvailableBySeconds(roomSessionId, seconds) {
|
|
|
|
+ return this.redis.expire(getInKey(roomSessionId), seconds);
|
|
|
|
+ }
|
|
|
|
+ setRoomAvailableByHours(roomSessionId, hours) {
|
|
|
|
+ return this.redis.expire(getInKey(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);
|
|
|
|
+ }
|
|
|
|
+}
|