index.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. import { ROLES, CODEMEG, EVENT, FROMTYPE } from "../../enum/index.js";
  2. import { updateUser, removeRoomAllUsers, getAllRoomUsers, updateRoomUser } from "../../service/userService.js";
  3. // import { watchRoomService } from "../../service/watchRoomService.js";
  4. import { setRoomConfig, getRoomConfig, updateRoomConfigByKey } from "../../service/roomConfigService.js";
  5. import { RoomAssistant } from "./assistant.js";
  6. import { BasicController } from "../basicController.js";
  7. export class RoomController extends BasicController {
  8. constructor(...args) {
  9. super(...args);
  10. this.roomAssistant = new RoomAssistant(this.socket, this.redisCli, this);
  11. this.roomId = null;
  12. this.sessionId = null;
  13. this.userId = null;
  14. this.roomConfigId = null;
  15. this.debugger = true;
  16. this.user = {
  17. sig: null,
  18. roomId: null,
  19. userId: null,
  20. sceneNum: null,
  21. isClient: null,
  22. role: null,
  23. userLimitNum: null,
  24. sceneNumber: null,
  25. roomType: null,
  26. from: null,
  27. enableTalk: null,
  28. };
  29. }
  30. async run() {
  31. this.logger.info("socket conetcted has start!");
  32. try {
  33. await this.init();
  34. this.initBaseAction();
  35. this.roomMasterAutoRejoin();
  36. this.roomAssistant.watchRoomExpired();
  37. } catch (error) {
  38. this.logger.error("roomController::run::error", error);
  39. }
  40. }
  41. async init() {
  42. let user = this.socket.handshake.query;
  43. if (user) {
  44. this.user = Object.assign({}, user, {
  45. roomType: user.roomType || "",
  46. });
  47. this.user.sig = this.getSig(this.user.userId);
  48. const oneSceneNum = this.user.sceneNumber || this.user.sceneNum;
  49. const { userId, roomId } = this.user;
  50. await this.initParams(userId, roomId, oneSceneNum);
  51. const userObj = { ...this.user, isConnected: true };
  52. // console.log('userObj',userObj)
  53. updateUser(this.userId, userObj);
  54. // 只有来源于小程序用户信息才记录到redis
  55. if (this.isHoster(this.user.role)) {
  56. if ([FROMTYPE.MiniAPP].includes(Number(this.user.from))) {
  57. await setRoomConfig(this.roomId, {
  58. userLimitNum: this.user.userLimitNum,
  59. enableTalk: this.user.enableTalk === "true" ? true : false,
  60. });
  61. }
  62. }
  63. // 加入
  64. this.socket.join(this.roomId);
  65. } else {
  66. this.logger.info("user-query-不存在 :", this.socket.handshake.query);
  67. this.socket.disconnect();
  68. }
  69. }
  70. async initParams(userId, roomId, oneSceneNum) {
  71. this.userId = `user:${userId}`;
  72. this.syncId = `sync:${oneSceneNum}:${userId}`;
  73. this.sessionId = `session:${oneSceneNum}:${userId}`;
  74. const uRoomId = await this.roomAssistant.prepearRoom(this.sessionId, roomId);
  75. // this.roomId = `room:${uRoomId}_${oneSceneNum}`;
  76. this.roomId = `room:${oneSceneNum}:${uRoomId}`;
  77. this.user.roomId = uRoomId;
  78. this.roomConfigId = `config:${this.roomId}`;
  79. return Promise.resolve(true);
  80. }
  81. initBaseAction() {
  82. // 通知 baseView 减少大量通知
  83. this.socket.on(EVENT.webSyncAction, (data) => {
  84. // socket.broadcast.to(roomUniqueId).emit(EVENT.webSyncAction, data);
  85. try {
  86. if ([FROMTYPE.base].includes(Number(this.user.from))) {
  87. this.socket.broadcast.to(this.roomId).emit(EVENT.webSyncAction, data);
  88. }
  89. } catch (error) {
  90. this.logger.error("roomController::EVENT.webSyncAction", error);
  91. }
  92. });
  93. // 转发action
  94. this.socket.on(EVENT.action, (data) => {
  95. try {
  96. this.logger.debug("room-action", this.roomId, this.socket.rooms.has(this.roomId), JSON.stringify(data));
  97. if (this.socket.rooms.has(this.roomId)) {
  98. this.socket.broadcast.to(this.roomId).emit(EVENT.action, data);
  99. } else {
  100. this.logger.error("action 事件不在房间内", this.user);
  101. }
  102. } catch (error) {
  103. this.logger.error("roomController::EVENT.action", error);
  104. }
  105. });
  106. this.socket.on(EVENT.startCall, async () => {
  107. this.roomAssistant.startCall(this.roomId, this.userId, this.user);
  108. if (this.isHoster(this.user.role)) {
  109. // 以startCall做为真正的进入房间
  110. await updateRoomConfigByKey(this.roomId, "isStart", true);
  111. }
  112. });
  113. this.socket.on(EVENT.stopCall, () => {
  114. this.roomAssistant.stopCall(this.roomId, this.userId, this.user);
  115. if (this.isHoster(this.user.role)) {
  116. // 以stopCall断开做为真正的退出房间
  117. this.roomAssistant.destoryRoom(this.sessionId, this.roomConfigId);
  118. }
  119. });
  120. this.socket.on(EVENT.changeRoomEnableTalk, async (data) => {
  121. // this._roomsConfig[roomId].enableTalk = data;
  122. try {
  123. await setRoomConfig(this.roomId, data);
  124. const roomConfig = await getRoomConfig(this.roomId);
  125. this.socket.broadcast.to(this.roomId).emit(EVENT.changeRoomEnableTalk, roomConfig);
  126. } catch (error) {
  127. this.logger.error("event:changeRoomEnableTalk", error);
  128. }
  129. });
  130. this.socket.on(EVENT.changeOnlineStatus, async (data) => {
  131. try {
  132. this.user.onlineStatus = data.status;
  133. const AllRoomUsers = await getAllRoomUsers(this.roomId);
  134. await updateRoomUser(this.roomId, this.userId, this.user);
  135. let actionName = this.user.onlineStatus ? "inRoom" : "leaveRoom";
  136. this.logger.info("changeOnlineStatus", JSON.stringify(this.user));
  137. this.socket.broadcast.to(this.roomId).emit(EVENT.roomPersonChange, {
  138. roomsPerson: AllRoomUsers,
  139. actionName,
  140. user: this.user,
  141. });
  142. } catch (error) {
  143. this.logger.error("event:changeOnlineStatus", error);
  144. }
  145. });
  146. if (this.debugger) {
  147. this.socket.onAny((event, data) => {
  148. if (event !== "webSyncAction") {
  149. console.log(`onAny:get ${event}, data:${JSON.stringify(data)}`);
  150. }
  151. });
  152. }
  153. }
  154. async roomMasterAutoRejoin() {
  155. try {
  156. const sessionExist = await this.redisCli.exists(this.sessionId);
  157. const roomConfig = await getRoomConfig(this.roomId);
  158. if (sessionExist > 0 && roomConfig.isStart && roomConfig.isStart === "true") {
  159. const AllRoomUsers = await getAllRoomUsers(this.roomId);
  160. // 房主
  161. if (this.isHoster(this.user.role)) {
  162. console.log("自动接连", this.roomId);
  163. this.socket.join(this.roomId);
  164. this.socket.emit("autoReJoin", {
  165. user: this.user,
  166. roomsPerson: AllRoomUsers,
  167. roomId: this.user.roomId,
  168. });
  169. }
  170. setTimeout(() => {
  171. this.socket.emit("someOneInRoom", {
  172. user: this.user,
  173. roomsPerson: AllRoomUsers,
  174. });
  175. });
  176. }
  177. } catch (error) {
  178. this.logger.error("room::roomMasterAutoRejoin", error);
  179. }
  180. }
  181. }