socket.gateway.ts 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. import { InjectRedis } from '@liaoliaots/nestjs-redis';
  2. import {
  3. ConnectedSocket,
  4. MessageBody,
  5. OnGatewayConnection,
  6. OnGatewayDisconnect,
  7. OnGatewayInit,
  8. SubscribeMessage,
  9. WebSocketGateway,
  10. WebSocketServer,
  11. } from '@nestjs/websockets';
  12. import { Server, Socket } from 'socket.io';
  13. import Redis from 'ioredis';
  14. import { instrument } from '@socket.io/admin-ui';
  15. import * as bcrypt from 'bcrypt';
  16. import { RoomService } from '../room/room.service';
  17. import { Logger } from '@nestjs/common';
  18. import { DelayService } from 'src/room/delay/delay.service';
  19. console.log('SOCKET_NAME', process.env.SOCKET_NAME);
  20. console.log('SOCKET_PATH', process.env.SOCKET_PATH);
  21. console.log('SOCKET_USE_MSPACK', process.env.SOCKET_USE_MSPACK);
  22. @WebSocketGateway(Number(process.env.SOCKET_PORT), {
  23. transports: ['websocket'],
  24. cors: '*',
  25. // namespace: "ws",
  26. // path: '/ws-sync',
  27. path: process.env.SOCKET_PATH,
  28. parser:
  29. Number(process.env.SOCKET_USE_MSPACK) === 1
  30. ? require('socket.io-msgpack-parser')
  31. : '',
  32. })
  33. export class SocketGateway
  34. implements OnGatewayInit, OnGatewayDisconnect, OnGatewayConnection
  35. {
  36. constructor(
  37. @InjectRedis() private readonly redis: Redis,
  38. private readonly roomService: RoomService,
  39. private readonly delayService: DelayService,
  40. ) {}
  41. public readonly logger = new Logger('socketGateway');
  42. @WebSocketServer() server: Server;
  43. // public _loginLimit = new Map<string, string>();
  44. async handleConnection(@ConnectedSocket() socket: Socket) {
  45. const { isBenmark } = socket.handshake.query;
  46. if (Number(isBenmark) === 1) {
  47. socket.data.isBenmark = 1;
  48. }
  49. // this.delayService
  50. }
  51. async handleDisconnect(@ConnectedSocket() socket: Socket) {
  52. const deviceId = socket.data.deviceId;
  53. const isBenmark = socket.data.isBenmark;
  54. if (deviceId) {
  55. const redisFlag = `kankan:socket:deviceId`;
  56. // const did = this._loginLimit.get(deviceId);
  57. const did = await this.redis.hget(redisFlag, deviceId);
  58. if (did === socket.id) {
  59. await this.redis.hdel(redisFlag, deviceId);
  60. // this._loginLimit.delete(deviceId);
  61. }
  62. if (!!isBenmark) {
  63. // console.log('isBenmark', isBenmark);
  64. await this.redis.hdel(redisFlag, deviceId);
  65. }
  66. }
  67. await this.roomService.handleUserOffline(socket);
  68. socket.removeAllListeners();
  69. socket.disconnect();
  70. // console.log('handleDisconnect', client);
  71. }
  72. afterInit(server: any) {
  73. instrument(server, {
  74. auth: {
  75. type: 'basic',
  76. username: process.env.WATCH_USER,
  77. password: bcrypt.hashSync(process.env.WATCH_PASSWORD, 10),
  78. },
  79. namespaceName: '/watch',
  80. });
  81. this.delayService.init();
  82. }
  83. @SubscribeMessage('join')
  84. async handleMessage(
  85. @MessageBody() message: UserInfoParams,
  86. @ConnectedSocket() socket: Socket,
  87. ): Promise<void> {
  88. message.id = socket.id;
  89. // (socket as any).userId = message.userId;
  90. // (socket as any).roomId = message.roomId;
  91. socket.data.user = message;
  92. const isRepeat = await this.handleRepeatJoin(socket, message);
  93. // console.log('isRepeat', isRepeat);
  94. if (!isRepeat) {
  95. this.logger.warn(
  96. `当前加入房间:roomId: ${message.roomId} userId: ${message.userId}`,
  97. 'join-user',
  98. );
  99. socket.join(message.roomId);
  100. if (!message.isClient) {
  101. await this.roomService.handleUserJoin(socket, message);
  102. }
  103. }
  104. }
  105. async handleRepeatJoin(
  106. socket: Socket,
  107. message: UserInfoParams,
  108. ): Promise<boolean> {
  109. const from = !!message.isClient ? 1 : 0;
  110. const flag = `${message.userId}-${from}`;
  111. socket.data.deviceId = flag;
  112. const redisFlag = `kankan:socket:deviceId`;
  113. const isExist = await this.redis.hexists(redisFlag, flag);
  114. if (!isExist) {
  115. await this.redis.hset(redisFlag, flag, socket.id);
  116. // this._loginLimit.set(flag, socket.id);
  117. return Promise.resolve(false);
  118. } else {
  119. socket.emit('manager-error', {
  120. type: 'repeat-login',
  121. code: 306,
  122. });
  123. this.logger.warn(`306:${message.userId}`, 'repeat-login');
  124. return Promise.resolve(true);
  125. }
  126. }
  127. // 订阅action通道
  128. @SubscribeMessage('action')
  129. async handleActionMessage(
  130. @ConnectedSocket() socket: Socket,
  131. @MessageBody() message: any,
  132. ): Promise<void> {
  133. await this.roomService.handleUserAction(socket, message);
  134. }
  135. // 订阅sync通道
  136. @SubscribeMessage('sync')
  137. async handleSyncMessage(
  138. @ConnectedSocket() socket: Socket,
  139. @MessageBody() message: any,
  140. ): Promise<void> {
  141. await this.roomService.handleSyncAction(socket, message);
  142. }
  143. // 订阅paint通道
  144. @SubscribeMessage('paint')
  145. async handlePaintessage(
  146. @ConnectedSocket() socket: Socket,
  147. @MessageBody() message: any,
  148. ): Promise<void> {
  149. await this.roomService.handlePaintAction(socket, message);
  150. }
  151. // 订阅主动退出exit通道
  152. @SubscribeMessage('exit')
  153. async handleExitessage(
  154. @ConnectedSocket() socket: Socket,
  155. @MessageBody() message: any,
  156. ): Promise<void> {
  157. await this.roomService.handleExitAction(socket, message);
  158. }
  159. @SubscribeMessage('active-status')
  160. async handleActive(@ConnectedSocket() socket: Socket) {
  161. const sockets = await this.server.fetchSockets();
  162. socket.emit('active-status', { number: sockets.length });
  163. }
  164. }