gemercheung 3 years ago
parent
commit
52b00005de

+ 1 - 0
.env

@@ -4,3 +4,4 @@ PUBLIC_IP=120.24.252.95
 ALL_IPS=['192.168.0']
 STUNS_SEVER="stun:172.18.156.41:3478,stun:120.24.252.95:3478"
 GRPC_URL="192.168.0.152:3000"
+REDIS_URL="redis://:192.168.0.47:6379/9"

+ 2 - 1
package.json

@@ -32,8 +32,9 @@
     "@nestjs/platform-ws": "^8.4.4",
     "@nestjs/websockets": "^8.4.4",
     "buffer": "^6.0.3",
+    "nestjs-redis": "^1.3.3",
     "node-datachannel": "^0.3.2",
-    "redis": "^3",
+    "redis": "^4",
     "reflect-metadata": "^0.1.13",
     "rimraf": "^3.0.2",
     "rxjs": "^7.2.0"

+ 15 - 4
proto/scene.proto

@@ -7,6 +7,7 @@ option java_package = "com.fdkk.fdkkmeta.grpc";
 
 // grpc的方法
 service SceneGrpcService {
+  rpc test (TestRequest) returns (TestReply){}
   rpc getRoute (RouteRequest) returns (RouteReply){}
   rpc init (InitRequest) returns (NormalReply){}
   rpc rotate (RotateRequest) returns (NormalReply){}
@@ -17,6 +18,12 @@ service SceneGrpcService {
   rpc getBreakPoint (BreakPointRequest) returns (BreakPointReply){}
   rpc joystick (JoystickRequest) returns (NormalReply){} //操作杆
 }
+message TestRequest {
+  string name=3;
+}
+message TestReply {
+  bool msg=3;
+}
 // 全局对象
 message Point {
   string x=1;
@@ -62,7 +69,7 @@ message SceneReply {
 /**********************************************************/
 // 正常出参对象
 message NormalReply {
-  string code=1;                                       //0/1   0表示没收到,1表示收到
+  int32 code=1;                                       //0/1   0表示没收到,1表示收到
 }
 
 /**********************************************************/
@@ -72,6 +79,9 @@ message Space {
    Point position=1;
    AngleUe4 angle=2;
 }
+message Extra{
+   bool removeWhenDisconnected=1;
+}
 
 message State {
    string roomTypeId=1;
@@ -90,7 +100,7 @@ message State {
    string pathName=14;
    string pathId=15;
    int32 avatarSize=16;
-   string extra=17;
+   Extra extra=17;
    bool prioritySync=18;
    Space player=19;
    Space camera=20;
@@ -138,15 +148,16 @@ message InitRequest {
   string avatar_id=4;
   string room_id=5;
   string app_id=6;
+  Space player=7;
 }
 /**********************************************************/
-message echoMsg{
+message EchoMsg{
   string echoMsg=1;
 }
 
 message EchoRequest{
   int32 action_type=1;   //1009
-  echoMsg echo_msg=2;
+  EchoMsg echo_msg=2;
   string trace_id=3;
   string user_id=4;
 }

+ 0 - 22
src/app.controller.spec.ts

@@ -1,22 +0,0 @@
-import { Test, TestingModule } from '@nestjs/testing';
-import { AppController } from './app.controller';
-import { AppService } from './app.service';
-
-describe('AppController', () => {
-  let appController: AppController;
-
-  beforeEach(async () => {
-    const app: TestingModule = await Test.createTestingModule({
-      controllers: [AppController],
-      providers: [AppService],
-    }).compile();
-
-    appController = app.get<AppController>(AppController);
-  });
-
-  describe('root', () => {
-    it('should return "Hello World!"', () => {
-      expect(appController.getHello()).toBe('Hello World!');
-    });
-  });
-});

+ 53 - 7
src/app.controller.ts

@@ -1,7 +1,7 @@
 import { Controller, Get, OnModuleInit } from '@nestjs/common';
 import { AppService } from './app.service';
 // import { UtilsModule } from '@app/utils';
-// import { grpcClientOptions } from './grpc-scene.options';
+import { grpcClientOptions } from './scene/grpc-scene.options';
 
 import { ClientGrpc, Client } from '@nestjs/microservices';
 
@@ -12,15 +12,16 @@ interface Point {
 }
 @Controller()
 export class AppController implements OnModuleInit {
-  // @Client(grpcClientOptions) private readonly client: ClientGrpc;
-  // private sceneGrpcService: SceneGrpcService;
+  @Client(grpcClientOptions) private readonly client: ClientGrpc;
+  private sceneGrpcService: SceneGrpcService;
 
-  constructor(private readonly appService: AppService) {}
+  constructor(private readonly appService: AppService) { }
 
   onModuleInit() {
     // console.log('this.client', this.client);
-    // this.sceneGrpcService =
-    //   this.client.getService<SceneGrpcService>('SceneGrpcService');
+    this.sceneGrpcService =
+      this.client.getService<SceneGrpcService>('SceneGrpcService');
+    console.log('this.sceneGrpcService', this.sceneGrpcService);
   }
   @Get()
   getHello(): string {
@@ -38,11 +39,56 @@ export class AppController implements OnModuleInit {
     //   },
     //   sceneCode: 'Hello',
     // };
-    // // console.log('params', params);
+    // // // console.log('params', params);
     // const test = this.sceneGrpcService.getRoute(params);
     // test.subscribe((val) => {
     //   console.log('val', val);
     // });
+
+    try {
+      // const demo_test = {
+      //   user_id: '92dd7e2f-cca9-495d-8f16-458e628ea827',
+      //   nick_name: 'Hello',
+      //   skin_id: 'ce098a8f-a7fc-4721-9c37-31bdbc580c59',
+      //   avatar_id: 'c961561e-78e5-4478-b158-944e3b9c9287',
+      //   room_id: 'c38187b6-d4af-44bb-8028-7ad1e5461cd8',
+      //   app_id: '2282e1b5-6129-4e0d-a30b-2339a1c761cd',
+      //   player: {
+      //     position: {
+      //       x: '0.0',
+      //       y: '0.0',
+      //       z: '0.0',
+      //     },
+      //     angle: {
+      //       pitch: 10,
+      //       yaw: 10,
+      //       roll: 10,
+      //     },
+      //   },
+      // };
+      // const initReply = this.sceneGrpcService.init(demo_test);
+      // initReply.subscribe((val) => {
+      //   console.log('val', val);
+      // });
+
+      // const params = {
+      //   action_type: 1009,
+      //   echo_msg: {
+      //     echoMsg: 'Hello',
+      //   },
+      //   trace_id: '2b6e3444-63eb-40a7-8049-1d6616f16664',
+      //   user_id: '31a6322c-78f1-4744-99df-bc042f50bebc',
+      // };
+      const initReply = this.sceneGrpcService.test({
+        name: 'lala',
+      });
+      initReply.subscribe((val) => {
+        console.log('val', val);
+      });
+      // console.log('initReply')
+    } catch (error) {
+      console.log('test', error);
+    }
     return this.appService.getHello();
   }
 }

+ 2 - 18
src/app.module.ts

@@ -5,26 +5,10 @@ import { AppService } from './app.service';
 import { MetaGateway } from './meta.gateway';
 import { RoomModule } from './room/room.module';
 import { SceneModule } from './scene/scene.module';
-import { RedisModule } from './redis/redis.module';
-
-// const protodir = join(__dirname, '..', 'proto/scene.proto');
-
-// console.log('protodir', protodir);
-
-// const grpcClientModule = ClientsModule.register([
-//   {
-//     name: 'SCENE_PACKAGE',
-//     transport: Transport.GRPC,
-//     options: {
-//       url: '192.168.0.152:3000',
-//       package: 'scene',
-//       protoPath: join(__dirname, '..', 'proto/scene.proto'),
-//     },
-//   },
-// ]);
+// import { RedisModule } from './redis/redis.module';
 
 @Module({
-  imports: [ConfigModule.forRoot(), RoomModule, SceneModule, RedisModule],
+  imports: [ConfigModule.forRoot(), RoomModule, SceneModule],
   controllers: [AppController],
   providers: [AppService, MetaGateway],
 })

+ 24 - 20
src/meta.gateway.ts

@@ -172,12 +172,15 @@ export class MetaGateway
 
     this.gameChanel.onOpen(() => {
       console.log('channel is open');
+
+      this.sceneService.handleDataChanelOpen(this.gameChanel);
+
       clearInterval(this.timer);
 
       const peers = this.peer.getSelectedCandidatePair();
       this.logger.log('配对成功', peers);
 
-      let i = 1;
+      const i = 1;
       const paths = path.join(__dirname, '../ws/video/100');
       console.error('__dirname', __dirname);
       console.error('paths', paths);
@@ -189,28 +192,29 @@ export class MetaGateway
       Number.prototype.padLeft = function (n, str) {
         return Array(n - String(this).length + 1).join(str || '0') + this;
       };
-      this.timer = setInterval(() => {
-        if (i < 30) {
-          const steam = createReadStream(
-            paths + `/100.${Number(i).padLeft(4, '0')}.h264`,
-          );
-          // const steam = createReadStream(paths + `/test2`);
-          steam.on('data', (data: Buffer) => {
-            // console.log(data.buffer);
-            const frame = new DataView(data.buffer);
-            frame.setUint32(0, 1437227610);
-            // frame.setUint16(6, 36);
-            // frame.setUint16(24, 0);
-            // frame.setUint16(26, 0);
-            // frame.setUint32(28, 0);
-            this.gameChanel.sendMessageBinary(Buffer.from(frame.buffer));
-          });
-        }
-        i++;
-      }, 1000 / 30);
+      // this.timer = setInterval(() => {
+      //   if (i < 30) {
+      //     const steam = createReadStream(
+      //       paths + `/100.${Number(i).padLeft(4, '0')}.h264`,
+      //     );
+      //     // const steam = createReadStream(paths + `/test2`);
+      //     steam.on('data', (data: Buffer) => {
+      //       // console.log(data.buffer);
+      //       const frame = new DataView(data.buffer);
+      //       frame.setUint32(0, 1437227610);
+      //       // frame.setUint16(6, 36);
+      //       // frame.setUint16(24, 0);
+      //       // frame.setUint16(26, 0);
+      //       // frame.setUint32(28, 0);
+      //       this.gameChanel.sendMessageBinary(Buffer.from(frame.buffer));
+      //     });
+      //   }
+      //   i++;
+      // }, 1000 / 30);
     });
     this.gameChanel.onClosed(() => {
       console.log('gameChanel close');
+      this.sceneService.handleDataChanelClose();
       this.stopSendWertcHeartPack();
       cleanup();
     });

+ 9 - 12
src/redis/redis.module.ts

@@ -1,20 +1,17 @@
 import { Module } from '@nestjs/common';
 // import { ClientsModule, Transport } from '@nestjs/microservices';
 import { RedisService } from './redis.service';
+import { RedisModule as CacheModule } from 'nestjs-redis';
 
+const options = {
+  port: 6379,
+  host: '192.168.0.47', // 远程调试需要设置bindip 为0.0.0.0 并且设置密码
+  password: '', // 非远程不需要密码
+  decode_responses: true,
+  db: 9,
+};
 @Module({
-  imports: [
-    // ClientsModule.register([
-    //   {
-    //     name: 'REDIS_SERVICE',
-    //     transport: Transport.REDIS,
-    //     // rediss://<username>:<password>@<host>:<port>
-    //     options: {
-    //       url: 'redis://:1234@192.168.0.152:6379#4',
-    //     },
-    //   },
-    // ]),
-  ],
+  imports: [CacheModule.register(options)],
   providers: [RedisService],
   exports: [RedisService],
 })

+ 2 - 2
src/redis/redis.options.ts

@@ -4,8 +4,8 @@ export const redisClientOptions: ClientOptions = {
   transport: Transport.REDIS,
   options: {
     // url: process.env.GRPC_URL,
-    url: 'redis://:redis9394@127.0.0.1:6379/',
-    // url: 'redis://:1234@192.168.0.152:6379/4',
+    // url: 'redis://:redis9394@127.0.0.1:6379/',
+    url: process.env.REDIS_URL,
     retryAttempts: 20,
     retryDelay: 2,
   },

+ 0 - 18
src/redis/redis.service.spec.ts

@@ -1,18 +0,0 @@
-import { Test, TestingModule } from '@nestjs/testing';
-import { RedisService } from './redis.service';
-
-describe('RedisService', () => {
-  let service: RedisService;
-
-  beforeEach(async () => {
-    const module: TestingModule = await Test.createTestingModule({
-      providers: [RedisService],
-    }).compile();
-
-    service = module.get<RedisService>(RedisService);
-  });
-
-  it('should be defined', () => {
-    expect(service).toBeDefined();
-  });
-});

+ 48 - 12
src/redis/redis.service.ts

@@ -1,24 +1,60 @@
 import { Injectable, OnModuleInit } from '@nestjs/common';
-import { ClientRedis, Client } from '@nestjs/microservices';
-import { redisClientOptions } from './redis.options';
+// import { ClientRedis, Client } from '@nestjs/microservices';
+// import { redisClientOptions } from './redis.options';
+import { RedisService as CacheService } from 'nestjs-redis';
+
 @Injectable()
 export class RedisService implements OnModuleInit {
-  @Client(redisClientOptions) private readonly client: ClientRedis;
+  public client;
+  constructor(private redisService: CacheService) {}
   async onModuleInit() {
     console.log('redis init');
-    // console.log('this.client', this.client);
     try {
-      // const opt = this.client.getClientOptions();
-      //   const connect = await this.client.connect();
-      //   const redis = this.client.createClient();
-      //   console.log('connect', connect);
-      // this.client
-    } catch (error) { 
+      this.getClient();
+    } catch (error) {
+      console.error('error', error);
+    }
+  }
 
+  async getClient() {
+    this.client = await this.redisService.getClient();
+  }
 
-      
+  public async set(key: string, value: any, seconds?: number) {
+    value = JSON.stringify(value);
+    if (!this.client) {
+      await this.getClient();
+    }
+    if (!seconds) {
+      await this.client.set(key, value);
+    } else {
+      await this.client.set(key, value, 'EX', seconds);
+    }
+  }
+
+  //获取值的方法
+  public async get(key: string) {
+    if (!this.client) {
+      await this.getClient();
+    }
+    const data = await this.client.get(key);
+    if (!data) return;
+    return JSON.parse(data);
+  }
+
+  //获取值的方法
+  public async del(key: string) {
+    if (!this.client) {
+      await this.getClient();
+    }
+    await this.client.del(key);
+  }
+  // 清理缓存
+  public async flushall(): Promise<any> {
+    if (!this.client) {
+      await this.getClient();
     }
 
-    // this.client.createClient();
+    await this.client.flushall();
   }
 }

+ 30 - 6
src/scene/scene.d.ts

@@ -5,6 +5,8 @@ interface SceneGrpcService {
   move(request: MoveRequest): Observable<any>;
   getBreakPoint(request: GetBreakPointRequest): Observable<any>;
   joystick(request: JoystickRequest): Observable<any>;
+  echo(request: EchoRequest): Observable<any>;
+  test(request: TestRequest): Observable<any>;
 }
 
 interface Point {
@@ -12,7 +14,19 @@ interface Point {
   y: string;
   z: string;
 }
+interface Angle {
+  pitch: number;
+  yaw: number;
+  roll: number;
+}
+interface Player {
+  position: Point;
+  angle: Angle;
+}
 
+interface TestRequest {
+  name: string;
+}
 interface RouteRequest {
   sLocation: Point;
   eLocation: Point;
@@ -20,12 +34,13 @@ interface RouteRequest {
 }
 
 interface InitRequest {
-  userId: string;
-  nickName: string;
-  skinId: string;
-  avatarId: string;
-  roomId: string;
-  appId: string;
+  user_id: string;
+  nick_name: string;
+  skin_id: string;
+  avatar_id: string;
+  room_id: string;
+  app_id: string;
+  player: Player;
 }
 
 interface RotateRequest {
@@ -105,3 +120,12 @@ interface JoystickRequest {
   userId: string;
   packetId: string;
 }
+
+interface EchoRequest {
+  action_type: number;
+  echo_msg: {
+    echoMsg: string;
+  };
+  trace_id: string;
+  user_id: string;
+}

+ 2 - 0
src/scene/scene.module.ts

@@ -1,5 +1,7 @@
 import { Module } from '@nestjs/common';
 import { SceneService } from './scene.service';
+// import { RedisModule } from '../redis/redis.module';
+// import { RedisService } from '../redis/redis.service'
 @Module({
   imports: [],
   controllers: [],

File diff suppressed because it is too large
+ 110 - 2
src/scene/scene.service.ts


+ 179 - 15
yarn.lock

@@ -611,6 +611,16 @@
     webpack "5.71.0"
     webpack-node-externals "3.0.0"
 
+"@nestjs/common@^7.4.4":
+  version "7.6.18"
+  resolved "https://registry.npmmirror.com/@nestjs/common/-/common-7.6.18.tgz#d89e6d248985eec13af60507a8725cb2142d660a"
+  integrity sha512-BUJQHNhWzwWOkS4Ryndzd4HTeRObcAWV2Fh+ermyo3q3xYQQzNoEWclJVL/wZec8AONELwIJ+PSpWI53VP0leg==
+  dependencies:
+    axios "0.21.1"
+    iterare "1.2.1"
+    tslib "2.2.0"
+    uuid "8.3.2"
+
 "@nestjs/common@^8.0.0":
   version "8.4.4"
   resolved "https://registry.npmmirror.com/@nestjs/common/-/common-8.4.4.tgz"
@@ -631,6 +641,19 @@
     lodash "4.17.21"
     uuid "8.3.2"
 
+"@nestjs/core@^7.4.4":
+  version "7.6.18"
+  resolved "https://registry.npmmirror.com/@nestjs/core/-/core-7.6.18.tgz#36448f0ae7f7d08f032e1e7e53b4a4c82ae844d7"
+  integrity sha512-CGu20OjIxgFDY7RJT5t1TDGL8wSlTSlbZEkn8U5OlICZEB3WIpi98G7ajJpnRWmEgW8S4aDJmRKGjT+Ntj5U4A==
+  dependencies:
+    "@nuxtjs/opencollective" "0.3.2"
+    fast-safe-stringify "2.0.7"
+    iterare "1.2.1"
+    object-hash "2.1.1"
+    path-to-regexp "3.2.0"
+    tslib "2.2.0"
+    uuid "8.3.2"
+
 "@nestjs/core@^8.0.0":
   version "8.4.4"
   resolved "https://registry.npmmirror.com/@nestjs/core/-/core-8.4.4.tgz"
@@ -791,6 +814,40 @@
   resolved "https://registry.npmmirror.com/@protobufjs/utf8/-/utf8-1.1.0.tgz"
   integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==
 
+"@redis/bloom@1.0.2":
+  version "1.0.2"
+  resolved "https://registry.npmmirror.com/@redis/bloom/-/bloom-1.0.2.tgz#42b82ec399a92db05e29fffcdfd9235a5fc15cdf"
+  integrity sha512-EBw7Ag1hPgFzdznK2PBblc1kdlj5B5Cw3XwI9/oG7tSn85/HKy3X9xHy/8tm/eNXJYHLXHJL/pkwBpFMVVefkw==
+
+"@redis/client@1.1.0":
+  version "1.1.0"
+  resolved "https://registry.npmmirror.com/@redis/client/-/client-1.1.0.tgz#e52a85aee802796ceb14bf27daf9550f51f238b8"
+  integrity sha512-xO9JDIgzsZYDl3EvFhl6LC52DP3q3GCMUer8zHgKV6qSYsq1zB+pZs9+T80VgcRogrlRYhi4ZlfX6A+bHiBAgA==
+  dependencies:
+    cluster-key-slot "1.1.0"
+    generic-pool "3.8.2"
+    yallist "4.0.0"
+
+"@redis/graph@1.0.1":
+  version "1.0.1"
+  resolved "https://registry.npmmirror.com/@redis/graph/-/graph-1.0.1.tgz#eabc58ba99cd70d0c907169c02b55497e4ec8a99"
+  integrity sha512-oDE4myMCJOCVKYMygEMWuriBgqlS5FqdWerikMoJxzmmTUErnTRRgmIDa2VcgytACZMFqpAOWDzops4DOlnkfQ==
+
+"@redis/json@1.0.3":
+  version "1.0.3"
+  resolved "https://registry.npmmirror.com/@redis/json/-/json-1.0.3.tgz#a13fde1d22ebff0ae2805cd8e1e70522b08ea866"
+  integrity sha512-4X0Qv0BzD9Zlb0edkUoau5c1bInWSICqXAGrpwEltkncUwcxJIGEcVryZhLgb0p/3PkKaLIWkjhHRtLe9yiA7Q==
+
+"@redis/search@1.0.6":
+  version "1.0.6"
+  resolved "https://registry.npmmirror.com/@redis/search/-/search-1.0.6.tgz#53d7451c2783f011ebc48ec4c2891264e0b22f10"
+  integrity sha512-pP+ZQRis5P21SD6fjyCeLcQdps+LuTzp2wdUbzxEmNhleighDDTD5ck8+cYof+WLec4csZX7ks+BuoMw0RaZrA==
+
+"@redis/time-series@1.0.3":
+  version "1.0.3"
+  resolved "https://registry.npmmirror.com/@redis/time-series/-/time-series-1.0.3.tgz#4cfca8e564228c0bddcdf4418cba60c20b224ac4"
+  integrity sha512-OFp0q4SGrTH0Mruf6oFsHGea58u8vS/iI5+NpYdicaM+7BgqBZH8FFvNZ8rYYLrUO/QRqMq72NpXmxLVNcdmjA==
+
 "@sinonjs/commons@^1.7.0":
   version "1.8.3"
   resolved "https://registry.npmmirror.com/@sinonjs/commons/-/commons-1.8.3.tgz"
@@ -950,6 +1007,13 @@
   dependencies:
     "@types/node" "*"
 
+"@types/ioredis@*":
+  version "4.28.10"
+  resolved "https://registry.npmmirror.com/@types/ioredis/-/ioredis-4.28.10.tgz#40ceb157a4141088d1394bb87c98ed09a75a06ff"
+  integrity sha512-69LyhUgrXdgcNDv7ogs1qXZomnfOEnSmrmMFqKgt1XMJxmoOSG/u3wYy13yACIfKuMJ8IhKgHafDO3sx19zVQQ==
+  dependencies:
+    "@types/node" "*"
+
 "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1":
   version "2.0.4"
   resolved "https://registry.npmmirror.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz"
@@ -1050,6 +1114,11 @@
   dependencies:
     "@types/superagent" "*"
 
+"@types/uuid@*":
+  version "8.3.4"
+  resolved "https://registry.npmmirror.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc"
+  integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==
+
 "@types/yargs-parser@*":
   version "21.0.0"
   resolved "https://registry.npmmirror.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz"
@@ -1477,6 +1546,13 @@ asynckit@^0.4.0:
   resolved "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz"
   integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
 
+axios@0.21.1:
+  version "0.21.1"
+  resolved "https://registry.npmmirror.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8"
+  integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==
+  dependencies:
+    follow-redirects "^1.10.0"
+
 axios@0.26.1:
   version "0.26.1"
   resolved "https://registry.npmmirror.com/axios/-/axios-0.26.1.tgz"
@@ -1825,6 +1901,11 @@ clone@^1.0.2:
   resolved "https://registry.npmmirror.com/clone/-/clone-1.0.4.tgz"
   integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==
 
+cluster-key-slot@1.1.0, cluster-key-slot@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.npmmirror.com/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz#30474b2a981fb12172695833052bc0d01336d10d"
+  integrity sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==
+
 co@^4.6.0:
   version "4.6.0"
   resolved "https://registry.npmmirror.com/co/-/co-4.6.0.tgz"
@@ -2021,7 +2102,7 @@ debug@2.6.9:
   dependencies:
     ms "2.0.0"
 
-debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3, debug@~4.3.1, debug@~4.3.2:
+debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@~4.3.1, debug@~4.3.2:
   version "4.3.4"
   resolved "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz"
   integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@@ -2077,7 +2158,7 @@ delegates@^1.0.0:
   resolved "https://registry.npmmirror.com/delegates/-/delegates-1.0.0.tgz"
   integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==
 
-denque@^1.5.0:
+denque@^1.1.0:
   version "1.5.1"
   resolved "https://registry.npmmirror.com/denque/-/denque-1.5.1.tgz#07f670e29c9a78f8faecb2566a1e2c11929c5cbf"
   integrity sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==
@@ -2551,6 +2632,11 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6:
   resolved "https://registry.npmmirror.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz"
   integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
 
+fast-safe-stringify@2.0.7:
+  version "2.0.7"
+  resolved "https://registry.npmmirror.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743"
+  integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==
+
 fast-safe-stringify@2.1.1, fast-safe-stringify@^2.1.1:
   version "2.1.1"
   resolved "https://registry.npmmirror.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz"
@@ -2625,6 +2711,11 @@ flatted@^3.1.0:
   resolved "https://registry.npmmirror.com/flatted/-/flatted-3.2.5.tgz"
   integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==
 
+follow-redirects@^1.10.0:
+  version "1.15.0"
+  resolved "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.0.tgz#06441868281c86d0dda4ad8bdaead2d02dca89d4"
+  integrity sha512-aExlJShTV4qOUOL7yF1U5tvLCB0xQuudbf6toyYA0E/acBNw71mvjFTnLaRp50aQaYocMR0a/RMMBIHeZnGyjQ==
+
 follow-redirects@^1.14.8:
   version "1.14.9"
   resolved "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.14.9.tgz"
@@ -2747,6 +2838,11 @@ gauge@~2.7.3:
     strip-ansi "^3.0.1"
     wide-align "^1.1.0"
 
+generic-pool@3.8.2:
+  version "3.8.2"
+  resolved "https://registry.npmmirror.com/generic-pool/-/generic-pool-3.8.2.tgz#aab4f280adb522fdfbdc5e5b64d718d3683f04e9"
+  integrity sha512-nGToKy6p3PAbYQ7p1UlWl6vSPwfwU6TMSWK7TTu+WUY4ZjyZQGniGGt2oNVvyNSpyZYSB43zMXVLcBm08MTMkg==
+
 gensync@^1.0.0-beta.2:
   version "1.0.0-beta.2"
   resolved "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz"
@@ -3041,6 +3137,23 @@ interpret@^1.0.0:
   resolved "https://registry.npmmirror.com/interpret/-/interpret-1.4.0.tgz"
   integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==
 
+ioredis@^4:
+  version "4.28.5"
+  resolved "https://registry.npmmirror.com/ioredis/-/ioredis-4.28.5.tgz#5c149e6a8d76a7f8fa8a504ffc85b7d5b6797f9f"
+  integrity sha512-3GYo0GJtLqgNXj4YhrisLaNNvWSNwSS2wS4OELGfGxH8I69+XfNdnmV1AyN+ZqMh0i7eX+SWjrwFKDBDgfBC1A==
+  dependencies:
+    cluster-key-slot "^1.1.0"
+    debug "^4.3.1"
+    denque "^1.1.0"
+    lodash.defaults "^4.2.0"
+    lodash.flatten "^4.4.0"
+    lodash.isarguments "^3.1.0"
+    p-map "^2.1.0"
+    redis-commands "1.7.0"
+    redis-errors "^1.2.0"
+    redis-parser "^3.0.0"
+    standard-as-callback "^2.1.0"
+
 ipaddr.js@1.9.1:
   version "1.9.1"
   resolved "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz"
@@ -3753,6 +3866,21 @@ lodash.camelcase@^4.3.0:
   resolved "https://registry.npmmirror.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz"
   integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==
 
+lodash.defaults@^4.2.0:
+  version "4.2.0"
+  resolved "https://registry.npmmirror.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
+  integrity sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==
+
+lodash.flatten@^4.4.0:
+  version "4.4.0"
+  resolved "https://registry.npmmirror.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
+  integrity sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==
+
+lodash.isarguments@^3.1.0:
+  version "3.1.0"
+  resolved "https://registry.npmmirror.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a"
+  integrity sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==
+
 lodash.memoize@4.x:
   version "4.1.2"
   resolved "https://registry.npmmirror.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz"
@@ -3969,6 +4097,20 @@ neo-async@^2.6.2:
   resolved "https://registry.npmmirror.com/neo-async/-/neo-async-2.6.2.tgz"
   integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
 
+nestjs-redis@^1.3.3:
+  version "1.3.3"
+  resolved "https://registry.npmmirror.com/nestjs-redis/-/nestjs-redis-1.3.3.tgz#9b285653bbe3af92cf7ecd1e2225b8bf2df32ad2"
+  integrity sha512-YLvWtVKP38Uica7pL8T955jPi0MFmJ4+Wj3R/IHbLpsdCJkdA9wtfO9NoUpiZpM1aO1dEGcOBoStvgb0Uy7MGA==
+  dependencies:
+    "@nestjs/common" "^7.4.4"
+    "@nestjs/core" "^7.4.4"
+    "@types/ioredis" "*"
+    "@types/uuid" "*"
+    ioredis "^4"
+    reflect-metadata "*"
+    rxjs "^6"
+    uuid "^8"
+
 node-abi@^3.3.0:
   version "3.15.0"
   resolved "https://registry.npmmirror.com/node-abi/-/node-abi-3.15.0.tgz#cd9ac8c58328129b49998cc6fa16aa5506152716"
@@ -4044,6 +4186,11 @@ object-assign@^4, object-assign@^4.1.0, object-assign@^4.1.1:
   resolved "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz"
   integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
 
+object-hash@2.1.1:
+  version "2.1.1"
+  resolved "https://registry.npmmirror.com/object-hash/-/object-hash-2.1.1.tgz#9447d0279b4fcf80cff3259bf66a1dc73afabe09"
+  integrity sha512-VOJmgmS+7wvXf8CjbQmimtCnEx3IAoLxI3fp2fbWehxrWBcAQFbk+vcwb6vzR0VZv/eNCJ/27j151ZTwqW/JeQ==
+
 object-hash@3.0.0:
   version "3.0.0"
   resolved "https://registry.npmmirror.com/object-hash/-/object-hash-3.0.0.tgz"
@@ -4153,6 +4300,11 @@ p-locate@^4.1.0:
   dependencies:
     p-limit "^2.2.0"
 
+p-map@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.npmmirror.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175"
+  integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==
+
 p-try@^2.0.0:
   version "2.2.0"
   resolved "https://registry.npmmirror.com/p-try/-/p-try-2.2.0.tgz"
@@ -4470,7 +4622,7 @@ rechoir@^0.6.2:
   dependencies:
     resolve "^1.1.6"
 
-redis-commands@^1.7.0:
+redis-commands@1.7.0:
   version "1.7.0"
   resolved "https://registry.npmmirror.com/redis-commands/-/redis-commands-1.7.0.tgz#15a6fea2d58281e27b1cd1acfb4b293e278c3a89"
   integrity sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==
@@ -4487,17 +4639,19 @@ redis-parser@^3.0.0:
   dependencies:
     redis-errors "^1.0.0"
 
-redis@^3:
-  version "3.1.2"
-  resolved "https://registry.npmmirror.com/redis/-/redis-3.1.2.tgz#766851117e80653d23e0ed536254677ab647638c"
-  integrity sha512-grn5KoZLr/qrRQVwoSkmzdbw6pwF+/rwODtrOr6vuBRiR/f3rjSTGupbF90Zpqm2oenix8Do6RV7pYEkGwlKkw==
+redis@^4:
+  version "4.1.0"
+  resolved "https://registry.npmmirror.com/redis/-/redis-4.1.0.tgz#6e400e8edf219e39281afe95e66a3d5f7dcf7289"
+  integrity sha512-5hvJ8wbzpCCiuN1ges6tx2SAh2XXCY0ayresBmu40/SGusWHFW86TAlIPpbimMX2DFHOX7RN34G2XlPA1Z43zg==
   dependencies:
-    denque "^1.5.0"
-    redis-commands "^1.7.0"
-    redis-errors "^1.2.0"
-    redis-parser "^3.0.0"
+    "@redis/bloom" "1.0.2"
+    "@redis/client" "1.1.0"
+    "@redis/graph" "1.0.1"
+    "@redis/json" "1.0.3"
+    "@redis/search" "1.0.6"
+    "@redis/time-series" "1.0.3"
 
-reflect-metadata@^0.1.13:
+reflect-metadata@*, reflect-metadata@^0.1.13:
   version "0.1.13"
   resolved "https://registry.npmmirror.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz"
   integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==
@@ -4594,7 +4748,7 @@ run-parallel@^1.1.9:
   dependencies:
     queue-microtask "^1.2.2"
 
-rxjs@6.6.7, rxjs@^6.6.0:
+rxjs@6.6.7, rxjs@^6, rxjs@^6.6.0:
   version "6.6.7"
   resolved "https://registry.npmmirror.com/rxjs/-/rxjs-6.6.7.tgz"
   integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==
@@ -4822,6 +4976,11 @@ stack-utils@^2.0.3:
   dependencies:
     escape-string-regexp "^2.0.0"
 
+standard-as-callback@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.npmmirror.com/standard-as-callback/-/standard-as-callback-2.1.0.tgz#8953fc05359868a77b5b9739a665c5977bb7df45"
+  integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==
+
 statuses@2.0.1:
   version "2.0.1"
   resolved "https://registry.npmmirror.com/statuses/-/statuses-2.0.1.tgz"
@@ -5186,6 +5345,11 @@ tsconfig-paths@3.14.1, tsconfig-paths@^3.10.1, tsconfig-paths@^3.9.0:
     minimist "^1.2.6"
     strip-bom "^3.0.0"
 
+tslib@2.2.0:
+  version "2.2.0"
+  resolved "https://registry.npmmirror.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c"
+  integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==
+
 tslib@2.3.1:
   version "2.3.1"
   resolved "https://registry.npmmirror.com/tslib/-/tslib-2.3.1.tgz"
@@ -5306,7 +5470,7 @@ utils-merge@1.0.1:
   resolved "https://registry.npmmirror.com/utils-merge/-/utils-merge-1.0.1.tgz"
   integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==
 
-uuid@8.3.2:
+uuid@8.3.2, uuid@^8:
   version "8.3.2"
   resolved "https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz"
   integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
@@ -5540,7 +5704,7 @@ y18n@^5.0.5:
   resolved "https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz"
   integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
 
-yallist@^4.0.0:
+yallist@4.0.0, yallist@^4.0.0:
   version "4.0.0"
   resolved "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz"
   integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==