gemercheung 3 년 전
부모
커밋
305df61b39
5개의 변경된 파일171개의 추가작업 그리고 103개의 파일을 삭제
  1. 24 8
      src/app.controller.ts
  2. 33 3
      src/cache/cache.service.ts
  3. 7 8
      src/logConfig.ts
  4. 1 3
      src/meta.gateway.ts
  5. 106 81
      src/scene/scene.service.ts

+ 24 - 8
src/app.controller.ts

@@ -1,8 +1,9 @@
-import { Controller, Get, OnModuleInit } from '@nestjs/common';
+import { Controller, Get, OnModuleInit, Param } from '@nestjs/common';
 import { AppService } from './app.service';
 import { AppService } from './app.service';
 import { grpcClientOptions } from './scene/grpc-scene.options';
 import { grpcClientOptions } from './scene/grpc-scene.options';
 import { ClientGrpc, Client } from '@nestjs/microservices';
 import { ClientGrpc, Client } from '@nestjs/microservices';
 import { SceneService } from './scene/scene.service';
 import { SceneService } from './scene/scene.service';
+import { CacheService } from './cache/cache.service';
 
 
 @Controller()
 @Controller()
 export class AppController implements OnModuleInit {
 export class AppController implements OnModuleInit {
@@ -12,6 +13,7 @@ export class AppController implements OnModuleInit {
   constructor(
   constructor(
     private readonly appService: AppService,
     private readonly appService: AppService,
     private readonly sceneService: SceneService,
     private readonly sceneService: SceneService,
+    private readonly cacheService: CacheService,
   ) { }
   ) { }
 
 
   onModuleInit() {
   onModuleInit() {
@@ -20,13 +22,27 @@ export class AppController implements OnModuleInit {
     //   this.client.getService<SceneGrpcService>('SceneGrpcService');
     //   this.client.getService<SceneGrpcService>('SceneGrpcService');
     // console.log('this.sceneGrpcService', this.sceneGrpcService);
     // console.log('this.sceneGrpcService', this.sceneGrpcService);
   }
   }
-  @Get('/api/online')
-  getOnline(): string {
-    return 'xxxxxxx';
-  }
 
 
-  @Get()
-  getHello(): string {
-    return 'xx';
+  @Get('/api/online/:roomId')
+  async getOnline(@Param('roomId') roomId): Promise<any> {
+    try {
+      const roomKey =
+        process.env.NODE_ENV === 'development'
+          ? `test-room:${roomId}`
+          : `room:${roomId}`;
+      const onlineRoomUsers = await this.cacheService.hGetAll(roomKey);
+      const userIds = Object.keys(onlineRoomUsers);
+      console.log('onlineRoomUsers', userIds);
+      return {
+        users: userIds || [],
+        total: userIds.length || 0,
+      };
+    } catch (error) {
+      console.log('error', error);
+      return {
+        users: [],
+        total: 0,
+      };
+    }
   }
   }
 }
 }

+ 33 - 3
src/cache/cache.service.ts

@@ -10,7 +10,7 @@ import { RedisService } from 'nestjs-redis';
 export class CacheService implements OnModuleInit, OnModuleDestroy {
 export class CacheService implements OnModuleInit, OnModuleDestroy {
   public client;
   public client;
   private logger: Logger = new Logger('CacheService');
   private logger: Logger = new Logger('CacheService');
-  constructor(private redisService: RedisService) {}
+  constructor(private redisService: RedisService) { }
 
 
   async onModuleInit() {
   async onModuleInit() {
     try {
     try {
@@ -30,14 +30,30 @@ export class CacheService implements OnModuleInit, OnModuleDestroy {
   }
   }
 
 
   public async set(key: string, value: any, seconds?: number) {
   public async set(key: string, value: any, seconds?: number) {
+    try {
+      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);
+      }
+    } catch (error) {
+      console.log('redis:set:error', error);
+    }
+  }
+
+  public async hset(key: string, field: string, value: any, seconds?: number) {
     value = JSON.stringify(value);
     value = JSON.stringify(value);
     if (!this.client) {
     if (!this.client) {
       await this.getClient();
       await this.getClient();
     }
     }
     if (!seconds) {
     if (!seconds) {
-      await this.client.set(key, value);
+      await this.client.hset(key, field, value);
     } else {
     } else {
-      await this.client.set(key, value, 'EX', seconds);
+      await this.client.hset(key, field, value, 'EX', seconds);
     }
     }
   }
   }
   // rpop
   // rpop
@@ -68,6 +84,14 @@ export class CacheService implements OnModuleInit, OnModuleDestroy {
     if (!data) return;
     if (!data) return;
     return JSON.parse(data);
     return JSON.parse(data);
   }
   }
+  public async hGetAll(key: string) {
+    if (!this.client) {
+      await this.getClient();
+    }
+    const data = await this.client.hgetall(key);
+    if (!data) return;
+    return data;
+  }
 
 
   public async keys(key: string) {
   public async keys(key: string) {
     if (!this.client) {
     if (!this.client) {
@@ -84,6 +108,12 @@ export class CacheService implements OnModuleInit, OnModuleDestroy {
     }
     }
     await this.client.del(key);
     await this.client.del(key);
   }
   }
+  public async hDel(key: string, field: string) {
+    if (!this.client) {
+      await this.getClient();
+    }
+    await this.client.hdel(key, field);
+  }
   // 清理缓存
   // 清理缓存
   public async flushall(): Promise<any> {
   public async flushall(): Promise<any> {
     if (!this.client) {
     if (!this.client) {

+ 7 - 8
src/logConfig.ts

@@ -62,19 +62,18 @@ export const LoggerConfig = {
     // }),
     // }),
     new winston.transports.File({
     new winston.transports.File({
       dirname: logDir,
       dirname: logDir,
-      filename: 'bootsrap.log',
-      level: 'http',
-    }),
-
-    new winston.transports.File({
-      dirname: logDir,
       filename: 'combine.log',
       filename: 'combine.log',
       level: 'error',
       level: 'error',
     }),
     }),
+    // new winston.transports.File({
+    //   dirname: logDir,
+    //   filename: 'combine.log',
+    //   level: 'info',
+    // }),
     new winston.transports.File({
     new winston.transports.File({
       dirname: logDir,
       dirname: logDir,
-      filename: 'combine.log',
-      level: 'info',
+      filename: 'bootsrap.log',
+      level: 'http',
     }),
     }),
   ],
   ],
 };
 };

+ 1 - 3
src/meta.gateway.ts

@@ -85,10 +85,8 @@ export class MetaGateway
 
 
   @SubscribeMessage('init_webrtc')
   @SubscribeMessage('init_webrtc')
   handleInitWebRtc(client: any, payload: any): void {
   handleInitWebRtc(client: any, payload: any): void {
-    // TODO 可能会中断连接
-    // cleanup();
     this.logger.info('action::handleInitWebRtc', JSON.stringify(payload));
     this.logger.info('action::handleInitWebRtc', JSON.stringify(payload));
-    this.logger.log('http', `socket::开始`);
+    this.logger.log('debug', `socket::开始`);
     const stun_server = this.configService.get('stun.server');
     const stun_server = this.configService.get('stun.server');
     const portRangeBegin = this.configService.get('stun.portRangeBegin');
     const portRangeBegin = this.configService.get('stun.portRangeBegin');
     const portRangeEnd = this.configService.get('stun.portRangeEnd');
     const portRangeEnd = this.configService.get('stun.portRangeEnd');

+ 106 - 81
src/scene/scene.service.ts

@@ -17,6 +17,11 @@ import { MoveService } from 'src/move/move.service';
 import { GetRouterService } from 'src/get-router/get-router.service';
 import { GetRouterService } from 'src/get-router/get-router.service';
 import { ConfigService } from '@nestjs/config';
 import { ConfigService } from '@nestjs/config';
 
 
+// interface UserInfo {
+//   userId: string;
+//   roomId: string;
+// }
+
 const seqExeAsyncFn = (asyncFn) => {
 const seqExeAsyncFn = (asyncFn) => {
   let runPromise = null;
   let runPromise = null;
   return function seq(...args) {
   return function seq(...args) {
@@ -38,7 +43,7 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
     private rotateService: RotateService,
     private rotateService: RotateService,
     private moveService: MoveService,
     private moveService: MoveService,
     private getRouterService: GetRouterService, // @InjectQueue('rotate') private rotateQueue: Queue, // @InjectQueue('walking') private walkingQueue: Queue,
     private getRouterService: GetRouterService, // @InjectQueue('rotate') private rotateQueue: Queue, // @InjectQueue('walking') private walkingQueue: Queue,
-  ) {}
+  ) { }
   @Client(grpcClientOptions) private readonly client: ClientGrpc;
   @Client(grpcClientOptions) private readonly client: ClientGrpc;
 
 
   public _frameInteval: NodeJS.Timeout;
   public _frameInteval: NodeJS.Timeout;
@@ -230,10 +235,17 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
     }
     }
   }
   }
 
 
-  exit() {
+  async exit() {
     this.frameCnt.next(-1);
     this.frameCnt.next(-1);
     this.rotateService.deleteUser(this.user_id);
     this.rotateService.deleteUser(this.user_id);
     this.hasJoystickFocusRepeat = false;
     this.hasJoystickFocusRepeat = false;
+    const userId = this.user_id;
+    const roomId = this.roomId;
+    const roomKey =
+      process.env.NODE_ENV === 'development'
+        ? `test-room:${roomId}`
+        : `room:${roomId}`;
+    this.cacheService.hDel(roomKey, userId);
     if (this.startSub) {
     if (this.startSub) {
       this.startSub.unsubscribe();
       this.startSub.unsubscribe();
       this.startSub = null;
       this.startSub = null;
@@ -297,7 +309,7 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
             const rounded = Number(inMillSeconds).toFixed(3);
             const rounded = Number(inMillSeconds).toFixed(3);
             this.logger.log(
             this.logger.log(
               `[timer]-rotate-入队列前: ${rounded}ms -->` +
               `[timer]-rotate-入队列前: ${rounded}ms -->` +
-                JSON.stringify(stream),
+              JSON.stringify(stream),
             );
             );
             if (!this.stopRotated) {
             if (!this.stopRotated) {
               await this.seqExehandleRotateStream(stream);
               await this.seqExehandleRotateStream(stream);
@@ -494,16 +506,16 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
     const playerAngle = newUserStates.playerState.player.angle;
     const playerAngle = newUserStates.playerState.player.angle;
     this.logger.log(
     this.logger.log(
       'stop-data-0' +
       'stop-data-0' +
-        'trace_id: ' +
-        trace_id +
-        'userId:' +
-        userId +
-        'breakPointId :' +
-        breakPointId +
-        'cameraAngle :' +
-        JSON.stringify(cameraAngle) +
-        'playerAngle: ' +
-        JSON.stringify(playerAngle),
+      'trace_id: ' +
+      trace_id +
+      'userId:' +
+      userId +
+      'breakPointId :' +
+      breakPointId +
+      'cameraAngle :' +
+      JSON.stringify(cameraAngle) +
+      'playerAngle: ' +
+      JSON.stringify(playerAngle),
     );
     );
     //debugger;
     //debugger;
     console.log('moveService.stop-1:' + breakPointId);
     console.log('moveService.stop-1:' + breakPointId);
@@ -547,18 +559,18 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
     }
     }
   }
   }
 
 
-  async getSimplestCameraInfo(appId,userId){
-    if(this.moveService.cameraInfos.length>20){
+  async getSimplestCameraInfo(appId, userId) {
+    if (this.moveService.cameraInfos.length > 20) {
       const startBreakPointId = this.moveService.cameraInfos[0].startBreakPointId;
       const startBreakPointId = this.moveService.cameraInfos[0].startBreakPointId;
-      const endBreakPointId = this.moveService.cameraInfos[this.moveService.cameraInfos.length-1].endBreakPointId;
+      const endBreakPointId = this.moveService.cameraInfos[this.moveService.cameraInfos.length - 1].endBreakPointId;
 
 
-      const path = this.getRouterService.searchRoad2(startBreakPointId,endBreakPointId);
-      if(path == null){
+      const path = this.getRouterService.searchRoad2(startBreakPointId, endBreakPointId);
+      if (path == null) {
         //可以清空cameraInfos
         //可以清空cameraInfos
         this.moveService.cameraInfos = [];
         this.moveService.cameraInfos = [];
       }
       }
-      else{
-        await this.moveService.updateCameraInfoForDely(appId,userId,path);
+      else {
+        await this.moveService.updateCameraInfoForDely(appId, userId, path);
       }
       }
     }
     }
   }
   }
@@ -683,15 +695,15 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
       console.log('进入1 - searchRoad');
       console.log('进入1 - searchRoad');
       this.logger.log(
       this.logger.log(
         'handleWalking-users' +
         'handleWalking-users' +
-          JSON.stringify(this.moveService.users) +
-          ' this.user_id: ' +
-          this.user_id,
+        JSON.stringify(this.moveService.users) +
+        ' this.user_id: ' +
+        this.user_id,
       );
       );
       this.logger.log(
       this.logger.log(
         'handleWalking-currentUser' +
         'handleWalking-currentUser' +
-          JSON.stringify(user) +
-          ' this.user_id: ' +
-          this.user_id,
+        JSON.stringify(user) +
+        ' this.user_id: ' +
+        this.user_id,
       );
       );
       console.log('path-start' + user.breakPointId);
       console.log('path-start' + user.breakPointId);
 
 
@@ -723,7 +735,7 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
               (item: StreamReplyType, index: number) => {
               (item: StreamReplyType, index: number) => {
                 console.log(
                 console.log(
                   '20220628test:handleWalking->' +
                   '20220628test:handleWalking->' +
-                    item['newUserStates'][0].renderInfo.isMoving,
+                  item['newUserStates'][0].renderInfo.isMoving,
                 );
                 );
                 //const IDRflag = index % 5 === 0 ? 1 : 3;
                 //const IDRflag = index % 5 === 0 ? 1 : 3;
                 const IDRflag = item.isIDR ? 1 : 3;
                 const IDRflag = item.isIDR ? 1 : 3;
@@ -750,16 +762,16 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
         if (seqs?.length) {
         if (seqs?.length) {
           this.logger.log(
           this.logger.log(
             'walking --队列总览:' +
             'walking --队列总览:' +
-              ' 总段数: ' +
-              walkingRes.length +
-              ' 镜头帧数:' +
-              walkingRes[0].length +
-              ' 行走段数:' +
-              (walkingRes[0]?.length
-                ? walkingRes.length - 1
-                : walkingRes.length) +
-              ' 队列总帧数:' +
-              seqs.length,
+            ' 总段数: ' +
+            walkingRes.length +
+            ' 镜头帧数:' +
+            walkingRes[0].length +
+            ' 行走段数:' +
+            (walkingRes[0]?.length
+              ? walkingRes.length - 1
+              : walkingRes.length) +
+            ' 队列总帧数:' +
+            seqs.length,
           );
           );
           const stop = performance.now();
           const stop = performance.now();
           const inMillSeconds = stop - start;
           const inMillSeconds = stop - start;
@@ -817,7 +829,7 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
     //console.log('joystickRes有mediaSrc', joystickRes.mediaSrc);
     //console.log('joystickRes有mediaSrc', joystickRes.mediaSrc);
     console.log(
     console.log(
       'handlejoystick-angle->相机角度-------------------------:' +
       'handlejoystick-angle->相机角度-------------------------:' +
-        joystickRes['newUserStates'][0].playerState.camera.angle.yaw,
+      joystickRes['newUserStates'][0].playerState.camera.angle.yaw,
     );
     );
     let streamData: StreamFrameType | StreamMetaType;
     let streamData: StreamFrameType | StreamMetaType;
 
 
@@ -839,11 +851,11 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
       };
       };
       console.log(
       console.log(
         'handlejoystick-hasMedia->-------------------------:' +
         'handlejoystick-hasMedia->-------------------------:' +
-          ' frame: ' +
-          streamData.frame +
-          mediaSrc +
-          '  IDR :' +
-          setDIR,
+        ' frame: ' +
+        streamData.frame +
+        mediaSrc +
+        '  IDR :' +
+        setDIR,
       );
       );
     } else {
     } else {
       streamData = {
       streamData = {
@@ -862,8 +874,8 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
     const hasPush = hasMedia
     const hasPush = hasMedia
       ? await this.streamService.pushFrameToSteam(streamData as StreamFrameType)
       ? await this.streamService.pushFrameToSteam(streamData as StreamFrameType)
       : await this.streamService.pushMetaDataToSteam(
       : await this.streamService.pushMetaDataToSteam(
-          streamData as StreamMetaType,
-        );
+        streamData as StreamMetaType,
+      );
 
 
     if (hasPush.done) {
     if (hasPush.done) {
       this.isJoystickHasStream = true;
       this.isJoystickHasStream = true;
@@ -900,9 +912,9 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
         if (complementFrame) {
         if (complementFrame) {
           console.log(
           console.log(
             '20220627test-complementFrame 进行' +
             '20220627test-complementFrame 进行' +
-              complementFrame.mediaSrc +
-              '***' +
-              this.frameCnt.value,
+            complementFrame.mediaSrc +
+            '***' +
+            this.frameCnt.value,
           );
           );
           // 第二次或N次进入时如果有值直接重新进入流主程
           // 第二次或N次进入时如果有值直接重新进入流主程
           this.holdSteam();
           this.holdSteam();
@@ -935,7 +947,7 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
     this._JoyStickingSteamTimeout = setTimeout(async () => {
     this._JoyStickingSteamTimeout = setTimeout(async () => {
       console.log('20220627test-complementFrame handleJoystickStop 200ms之后');
       console.log('20220627test-complementFrame handleJoystickStop 200ms之后');
       const user = this.moveService.users[this.user_id];
       const user = this.moveService.users[this.user_id];
-      await this.getSimplestCameraInfo(user.appId,this.user_id);
+      await this.getSimplestCameraInfo(user.appId, this.user_id);
       const complementFrame = this.moveService.complementFrame(
       const complementFrame = this.moveService.complementFrame(
         this.user_id,
         this.user_id,
       ) as StreamReplyType;
       ) as StreamReplyType;
@@ -977,7 +989,7 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
       const joystickRes = await this.moveService.seqExeJoystick(request);
       const joystickRes = await this.moveService.seqExeJoystick(request);
       this.logger.log(
       this.logger.log(
         'joystick-breakPointId:' +
         'joystick-breakPointId:' +
-          this.moveService.users[this.user_id].breakPointId,
+        this.moveService.users[this.user_id].breakPointId,
       );
       );
       // 有数据 [0]是rotate数据,[1-infinity]是walking数据
       // 有数据 [0]是rotate数据,[1-infinity]是walking数据
       //this.logger.log('joystickRes', JSON.stringify(joystickRes));
       //this.logger.log('joystickRes', JSON.stringify(joystickRes));
@@ -1062,14 +1074,14 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
         };
         };
         this.logger.log(
         this.logger.log(
           '[media-move]: ' +
           '[media-move]: ' +
-            ', moveframeCnt: ' +
-            this.moveframeCnt +
-            ', clipPath: ' +
-            stream.clipPath +
-            ', mType: ' +
-            stream.mType +
-            ', DIR: ' +
-            stream.DIR,
+          ', moveframeCnt: ' +
+          this.moveframeCnt +
+          ', clipPath: ' +
+          stream.clipPath +
+          ', mType: ' +
+          stream.mType +
+          ', DIR: ' +
+          stream.DIR,
           // stream.metaData,
           // stream.metaData,
         );
         );
         this.logger.log(
         this.logger.log(
@@ -1159,13 +1171,26 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
     this.rotateStopThrottle = false;
     this.rotateStopThrottle = false;
   }
   }
 
 
-  handleDataChanelOpen(channel: DataChannel, peer: PeerConnection): void {
+  async handleDataChanelOpen(
+    channel: DataChannel,
+    peer: PeerConnection,
+  ): Promise<void> {
     this.channel = channel;
     this.channel = channel;
     this.peer = peer;
     this.peer = peer;
     this.streamService.setChannel(channel);
     this.streamService.setChannel(channel);
     this.startSteaming.next(true);
     this.startSteaming.next(true);
     // this.startStream();
     // this.startStream();
     // this.handleStream();
     // this.handleStream();
+    //TODO 正式channel打开记录,记录多少人在线
+    const userId = this.user_id;
+    const roomId = this.roomId;
+    const roomKey =
+      process.env.NODE_ENV === 'development'
+        ? `test-room:${roomId}`
+        : `room:${roomId}`;
+
+    this.cacheService.hset(roomKey, userId, 1);
+    // debugger;
     this.channel.onBufferedAmountLow(() => {
     this.channel.onBufferedAmountLow(() => {
       console.error('onBufferedAmountLow-rtt', this.peer.rtt());
       console.error('onBufferedAmountLow-rtt', this.peer.rtt());
       console.error('onBufferedAmountLow', this.channel.bufferedAmount());
       console.error('onBufferedAmountLow', this.channel.bufferedAmount());
@@ -1329,16 +1354,16 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
           this.logger.log('frame', frame);
           this.logger.log('frame', frame);
           console.log(
           console.log(
             'networkState:::--->' +
             'networkState:::--->' +
-              ' maxMessageSize: ' +
-              this.channel.maxMessageSize() +
-              ' bytesReceived: ' +
-              this.peer.bytesReceived() +
-              ' bytesSent: ' +
-              this.peer.bytesSent() +
-              ' rtt: ' +
-              this.peer.rtt() +
-              ' state: ' +
-              this.peer.state(),
+            ' maxMessageSize: ' +
+            this.channel.maxMessageSize() +
+            ' bytesReceived: ' +
+            this.peer.bytesReceived() +
+            ' bytesSent: ' +
+            this.peer.bytesSent() +
+            ' rtt: ' +
+            this.peer.rtt() +
+            ' state: ' +
+            this.peer.state(),
           );
           );
           if (frame === 1) {
           if (frame === 1) {
             // redisData = await this.rotateService.echo(this.user_id, true);
             // redisData = await this.rotateService.echo(this.user_id, true);
@@ -1359,7 +1384,7 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
                 delete redisData.mediaSrc;
                 delete redisData.mediaSrc;
                 this.logger.log(
                 this.logger.log(
                   `user:${this.user_id}:first render stream` +
                   `user:${this.user_id}:first render stream` +
-                    JSON.stringify({ path: clipPath, meta: redisData }),
+                  JSON.stringify({ path: clipPath, meta: redisData }),
                 );
                 );
                 const status = await this.pushFirstRender(
                 const status = await this.pushFirstRender(
                   clipPath,
                   clipPath,
@@ -1388,17 +1413,17 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
 
 
             console.log(
             console.log(
               '空白流条件-->:' +
               '空白流条件-->:' +
-                isOk +
-                ' onMoving: ' +
-                this.onMoving.value +
-                ' onRotating: ' +
-                this.onRotating.value +
-                ' onJoysticking: ' +
-                this.onJoysticking.value +
-                ' onSteaming: ' +
-                this.onSteaming +
-                ' firstRender: ' +
-                this.firstRender,
+              isOk +
+              ' onMoving: ' +
+              this.onMoving.value +
+              ' onRotating: ' +
+              this.onRotating.value +
+              ' onJoysticking: ' +
+              this.onJoysticking.value +
+              ' onSteaming: ' +
+              this.onSteaming +
+              ' firstRender: ' +
+              this.firstRender,
             );
             );
           }
           }