gemercheung 2 년 전
부모
커밋
2b0529c998

+ 1 - 0
package.json

@@ -34,6 +34,7 @@
     "bcrypt": "^5.1.0",
     "camelcase-keys": "^8.0.2",
     "chalk": "^4",
+    "dayjs": "^1.11.7",
     "dotenv": "^16.0.3",
     "ioredis": "^5.3.1",
     "logform": "^2.5.1",

+ 6 - 0
pnpm-lock.yaml

@@ -24,6 +24,7 @@ specifiers:
   bcrypt: ^5.1.0
   camelcase-keys: ^8.0.2
   chalk: ^4
+  dayjs: ^1.11.7
   dotenv: ^16.0.3
   eslint: ^8.0.1
   eslint-config-prettier: ^8.3.0
@@ -64,6 +65,7 @@ dependencies:
   bcrypt: 5.1.0
   camelcase-keys: 8.0.2
   chalk: 4.1.2
+  dayjs: 1.11.7
   dotenv: 16.0.3
   ioredis: 5.3.1
   logform: 2.5.1
@@ -2466,6 +2468,10 @@ packages:
     resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==}
     dev: false
 
+  /dayjs/1.11.7:
+    resolution: {integrity: sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==}
+    dev: false
+
   /debug/2.6.9:
     resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
     peerDependencies:

+ 9 - 3
src/app.module.ts

@@ -17,9 +17,15 @@ import { RoomManagerModule } from './room-manager/room-manager.module';
 const url = `redis://:${process.env.REDIS_PASSWORD}@${process.env.REDIS_HOST}:${process.env.REDIS_PORT}/${process.env.REDIS_DB}`;
 
 const redisMo = RedisModule.forRoot({
-  config: {
-    url: url,
-  },
+  config: [
+    {
+      url: url,
+    },
+    {
+      namespace: 'sub',
+      url: url,
+    },
+  ],
 });
 const storeThor = ThrottlerModule.forRootAsync({
   useFactory(redisService: RedisService) {

+ 1 - 1
src/redis-io-adapter/redis-io-adapter.ts

@@ -14,7 +14,7 @@ export class RedisIoAdapter extends IoAdapter {
       url: url,
     });
     const subClient = pubClient.duplicate();
-
+    // pubClient.configSet('notify-keyspace-events', 'Ex');
     await Promise.all([pubClient.connect(), subClient.connect()]);
 
     this.adapterConstructor = createAdapter(pubClient, subClient);

+ 1 - 1
src/room/actions/actions.service.ts

@@ -12,7 +12,7 @@ export class ActionsService {
     private roomService: RoomService,
     @Inject(forwardRef(() => UsersService))
     private userService: UsersService,
-  ) { }
+  ) {}
 
   async handleAllAction(socket: Socket, data: ActionsParams): Promise<void> {
     const isSocketLeader = () => {

+ 44 - 0
src/room/delay/delay.service.ts

@@ -0,0 +1,44 @@
+import { InjectRedis } from '@liaoliaots/nestjs-redis';
+import { Injectable } from '@nestjs/common';
+import { Redis } from 'ioredis';
+import { Socket } from 'socket.io';
+import * as dayjs from 'dayjs';
+import * as duration from 'dayjs/plugin/duration';
+import { ConfigService } from '@nestjs/config';
+dayjs.extend(duration);
+@Injectable()
+export class DelayService {
+  constructor(
+    @InjectRedis() private readonly redis: Redis,
+    @InjectRedis('sub') private readonly subRedis: Redis,
+    private configService: ConfigService,
+  ) {}
+
+  init(): void {
+    const redisDB = this.configService.get<string>('REDIS_DB');
+    console.log('redisDB', redisDB);
+    this.redis.on('ready', () => {
+      console.log('ready');
+      this.redis.config('SET', 'notify-keyspace-events', 'Ex');
+      //   this.subRedis.config('SET', 'notify-keyspace-events', 'Ex');
+    });
+    // const subscribeEvent = `__keyevent@${redisDB}__:expired`;
+    console.log('subRedis', this.subRedis);
+    this.subRedis.on('ready', () => {
+      this.subRedis.subscribe(`_key*@*__:*`, function () {
+        console.log('Arguments', arguments);
+      });
+    });
+  }
+  handleExpiredSubscribe(key) {
+    // eslint-disable-next-line prefer-rest-params
+    console.log('key', arguments);
+  }
+
+  async handleOffline(socket?: Socket): Promise<void> {
+    this.redis.set('test-test', 'wwwsssss', 'EX', 20);
+    this.redis.publish('what', 'xxxx');
+    // console.log('socket', socket);
+    // this.redis.subscribe();
+  }
+}

+ 8 - 1
src/room/room.module.ts

@@ -4,10 +4,17 @@ import { SocketGateway } from 'src/socket/socket.gateway';
 import { RoomService } from './room.service';
 import { UsersService } from './users/users.service';
 import { ActionsService } from './actions/actions.service';
+import { DelayService } from './delay/delay.service';
 
 @Module({
   imports: [],
-  providers: [RoomService, SocketGateway, UsersService, ActionsService],
+  providers: [
+    RoomService,
+    SocketGateway,
+    UsersService,
+    ActionsService,
+    DelayService,
+  ],
   exports: [RoomService],
 })
 export class RoomModule {}

+ 16 - 10
src/room/room.service.ts

@@ -1,10 +1,9 @@
-import { InjectRedis } from '@liaoliaots/nestjs-redis';
 import { forwardRef, Inject, Injectable, Logger } from '@nestjs/common';
-import { Redis } from 'ioredis';
 import { Socket } from 'socket.io';
 
 import { SocketGateway } from 'src/socket/socket.gateway';
 import { ActionsService } from './actions/actions.service';
+import { DelayService } from './delay/delay.service';
 import { UsersService } from './users/users.service';
 
 @Injectable()
@@ -12,10 +11,11 @@ export class RoomService {
   constructor(
     @Inject(forwardRef(() => SocketGateway))
     public readonly socketGateway: SocketGateway,
-    @InjectRedis() private readonly redis: Redis,
+    // @InjectRedis() private readonly redis: Redis,
     private readonly userService: UsersService,
     private readonly actionsService: ActionsService,
-  ) { }
+    private readonly delayService: DelayService,
+  ) {}
   public readonly logger = new Logger('user');
   public _sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
   public _userInfo = {} as UserInfoType;
@@ -91,6 +91,9 @@ export class RoomService {
     this.initUserProfile(userInfo);
     socket.data.user = this._userInfo;
     await this.handleUserOnline(socket);
+    //test
+    this.delayService.handleOffline();
+
     let blockJoin = false;
     if (this._roomId?.length && this._userId?.length) {
       //房主设置房间配置
@@ -204,7 +207,6 @@ export class RoomService {
       });
     }
     const res = await this.userService.deleteRoomUser(RoomId, userId);
-    // console.log('kick-user', delUser.id, RoomId, userId);
     if (res) {
       this.socketGateway.server.to(RoomId).emit('action', {
         type: 'user-leave',
@@ -245,11 +247,15 @@ export class RoomService {
       const res = await this.userService.deleteRoomUser(roomId, userId);
       console.log('user-exit', delUser.id, roomId, userId);
       if (res) {
-        this.socketGateway.server.to(roomId).emit('action', {
-          type: 'user-leave',
-          user: delUser,
-          members: filterRoomUser,
-        });
+        if (socket.data.user?.Role === 'leader') {
+          this.handleRoomDismiss(roomId);
+        } else {
+          this.socketGateway.server.to(roomId).emit('action', {
+            type: 'user-leave',
+            user: delUser,
+            members: filterRoomUser,
+          });
+        }
         socket.disconnect(true);
       }
     }

+ 1 - 1
src/room/users/users.service.ts

@@ -10,7 +10,7 @@ export class UsersService {
     @InjectRedis() private readonly redis: Redis,
     @Inject(forwardRef(() => RoomService))
     private roomService: RoomService,
-  ) { }
+  ) {}
 
   async isUserInRooms(RoomId: string, UserId: string): Promise<boolean> {
     const res = await this.redis.hexists(

+ 7 - 2
src/socket/socket.gateway.ts

@@ -15,6 +15,7 @@ import { instrument } from '@socket.io/admin-ui';
 import * as bcrypt from 'bcrypt';
 import { RoomService } from '../room/room.service';
 import { Logger } from '@nestjs/common';
+import { DelayService } from 'src/room/delay/delay.service';
 
 console.log('SOCKET_PATH-0', process.env.SOCKET_PATH);
 @WebSocketGateway(Number(process.env.SOCKET_PORT), {
@@ -26,16 +27,19 @@ console.log('SOCKET_PATH-0', process.env.SOCKET_PATH);
   // parser: require('socket.io-msgpack-parser'),
 })
 export class SocketGateway
-  implements OnGatewayInit, OnGatewayDisconnect, OnGatewayConnection {
+  implements OnGatewayInit, OnGatewayDisconnect, OnGatewayConnection
+{
   constructor(
     @InjectRedis() private readonly redis: Redis,
     private readonly roomService: RoomService,
-  ) { }
+    private readonly delayService: DelayService,
+  ) {}
   public readonly logger = new Logger('socketGateway');
   @WebSocketServer() server: Server;
   public _loginLimit = new Map<string, string>();
 
   async handleConnection(@ConnectedSocket() socket: Socket, ...args: any[]) {
+    // this.delayService
   }
   async handleDisconnect(@ConnectedSocket() socket: Socket) {
     const deviceId = socket.data.deviceId;
@@ -59,6 +63,7 @@ export class SocketGateway
       },
       namespaceName: '/watch',
     });
+    this.delayService.init();
   }
 
   @SubscribeMessage('join')