Browse Source

feat: update

test pc 3 years ago
parent
commit
202ab71c2b

+ 3 - 2
config.dev.yaml

@@ -2,6 +2,7 @@
 app:
   prefix: /mnt/metaverse/scene
   startPoint: 29
+  appId: "0000000003"
 
 log:
   logFolder: /var/log/metaverse
@@ -41,8 +42,8 @@ queueRedis:
 
 stun:
   server: ['turn:4dage:4dage168@47.107.125.202:4478', 'stun:47.107.125.202:3478']
-  portRangeBegin: 52000
-  portRangeEnd: 53000
+  portRangeBegin: 49152
+  portRangeEnd: 65535
 
 server:
   private_ip: 172.18.197.114

+ 48 - 0
config.p0000005-bk.yaml

@@ -0,0 +1,48 @@
+app:
+  prefix: /mnt/metaverse/scene
+  startPoint: 17
+  appId: "0000000005"
+
+log:
+  logFolder: /var/log/metaverse
+
+queueConfig:
+  move: 80
+  rotate: 2
+
+http:
+  host: '0.0.0.0'
+  port: 6688
+
+grpc:
+  url: '221.4.210.172:23000'
+# grpc:
+#   url: '192.168.0.47:3000'
+
+redis:
+  port: 6379
+  host: '47.107.125.202' #远程调试需要设置bindip 为0.0.0.0 并且设置密码
+  password: 'Happy@Pass#@!7' # 非远程不需要密码
+  decode_responses: true
+  db: 9
+# queueRedis:
+#   port: 6379
+#   host: '127.0.0.1' #远程调试需要设置bindip 为0.0.0.0 并且设置密码
+#   password: 'sxz123321SxZ@' # 非远程不需要密码
+#   decode_responses: true
+#   db: 14
+# server: ['stun:47.107.125.202:3478','stun:120.24.252.95:3478']
+#  server: ['stun:4dage:4dage168@47.107.125.202:3478','stun:120.24.252.95:3478']
+stun:
+  server: ['turn:4dage:4dage168@turn.4dage.com:4478', 'stun:120.24.252.95:3478']
+  portRangeBegin: 49152
+  portRangeEnd: 65535
+
+server:
+  private_ip: 172.18.144.42
+  public_ip: 47.107.125.202
+# PRIVATE_IP=172.18.197.114
+# PUBLIC_IP=120.24.252.95
+# STUNS_SEVER="stun:172.18.156.41:3478,stun:120.24.252.95:3478"
+# GRPC_URL="192.168.0.48:3000"
+# REDIS_URL="redis://:192.168.0.47:6379/9"

+ 1 - 0
config.production.yaml

@@ -1,6 +1,7 @@
 app:
   prefix: /mnt/metaverse/scene
   startPoint: 29
+  appId: "0000000005"
 
 queueConfig:
   move: 80

+ 4 - 3
config.production1.yaml

@@ -1,6 +1,7 @@
 app:
   prefix: /mnt/metaverse/scene
   startPoint: 29
+  appId: "0000000003"
 
 log:
   logFolder: /var/log/metaverse
@@ -33,9 +34,9 @@ redis:
 # server: ['stun:47.107.125.202:3478','stun:120.24.252.95:3478']
 #  server: ['stun:4dage:4dage168@47.107.125.202:3478','stun:120.24.252.95:3478']
 stun:
-  server: ['stun:4dage:4dage168@turn.4dage.com:4478', 'stun:120.24.252.95:3478']
-  portRangeBegin: 50000
-  portRangeEnd: 55000
+  server: ['turn:4dage:4dage168@turn.4dage.com:4478', 'stun:120.24.252.95:3478']
+  portRangeBegin: 49152
+  portRangeEnd: 65535
 
 server:
   private_ip: 172.18.144.42

+ 102 - 102
package.json

@@ -1,102 +1,102 @@
-{
-  "name": "meta-server",
-  "version": "0.0.1",
-  "description": "",
-  "author": "",
-  "private": true,
-  "license": "UNLICENSED",
-  "scripts": {
-    "prebuild": "rimraf dist",
-    "build": "cross-env NODE_ENV=production nest build",
-    "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\" \"libs/**/*.ts\"",
-    "start": "cross-env NODE_ENV=development nest start",
-    "start:dev": "cross-env NODE_ENV=development nest start --watch",
-    "start:debug": "cross-env NODE_ENV=development nest start --debug 0.0.0.0:9229 --watch",
-    "start:prod": "cross-env NODE_ENV=production node dist/main",
-    "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
-    "test": "jest",
-    "test:watch": "jest --watch",
-    "test:cov": "jest --coverage",
-    "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
-    "test:e2e": "jest --config ./test/jest-e2e.json"
-  },
-  "dependencies": {
-    "@grpc/grpc-js": "^1.6.7",
-    "@grpc/proto-loader": "^0.6.12",
-    "@nestjs/bull": "^0.5.5",
-    "@nestjs/common": "^8.0.0",
-    "@nestjs/config": "^2.0.0",
-    "@nestjs/core": "^8.0.0",
-    "@nestjs/microservices": "^8.4.4",
-    "@nestjs/platform-express": "^8.0.0",
-    "@nestjs/platform-socket.io": "^8.4.4",
-    "@nestjs/platform-ws": "^8.4.4",
-    "@nestjs/websockets": "^8.4.4",
-    "ajv": "^8.11.0",
-    "buffer": "^6.0.3",
-    "bull": "^4.8.3",
-    "js-yaml": "^4.1.0",
-    "multistream": "^4.1.0",
-    "nest-winston": "^1.6.2",
-    "nestjs-redis": "git+https://github.com/GyanendroKh/nestjs-redis.git#nest8-fix",
-    "node-datachannel": "^0.3.2",
-    "redis": "^4",
-    "reflect-metadata": "^0.1.13",
-    "rimraf": "^3.0.2",
-    "rx-queue": "^1.0.5",
-    "rxjs": "^7.2.0",
-    "stream-buffers": "^3.0.2",
-    "winston": "^3.7.2"
-  },
-  "devDependencies": {
-    "@nestjs/cli": "^8.0.0",
-    "@nestjs/schematics": "^8.0.0",
-    "@nestjs/testing": "^8.0.0",
-    "@types/bull": "^3.15.8",
-    "@types/express": "^4.17.13",
-    "@types/jest": "27.4.1",
-    "@types/js-yaml": "^4.0.5",
-    "@types/node": "^16.0.0",
-    "@types/supertest": "^2.0.11",
-    "@typescript-eslint/eslint-plugin": "^5.0.0",
-    "@typescript-eslint/parser": "^5.0.0",
-    "cross-env": "^7.0.3",
-    "eslint": "^8.0.1",
-    "eslint-config-prettier": "^8.3.0",
-    "eslint-plugin-prettier": "^4.0.0",
-    "jest": "^27.2.5",
-    "prettier": "^2.3.2",
-    "rollup-plugin-string": "^3.0.0",
-    "source-map-support": "^0.5.20",
-    "supertest": "^6.1.3",
-    "ts-jest": "^27.0.3",
-    "ts-loader": "^9.2.3",
-    "ts-node": "^10.0.0",
-    "tsconfig-paths": "^3.10.1",
-    "typescript": "^4.3.5"
-  },
-  "jest": {
-    "moduleFileExtensions": [
-      "js",
-      "json",
-      "ts"
-    ],
-    "rootDir": ".",
-    "testRegex": ".*\\.spec\\.ts$",
-    "transform": {
-      "^.+\\.(t|j)s$": "ts-jest"
-    },
-    "collectCoverageFrom": [
-      "**/*.(t|j)s"
-    ],
-    "coverageDirectory": "./coverage",
-    "testEnvironment": "node",
-    "roots": [
-      "<rootDir>/src/",
-      "<rootDir>/libs/"
-    ],
-    "moduleNameMapper": {
-      "^@app/utils(|/.*)$": "<rootDir>/libs/utils/src/$1"
-    }
-  }
-}
+{
+  "name": "meta-server",
+  "version": "0.0.1",
+  "description": "",
+  "author": "",
+  "private": true,
+  "license": "UNLICENSED",
+  "scripts": {
+    "prebuild": "rimraf dist",
+    "build": "cross-env NODE_ENV=production nest build",
+    "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\" \"libs/**/*.ts\"",
+    "start": "cross-env NODE_ENV=development nest start",
+    "start:dev": "cross-env NODE_ENV=development nest start --watch",
+    "start:debug": "cross-env NODE_ENV=development nest start --debug 0.0.0.0:9229 --watch",
+    "start:prod": "cross-env NODE_ENV=production node dist/main",
+    "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
+    "test": "jest",
+    "test:watch": "jest --watch",
+    "test:cov": "jest --coverage",
+    "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
+    "test:e2e": "jest --config ./test/jest-e2e.json"
+  },
+  "dependencies": {
+    "@grpc/grpc-js": "^1.6.7",
+    "@grpc/proto-loader": "^0.6.12",
+    "@nestjs/bull": "^0.5.5",
+    "@nestjs/common": "^8.0.0",
+    "@nestjs/config": "^2.0.0",
+    "@nestjs/core": "^8.0.0",
+    "@nestjs/microservices": "^8.4.4",
+    "@nestjs/platform-express": "^8.0.0",
+    "@nestjs/platform-socket.io": "^8.4.4",
+    "@nestjs/platform-ws": "^8.4.4",
+    "@nestjs/websockets": "^8.4.4",
+    "ajv": "^8.11.0",
+    "buffer": "^6.0.3",
+    "bull": "^4.8.3",
+    "js-yaml": "^4.1.0",
+    "multistream": "^4.1.0",
+    "nest-winston": "^1.6.2",
+    "nestjs-redis": "git+https://github.com/GyanendroKh/nestjs-redis.git#nest8-fix",
+    "node-datachannel": "^0.3.4",
+    "redis": "^4",
+    "reflect-metadata": "^0.1.13",
+    "rimraf": "^3.0.2",
+    "rx-queue": "^1.0.5",
+    "rxjs": "^7.2.0",
+    "stream-buffers": "^3.0.2",
+    "winston": "^3.7.2"
+  },
+  "devDependencies": {
+    "@nestjs/cli": "^8.0.0",
+    "@nestjs/schematics": "^8.0.0",
+    "@nestjs/testing": "^8.0.0",
+    "@types/bull": "^3.15.8",
+    "@types/express": "^4.17.13",
+    "@types/jest": "27.4.1",
+    "@types/js-yaml": "^4.0.5",
+    "@types/node": "^16.0.0",
+    "@types/supertest": "^2.0.11",
+    "@typescript-eslint/eslint-plugin": "^5.0.0",
+    "@typescript-eslint/parser": "^5.0.0",
+    "cross-env": "^7.0.3",
+    "eslint": "^8.0.1",
+    "eslint-config-prettier": "^8.3.0",
+    "eslint-plugin-prettier": "^4.0.0",
+    "jest": "^27.2.5",
+    "prettier": "^2.3.2",
+    "rollup-plugin-string": "^3.0.0",
+    "source-map-support": "^0.5.20",
+    "supertest": "^6.1.3",
+    "ts-jest": "^27.0.3",
+    "ts-loader": "^9.2.3",
+    "ts-node": "^10.0.0",
+    "tsconfig-paths": "^3.10.1",
+    "typescript": "^4.3.5"
+  },
+  "jest": {
+    "moduleFileExtensions": [
+      "js",
+      "json",
+      "ts"
+    ],
+    "rootDir": ".",
+    "testRegex": ".*\\.spec\\.ts$",
+    "transform": {
+      "^.+\\.(t|j)s$": "ts-jest"
+    },
+    "collectCoverageFrom": [
+      "**/*.(t|j)s"
+    ],
+    "coverageDirectory": "./coverage",
+    "testEnvironment": "node",
+    "roots": [
+      "<rootDir>/src/",
+      "<rootDir>/libs/"
+    ],
+    "moduleNameMapper": {
+      "^@app/utils(|/.*)$": "<rootDir>/libs/utils/src/$1"
+    }
+  }
+}

+ 1 - 1
src/cache/cache.service.ts

@@ -25,7 +25,7 @@ export class CacheService implements OnModuleInit, OnModuleDestroy {
     this.client = null;
   }
 
-  async getClient() {
+  public async getClient() {
     this.client = await this.redisService.getClient();
   }
 

+ 12 - 2
src/get-router/get-router.service.ts

@@ -1,18 +1,28 @@
 import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
+import { ConfigService } from '@nestjs/config';
 import { readFileSync } from 'fs';
 import { join } from 'path';
 import { CacheService } from 'src/cache/cache.service';
+import configuration from 'src/config/configuration';
 
 @Injectable()
 export class GetRouterService implements OnModuleInit {
   constructor(private cacheService: CacheService) {}
   private breakPointInfo: any;
   private logger: Logger = new Logger('GetRouterService');
+  // private configService: ConfigService;
 
   // eslint-disable-next-line @typescript-eslint/no-empty-function
   async onModuleInit() {
-    const app_id = '0000000003';
-    const prefix = '/mnt/metaverse/scene';
+    // const app_id = this.configService.get('app.appId');
+    // const prefix = this.configService.get('app.prefix');
+    const app_id = configuration().app.appId;
+    const prefix = configuration().app.prefix;
+
+    // const app_id = '0000000005';
+    // const prefix = '/mnt/metaverse/scene';
+    console.log('app_id', app_id, configuration().app.appId);
+    console.log('prefix', prefix, configuration().app.appId);
     let path;
     // let path: string;
     if (process.env.NODE_ENV === 'development') {

+ 24 - 7
src/logConfig.ts

@@ -15,23 +15,40 @@ if (process.env.NODE_ENV === 'production') {
 console.log('logDir', logDir);
 export const LoggerConfig = {
   format: winston.format.combine(
-    winston.format.timestamp(),
+    winston.format.timestamp({
+      format: 'YYYY-MM-DD HH:mm:ss SSS',
+    }),
     winston.format.ms(),
+    winston.format.json(),
+    // winston.format.printf(
+    //   (info) => `${info.timestamp} ${info.level}: ${info.message}`,
+    // ),
     nestWinstonModuleUtilities.format.nestLike('Meta-server', {
-      prettyPrint: true,
+      prettyPrint: false,
     }),
   ),
+  exitOnError: false,
   transports: [
     new winston.transports.Console(),
+    // new winston.transports.File({
+    //   dirname: logDir, //path to where save loggin result
+    //   filename: 'combine.log', //name of file where will be saved logging result
+    //   level: 'debug',
+    // }),
+    // new winston.transports.File({
+    //   dirname: logDir, //path to where save loggin result
+    //   filename: 'combine.log', //name of file where will be saved logging result
+    //   level: 'log',
+    // }),
     new winston.transports.File({
-      dirname: logDir, //path to where save loggin result
-      filename: 'debug.log', //name of file where will be saved logging result
-      level: 'debug',
+      dirname: logDir,
+      filename: 'combine.log',
+      level: 'info',
     }),
     new winston.transports.File({
       dirname: logDir,
-      filename: 'info.log',
-      level: 'info',
+      filename: 'combine.log',
+      level: 'error',
     }),
     new winston.transports.File({
       dirname: logDir,

+ 13 - 9
src/meta.gateway.ts

@@ -88,17 +88,20 @@ export class MetaGateway
 
   @SubscribeMessage('init_webrtc')
   handleInitWebRtc(client: any, payload: any): void {
-    cleanup();
+    // TODO 可能会中断连接
+    // cleanup();
     this.logger.log('action::handleInitWebRtc', JSON.stringify(payload));
     const stun_server = this.configService.get('stun.server');
     const portRangeBegin = this.configService.get('stun.portRangeBegin');
     const portRangeEnd = this.configService.get('stun.portRangeEnd');
 
-    this.peer = new PeerConnection('roomTest', {
+    this.peer = new PeerConnection('roomRtc', {
       portRangeBegin: portRangeBegin,
       portRangeEnd: portRangeEnd,
       iceServers: stun_server,
       // enableIceTcp: true,
+      maxMessageSize: 662144,
+      mtu: 1500,
     });
 
     this.peer.onLocalDescription((sdp, type) => {
@@ -185,14 +188,15 @@ export class MetaGateway
     });
 
     this.gameChanel.onOpen(() => {
-      console.log('channel is open');
-      this.sceneService.handleDataChanelOpen(this.gameChanel);
-      const peers = this.peer.getSelectedCandidatePair();
-      this.logger.log('配对成功', JSON.stringify(peers));
-
+      this.logger.log('channel is open');
       if (this.gameChanel.isOpen()) {
+        const peers = this.peer.getSelectedCandidatePair();
+        this.logger.log('配对成功', JSON.stringify(peers));
         console.log('gameChanel', this.gameChanel.isOpen());
         this.sendWertcHeartPack(this.gameChanel);
+        this.sceneService.handleDataChanelOpen(this.gameChanel, this.peer);
+      } else {
+        console.log('gameChanel has problem');
       }
 
       // Number.prototype.padLeft = function (n, str) {
@@ -266,8 +270,8 @@ export class MetaGateway
 
       const startReply = {
         id: 'start',
-        data: '{"IsHost":false,"SkinID":"10089","SkinDataVersion":"1008900008","RoomTypeID":""}',
-        room_id: 'e629ef3e-022d-4e64-8654-703bb96410eb',
+        data: '{"IsHost":false,"SkinID":"0000000001","SkinDataVersion":"1008900008","RoomTypeID":""}',
+        room_id: 'aea5406a-3099-48db-b428-30917872e58a',
         channel_id: '3a1a62e9a3c74de6___channel',
         user_id: 'ed58c8d4ce38c',
         trace_id: '394df10a-d924-43a9-940d-1dbb41e43f24',

+ 98 - 72
src/move/move.service.ts

@@ -829,7 +829,9 @@ export class MoveService implements OnModuleInit {
       this.reply.mediaSrc = null;
 
       if (surroundPointIds.length == 1) {
-        console.log('joystick校验--->'+breakPointId+'-'+surroundPointIds[0]);
+        console.log(
+          'joystick校验--->' + breakPointId + '-' + surroundPointIds[0],
+        );
         return await this.moveDirect(
           playerPosition,
           closestDis,
@@ -875,7 +877,9 @@ export class MoveService implements OnModuleInit {
           neighPoints.push(neighPoint);
           ++count;
         } else if (Math.abs(angle - move_angle) == 0) {
-          console.log('joystick直走--->'+breakPointId+'-'+surroundPointIds[i]);
+          console.log(
+            'joystick直走--->' + breakPointId + '-' + surroundPointIds[i],
+          );
           return await this.moveDirect(
             playerPosition,
             closestDis,
@@ -895,12 +899,15 @@ export class MoveService implements OnModuleInit {
           ++count;
         }
 
-        if(Math.abs(angle - move_angle)<45||Math.abs(angle+360 - move_angle)<45){
-          if(singleInfo == null){
+        if (
+          Math.abs(angle - move_angle) < 45 ||
+          Math.abs(angle + 360 - move_angle) < 45
+        ) {
+          if (singleInfo == null) {
             singleInfo = {
-              angle:angle,
-              breakPointId:surroundPointIds[i]
-            }
+              angle: angle,
+              breakPointId: surroundPointIds[i],
+            };
           }
         }
       }
@@ -911,10 +918,11 @@ export class MoveService implements OnModuleInit {
         this.reply['newUserStates'][0].playerState.player.position = JSON.parse(
           JSON.stringify(playerPosition),
         );
-      } 
-      else{
-        if(singleInfo != null){
-          console.log('joystick校验--->'+breakPointId+'-'+singleInfo.breakPointId);
+      } else {
+        if (singleInfo != null) {
+          console.log(
+            'joystick校验--->' + breakPointId + '-' + singleInfo.breakPointId,
+          );
           return await this.moveDirect(
             playerPosition,
             closestDis,
@@ -925,9 +933,13 @@ export class MoveService implements OnModuleInit {
             traceId,
             actionType,
           );
-        }
-        else if (count == 1) {
-          console.log('joystick校验--->'+breakPointId+'-'+neighPoints[0].breakPointId);
+        } else if (count == 1) {
+          console.log(
+            'joystick校验--->' +
+              breakPointId +
+              '-' +
+              neighPoints[0].breakPointId,
+          );
           return await this.moveDirect(
             playerPosition,
             closestDis,
@@ -938,11 +950,9 @@ export class MoveService implements OnModuleInit {
             traceId,
             actionType,
           );
-        }
-        else if (count == 0) {
-          this.reply['newUserStates'][0].playerState.player.position = JSON.parse(
-            JSON.stringify(user.player.position),
-          );
+        } else if (count == 0) {
+          this.reply['newUserStates'][0].playerState.player.position =
+            JSON.parse(JSON.stringify(user.player.position));
           this.reply.actionResponses[0].actionType = actionType;
           return this.reply;
         }
@@ -966,7 +976,9 @@ export class MoveService implements OnModuleInit {
         } else {
           chooseBreakPointId = neighPoints[0].breakPointId;
         }
-        console.log('joystick镜头过渡--->'+breakPointId+'-'+chooseBreakPointId);
+        console.log(
+          'joystick镜头过渡--->' + breakPointId + '-' + chooseBreakPointId,
+        );
         return await this.moveCamera(
           breakPointId,
           chooseBreakPointId,
@@ -982,12 +994,13 @@ export class MoveService implements OnModuleInit {
         );
         this.reply.actionResponses[0].actionType = actionType;
         const cameraInfo = this.getCameraInfo();
-        if(cameraInfo != null){
+        if (cameraInfo != null) {
           console.log('joystick自由--->合并');
-          this.reply['newUserStates'][0].playerState.camera.position = cameraInfo.cameraPosition;
-          this.reply['newUserStates'][0].playerState.camera.angle = cameraInfo.cameraAngle;
-        }
-        else{
+          this.reply['newUserStates'][0].playerState.camera.position =
+            cameraInfo.cameraPosition;
+          this.reply['newUserStates'][0].playerState.camera.angle =
+            cameraInfo.cameraAngle;
+        } else {
           console.log('joystick自由--->不合并');
         }
         return this.reply;
@@ -1015,10 +1028,10 @@ export class MoveService implements OnModuleInit {
     let player_Position = this.getTarget(
       playerPosition,
       breakPoint.position,
-      this.breakPointInfo[neighBreakPointId].position
+      this.breakPointInfo[neighBreakPointId].position,
     );
 
-    if(player_Position != null){
+    if (player_Position != null) {
       playerPosition.x = player_Position.x;
       playerPosition.y = player_Position.y;
       user.player.position = JSON.parse(JSON.stringify(playerPosition));
@@ -1039,9 +1052,11 @@ export class MoveService implements OnModuleInit {
       );
       this.reply.actionResponses[0].actionType = actionType;
       const cameraInfo = this.getCameraInfo();
-      if(cameraInfo != null){
-        this.reply['newUserStates'][0].playerState.camera.position = cameraInfo.camera_position;
-        this.reply['newUserStates'][0].playerState.camera.angle = cameraInfo.camera_angle;
+      if (cameraInfo != null) {
+        this.reply['newUserStates'][0].playerState.camera.position =
+          cameraInfo.camera_position;
+        this.reply['newUserStates'][0].playerState.camera.angle =
+          cameraInfo.camera_angle;
       }
       return this.reply;
     }
@@ -1084,9 +1099,13 @@ export class MoveService implements OnModuleInit {
 
       for (let i = 0; i < checkReplys.length; ++i) {
         //checkReplys[i].actionResponses[0].actionType = actionType;
-        this.addCameraInfo(checkReplys[i]['newUserStates'][0].playerState.camera.position,checkReplys[i]['newUserStates'][0].playerState.camera.angle,checkReplys[i].mediaSrc);
+        this.addCameraInfo(
+          checkReplys[i]['newUserStates'][0].playerState.camera.position,
+          checkReplys[i]['newUserStates'][0].playerState.camera.angle,
+          checkReplys[i].mediaSrc,
+        );
       }
-      
+
       //replys.push(checkReplys);
       //读redis里的数据,按照frame_index的大小排序
       const key =
@@ -1116,32 +1135,35 @@ export class MoveService implements OnModuleInit {
       // replys.push(pathReplys);
       user.breakPointId = chooseBreakPointId;
       const cameraInfo = this.getCameraInfo();
-      if(cameraInfo != null){
-        this.reply['newUserStates'][0].playerState.camera.position = cameraInfo.camera_position;
-        this.reply['newUserStates'][0].playerState.camera.angle = cameraInfo.camera_angle;
+      if (cameraInfo != null) {
+        this.reply['newUserStates'][0].playerState.camera.position =
+          cameraInfo.camera_position;
+        this.reply['newUserStates'][0].playerState.camera.angle =
+          cameraInfo.camera_angle;
 
         user.camera.position = JSON.parse(
           JSON.stringify(cameraInfo.camera_position),
         );
         user.camera.angle.yaw = cameraInfo.camera_angle.yaw;
 
-        if(cameraInfo.mediaSrc){
+        if (cameraInfo.mediaSrc) {
           this.reply.mediaSrc = cameraInfo.mediaSrc;
-        }
-        else if(cameraInfo.file_name){
+        } else if (cameraInfo.file_name) {
           this.reply.mediaSrc =
-          '/' +
-          appId +
-          '/' +
-          breakPointId +
-          '/' +
-          cameraInfo.file_name.substring(0, cameraInfo.file_name.indexOf('.')) +
-          '/' +
-          cameraInfo.file_name +
-          '?m=' +
-          new Date().getTime();
-        }
-        else{
+            '/' +
+            appId +
+            '/' +
+            breakPointId +
+            '/' +
+            cameraInfo.file_name.substring(
+              0,
+              cameraInfo.file_name.indexOf('.'),
+            ) +
+            '/' +
+            cameraInfo.file_name +
+            '?m=' +
+            new Date().getTime();
+        } else {
           debugger;
         }
       }
@@ -1154,24 +1176,23 @@ export class MoveService implements OnModuleInit {
     }
   }
 
-  setCameraInfo(moveFrames){
-    this.cameraInfos = moveFrames
+  setCameraInfo(moveFrames) {
+    this.cameraInfos = moveFrames;
   }
 
-  addCameraInfo(cameraPosition,cameraAngle,mediaSrc){
+  addCameraInfo(cameraPosition, cameraAngle, mediaSrc) {
     this.cameraInfos.push({
-      camera_position:cameraPosition,
-      camera_angle:cameraAngle,
-      mediaSrc:mediaSrc
-    })
+      camera_position: cameraPosition,
+      camera_angle: cameraAngle,
+      mediaSrc: mediaSrc,
+    });
   }
 
-  getCameraInfo(){
-    if(this.cameraInfos.length>0){
+  getCameraInfo() {
+    if (this.cameraInfos.length > 0) {
       const item = this.cameraInfos.shift();
       return item;
-    }
-    else{
+    } else {
       return null;
     }
   }
@@ -1406,25 +1427,30 @@ export class MoveService implements OnModuleInit {
     return parseFloat(num.toFixed(decimal));
   }
 
-  isPointInPoly(position,breakPointIds){
+  isPointInPoly(position, breakPointIds) {
     const x = position.x;
     const y = position.y;
 
     let inside = false;
 
-    for(let i=0,j=breakPointIds.length-1;i<breakPointIds.length;j=i++){
-      let pt1 = this.breakPointInfo[breakPointIds[i]]
-      let pt2 = this.breakPointInfo[breakPointIds[j]]
+    for (
+      let i = 0, j = breakPointIds.length - 1;
+      i < breakPointIds.length;
+      j = i++
+    ) {
+      const pt1 = this.breakPointInfo[breakPointIds[i]];
+      const pt2 = this.breakPointInfo[breakPointIds[j]];
 
-      const xi = pt1.x
-      const yi = pt1.y
-      const xj = pt2.x
-      const yj = pt2.y
+      const xi = pt1.x;
+      const yi = pt1.y;
+      const xj = pt2.x;
+      const yj = pt2.y;
 
-      const intersect = yi > y != yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi
-      if (intersect) inside = !inside
+      const intersect =
+        yi > y != yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi;
+      if (intersect) inside = !inside;
     }
 
-    return inside
+    return inside;
   }
 }

+ 89 - 0
src/queue/delay-queue/delay-queue copy.ts

@@ -0,0 +1,89 @@
+import {
+  concat,
+  empty,
+  of,
+  Subject,
+  Subscription,
+  timer,
+  EMPTY,
+  BehaviorSubject,
+} from 'rxjs';
+import {
+  concatMap,
+  ignoreElements,
+  startWith,
+  switchMap,
+} from 'rxjs/operators';
+
+import RxQueue from '../rx-queue';
+
+/**
+ * DelayQueue passes all the items and add delays between items.
+ * T: item type
+ */
+export class DelayQueue<T = unknown> extends RxQueue<T> {
+  private subscription: Subscription;
+  public subject: Subject<T>;
+
+  /**
+   *
+   * @param period milliseconds
+   */
+  constructor(
+    period?: number, // milliseconds
+  ) {
+    super(period);
+    this.subject = new Subject<T>();
+    this.initQueue();
+  }
+
+  initQueue(): void {
+    this.subscription = this.subject
+      .pipe(
+        concatMap((x) =>
+          concat(
+            of(x), // emit first item right away
+            /**
+             * Issue #71 - DelayQueue failed: behavior breaking change after RxJS from v6 to v7
+             *  https://github.com/huan/rx-queue/issues/71
+             */
+            timer(this.period).pipe(ignoreElements()),
+          ),
+        ),
+      )
+      .subscribe((item: T) => super.next(item));
+  }
+
+  override next(item: T) {
+    this.subject.next(item);
+  }
+
+  override unsubscribe() {
+    this.subscription.unsubscribe();
+    super.unsubscribe();
+  }
+
+  override clean(): void {
+    this.subscription.unsubscribe();
+    this.subject
+      .asObservable()
+      .pipe(switchMap(() => EMPTY))
+      .pipe(ignoreElements());
+    // .subscribe((item: T) => super.next(item));
+
+    this.initQueue();
+    // this.unsubscribe();
+    // this.subject.complete();
+    // this.initQueue();
+    // 2
+    // this.subject.pipe(switchMap(() => EMPTY));
+    // this.subject.pipe(startWith(true), ignoreElements());
+
+    // this.subscription = this.subject
+    //   .pipe(switchMap(() => EMPTY))
+    //   .subscribe((item: T) => super.next(item));
+    console.log('clean-DelayQueue-1', this.subject);
+  }
+}
+
+export default DelayQueue;

+ 21 - 14
src/queue/delay-queue/delay-queue.ts

@@ -1,4 +1,13 @@
-import { concat, empty, of, Subject, Subscription, timer, EMPTY } from 'rxjs';
+import {
+  concat,
+  empty,
+  of,
+  Subject,
+  Subscription,
+  timer,
+  EMPTY,
+  BehaviorSubject,
+} from 'rxjs';
 import {
   concatMap,
   ignoreElements,
@@ -29,6 +38,9 @@ export class DelayQueue<T = unknown> extends RxQueue<T> {
   }
 
   initQueue(): void {
+    if (!this.subject) {
+      this.subject = new Subject<T>();
+    }
     this.subscription = this.subject
       .pipe(
         concatMap((x) =>
@@ -55,23 +67,18 @@ export class DelayQueue<T = unknown> extends RxQueue<T> {
   }
 
   override clean(): void {
-    // 1
     this.subscription.unsubscribe();
-    this.subject.pipe(ignoreElements());
+    this.subject.complete();
+    this.subscription = null;
+    this.subject = null;
+    // this.subject
+    //   .asObservable()
+    //   .pipe(switchMap(() => EMPTY))
+    //   .pipe(ignoreElements());
     // .subscribe((item: T) => super.next(item));
 
     this.initQueue();
-    // this.unsubscribe();
-    // this.subject.complete();
-    // this.initQueue();
-    // 2
-    // this.subject.pipe(switchMap(() => EMPTY));
-    // this.subject.pipe(startWith(true), ignoreElements());
-
-    // this.subscription = this.subject
-    //   .pipe(switchMap(() => EMPTY))
-    //   .subscribe((item: T) => super.next(item));
-    console.log('clean-DelayQueue-1', this.subject);
+    console.log('clean-DelayQueue');
   }
 }
 

+ 3 - 3
src/rotate/rotate.service.ts

@@ -398,9 +398,9 @@ export class RotateService {
           playerState: {
             roomTypeId: '',
             person: 0,
-            avatarId: 'KGe_Boy',
-            skinId: '10089',
-            roomId: 'e629ef3e-022d-4e64-8654-703bb96410eb',
+            avatarId: 'My_Actor',
+            skinId: '0000000001',
+            roomId: 'aea5406a-3099-48db-b428-30917872e58a',
             isHost: false,
             isFollowHost: false,
             skinDataVersion: '1008900008',

+ 177 - 119
src/scene/scene.service.ts

@@ -2,7 +2,7 @@ import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
 import { ClientGrpc, Client } from '@nestjs/microservices';
 import { grpcClientOptions } from './grpc-scene.options';
 import { Logger } from '@nestjs/common';
-import { DataChannel } from 'node-datachannel';
+import { DataChannel, PeerConnection } from 'node-datachannel';
 import { BehaviorSubject } from 'rxjs';
 // import * as streamBuffers from 'stream-buffers';
 import { ActionType } from './actionType';
@@ -16,7 +16,6 @@ import { DelayQueue, RxQueue, DebounceQueue } from '../queue/mod';
 import { MoveService } from 'src/move/move.service';
 import { GetRouterService } from 'src/get-router/get-router.service';
 import { ConfigService } from '@nestjs/config';
-import { join } from 'path';
 
 @Injectable()
 export class SceneService implements OnModuleInit, OnModuleDestroy {
@@ -27,7 +26,7 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
     private rotateService: RotateService,
     private moveService: MoveService,
     private getRouterService: GetRouterService, // @InjectQueue('rotate') private rotateQueue: Queue, // @InjectQueue('walking') private walkingQueue: Queue,
-  ) {}
+  ) { }
   @Client(grpcClientOptions) private readonly client: ClientGrpc;
 
   public _frameInteval: NodeJS.Timeout;
@@ -44,9 +43,11 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
   private moveframeCnt = -1;
   private joystickFrameCnt = -1;
   private rotateFirstIDR = true;
+  private rotateStopThrottle = false; //防止多次瞬间解触发
 
   private sceneGrpcService: SceneGrpcService;
   private channel: DataChannel;
+  private peer: PeerConnection;
   private logger: Logger = new Logger('SceneService');
   private frameCntInterval = 1000;
   private user_id: string;
@@ -96,6 +97,12 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
     clipPath: '',
     metaData: '',
   });
+  public lastMoveStreamFrameBk: StreamFrameType = {
+    frame: -1,
+    clipPath: '',
+    metaData: '',
+  };
+
   public users = {};
 
   // initUsers(app_id, userId) {
@@ -225,33 +232,8 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
   init(request: InitRequest) {
     try {
       this.rotateService.init(request.app_id, request.user_id);
+      this.cacheService.getClient();
       // 加载
-      // let path: string;
-      // if (process.env.NODE_ENV === 'development') {
-      //   path = join(
-      //     __dirname,
-      //     `../ws/${request.app_id}/points-${request.app_id}.json`,
-      //   );
-      //   console.log('测试服JSON', path);
-      // }
-      // if (process.env.NODE_ENV === 'production') {
-      //   path = join(
-      //     `${this.configService.get('app.prefix')}/${request.app_id}/points-${
-      //       request.app_id
-      //     }.json`,
-      //   );
-      //   console.log('正式服JSON', path);
-      // }
-
-      // this.moveService.loadJSON(path);
-      // this.getRouterService.loadJSON(path);
-      this.startSteaming.next(true);
-      this.startStream();
-      this.handleStream();
-
-      // this.moveService.init(request.app_id, request.user_id);
-
-      // this.initUsers(request.app_id, request.user_id);
     } catch (error) {
       this.logger.error('error', error);
     }
@@ -276,8 +258,6 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
    */
 
   async handleRotate(request) {
-    // this.roRequestQueueSub = this.roRequestQueue.subscribe(
-    //   async (request: RotateRequest) => {
     // try {
     if (this.firstRender) {
       if (!this.roQueueSubscription) {
@@ -286,9 +266,20 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
       let redisMeta: StreamReplyType;
       this.onRotating.next(true);
       const start = performance.now();
-      // 当move时处理 _rotateCount是移动端同时触发的问题
-      if (this.onMoving.value && this._rotateCount > 5) {
+      // 当move时处理 _rotateCount是移动端同时触发的问题,rotateStopThrottle是减少重复抖动stop的处理。
+      if (
+        this.onMoving.getValue() &&
+        this._rotateCount > 5 &&
+        !this.rotateStopThrottle
+      ) {
+        this.rotateStopThrottle = true;
         const lastStreamFrame = this.lastMoveStreamFrame.getValue();
+        this.logger.log('lastStreamFrame', JSON.stringify(lastStreamFrame));
+        // this.logger.log(
+        //   'lastMoveStreamFrameBk',
+        //   JSON.stringify(lastMoveStreamFrameBk),
+        // );
+
         const metaData: StreamReplyType = JSON.parse(
           lastStreamFrame.metaData,
         ) as any as StreamReplyType;
@@ -300,21 +291,29 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
         if (metaData.traceIds.indexOf(request.trace_id) > -1) {
           return;
         }
-
+        console.log('currentUser-user_id', this.user_id);
         const newUserStates: NewUserStatesType = metaData.newUserStates.find(
           (item) => item.userId === this.user_id,
         );
+
         const trace_id = metaData.traceIds[0];
         const userId = newUserStates.userId;
-        const breakPointId = metaData.endBreakPointId;
+        //TODO 临时,可能数据会不对
+        const breakPointId = metaData.endBreakPointId || metaData.breakPointId;
         const cameraAngle = newUserStates.playerState.camera.angle;
         const playerAngle = newUserStates.playerState.player.angle;
         this.logger.log(
-          'stop-data-0',
-          trace_id,
-          userId,
-          cameraAngle,
-          cameraAngle,
+          'stop-data-0' +
+          'trace_id: ' +
+          trace_id +
+          'userId:' +
+          userId +
+          'breakPointId :' +
+          breakPointId +
+          'cameraAngle :' +
+          JSON.stringify(cameraAngle) +
+          'playerAngle: ' +
+          JSON.stringify(playerAngle),
         );
         //debugger;
         console.log('moveService.stop-1:'+breakPointId)
@@ -361,7 +360,11 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
             const stop = performance.now();
             const inMillSeconds = stop - start;
             const rounded = Number(inMillSeconds).toFixed(3);
-            this.logger.log(`[timer]-rotate-入队列前: ${rounded}ms`);
+            this.logger.log(
+              `[timer]-rotate-入队列前: ${rounded}ms -->` +
+              JSON.stringify(stream),
+            );
+
             this.roQueue.next(stream);
           } else {
             // this.onRotating.next(false);
@@ -385,7 +388,7 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
       this.handleWalking(request);
     }
 
-    console.log('moveSliceLastFrameSub', this.moveSliceLastFrameSub);
+    console.log('moveSliceLastFrameSub', !!this.moveSliceLastFrameSub);
 
     // 监听每小段最后一帧
     if (!this.moveSliceLastFrameSub) {
@@ -395,9 +398,9 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
           //TODO 正在行走时,有新的reqest
           if (this.latestWalkingRequest && this.onMoving.value) {
             this.logger.log('stop-data-1', frame);
+            this.moveQueueSubscription.unsubscribe();
+            this.moveQueueSubscription = null;
             this.moveQueue.clean();
-            // this.moveQueueSubscription.unsubscribe();
-            // this.moveQueueSubscription = null;
             //step1 执行stop方法
             const metaData: StreamReplyType = frame.metaData;
             const newUserStates: NewUserStatesType =
@@ -430,6 +433,14 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
               'walking-step-reWalking-1',
               request.trace_id + ',' + this.latestWalkingRequest.trace_id,
             );
+            // 中断清除上一次最后小段队列
+            if (this.moveSliceLastFrameSub) {
+              this.moveSliceLastFrameSub.unsubscribe();
+              this.moveSliceLastFrameSub = null;
+            }
+
+            this.logger.debug('重新行走---handleReWalking');
+            console.log('重新行走---handleReWalking');
             this.handleReWalking(this.latestWalkingRequest);
           }
         },
@@ -451,7 +462,20 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
       this._rotateCount = 0;
       const user = this.moveService.users[this.user_id];
       console.log('进入1 - searchRoad');
+      this.logger.log(
+        'handleWalking-users' +
+        JSON.stringify(this.moveService.users) +
+        ' this.user_id: ' +
+        this.user_id,
+      );
+      this.logger.log(
+        'handleWalking-currentUser' +
+        JSON.stringify(user) +
+        ' this.user_id: ' +
+        this.user_id,
+      );
       console.log('path-start' + user.breakPointId);
+
       const path = await this.getRouterService.searchRoad(
         user.appId,
         user.breakPointId,
@@ -516,7 +540,17 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
         const seqs = Array.from(walkingRes).flat() as any as StreamReplyType[];
 
         if (seqs?.length) {
-          this.logger.log('walking --总序列--seqs-2:' + seqs.length);
+          this.logger.log(
+            'walking --队列总览:' +
+            ' 总段数: ' +
+            walkingRes.length +
+            ' 镜头帧数:' +
+            walkingRes[0].length +
+            ' 行走段数:' +
+            (walkingRes.length - 1) +
+            ' 队列总帧数:' +
+            seqs.length,
+          );
           const stop = performance.now();
           const inMillSeconds = stop - start;
           const rounded = Number(inMillSeconds).toFixed(3);
@@ -571,7 +605,7 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
       const joystickRes = await this.moveService.seqExeJoystick(request);
       this.logger.log(
         'joystick-breakPointId:' +
-          this.moveService.users[this.user_id].breakPointId,
+        this.moveService.users[this.user_id].breakPointId,
       );
       // 有数据 [0]是rotate数据,[1-infinity]是walking数据
       this.logger.log('joystickRes-1', joystickRes);
@@ -674,11 +708,12 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
     if (!this.moveQueueSubscription) {
       this.handleMoveSteam();
     }
-    this.logger.log('moving-seqs', seqs.length);
+    // this.logger.log('moving-seqs', seqs.length);
     this.onMoving.next(true);
     this.holdSteam();
     //TODO Remove
     // clearTimeout(this._JoyStickingTimeout);
+    this.moveQueue.clean();
 
     seqs.forEach((frame: StreamReplyType) => {
       const mediaSrc = frame.mediaSrc;
@@ -716,27 +751,28 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
     //   this.clickQueueSub.unsubscribe();
     //   this.clickQueueSub = null;
     // }
+    this.rotateStopThrottle = false;
   }
   handleMoveSteam() {
     this.moveQueueSubscription = this.moveQueue.subscribe(
       async (stream: StreamFrameType) => {
-        const metaData: StreamReplyType = JSON.parse(stream.metaData);
-
-        if (this.moveframeCnt === -1) {
-          this.moveframeCnt = this.frameCnt.getValue();
-        }
-        this.moveframeCnt += 1;
-        this.latestBreakPointId = metaData.endBreakPointId;
-
-        const streamData: StreamFrameType = {
-          frame: this.moveframeCnt,
-          clipPath: stream.clipPath,
-          metaData: stream.metaData,
-          serverTime: this.mockserverTime,
-          DIR: stream.DIR,
-        };
-        this.logger.log(
-          '[media-move]: ' +
+        try {
+          const metaData: StreamReplyType = JSON.parse(stream.metaData);
+          if (this.moveframeCnt === -1) {
+            this.moveframeCnt = this.frameCnt.getValue();
+          }
+          this.moveframeCnt += 1;
+          this.latestBreakPointId = metaData.endBreakPointId;
+
+          const streamData: StreamFrameType = {
+            frame: this.moveframeCnt,
+            clipPath: stream.clipPath,
+            metaData: stream.metaData,
+            serverTime: this.mockserverTime,
+            DIR: stream.DIR,
+          };
+          this.logger.log(
+            '[media-move]: ' +
             ', moveframeCnt: ' +
             this.moveframeCnt +
             ', clipPath: ' +
@@ -745,56 +781,69 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
             stream.mType +
             ', DIR: ' +
             stream.DIR,
-          // stream.metaData,
-        );
-        this.logger.log(
-          '[media-move-lastMovingPointArray]',
-          this.lastMovingPointArray?.length,
-        );
-        this.lastMoveStreamFrame.next(streamData);
-        const res = await this.streamService.pushFrameToSteam(streamData);
+            // stream.metaData,
+          );
+          this.logger.log(
+            '[media-move-lastMovingPointArray]',
+            this.lastMovingPointArray?.length,
+          );
+          // 记录lastMoveStreamFrame给打断逻辑使用
+          this.lastMoveStreamFrame.next(streamData);
+          // this.lastMoveStreamFrameBk = streamData;
+          const res = await this.streamService.pushFrameToSteam(streamData);
 
-        const isLastFrameIndex = this.lastMovingPointArray.findIndex(
-          (item) => item.mediaSrc === metaData.mediaSrc,
-        );
-        //this.logger.log('path-update-index', isLastFrameIndex);
-        //每一段的最后一帧
-        if (isLastFrameIndex > -1) {
-          //this.logger.log('path-update-array', this.lastMovingPointArray);
-          const currentMeta = this.lastMovingPointArray[isLastFrameIndex];
-          const userId = this.user_id;
-          const breakPointId = currentMeta.metaData.endBreakPointId;
-          const lastReply = currentMeta.metaData;
-          this.moveService.updateUser(userId, breakPointId, lastReply);
-          //debugger
-          this.lastMovingPointArray.splice(isLastFrameIndex, 1);
-          //TODO 队列每一段最后one frame
-          this.moveSliceLastFrame.next(currentMeta);
-        }
+          const isLastFrameIndex = this.lastMovingPointArray.findIndex(
+            (item) => item.mediaSrc === metaData.mediaSrc,
+          );
+          //this.logger.log('path-update-index', isLastFrameIndex);
+          //每一段的最后一帧
+          if (isLastFrameIndex > -1) {
+            //this.logger.log('path-update-array', this.lastMovingPointArray);
+            const currentMeta = this.lastMovingPointArray[isLastFrameIndex];
+            const userId = this.user_id;
+            const breakPointId = currentMeta.metaData.endBreakPointId;
+            const lastReply = currentMeta.metaData;
+            this.moveService.updateUser(userId, breakPointId, lastReply);
+            //debugger
+            this.lastMovingPointArray.splice(isLastFrameIndex, 1);
+            //TODO 队列每一段最后one frame
+            this.moveSliceLastFrame.next(currentMeta);
+          }
 
-        if (res.done) {
-          clearTimeout(this._moveTimeout);
-          this._moveTimeout = setTimeout(() => {
-            this.logger.log('move 交权给空流,当前pts', res.frame);
-            this.rewalking = false;
-            this.frameCnt.next(res.frame);
-            this.resumeStream();
-            this.rotateframeCnt = -1;
-            this.onMoving.next(false);
-            this.onJoysticking.next(false);
-            this.cleanMoveSteam();
-            this.lastMovingPointArray = [];
-            this.hasJoystickMoveRequest = false;
-            this.logger.log('move end');
-          }, 300);
+          if (res.done) {
+            clearTimeout(this._moveTimeout);
+            this._moveTimeout = setTimeout(() => {
+              this.logger.log('move 交权给空流,当前pts', res.frame);
+              this.rewalking = false;
+              this.frameCnt.next(res.frame);
+              this.resumeStream();
+              this.rotateframeCnt = -1;
+              this.onMoving.next(false);
+              this.onJoysticking.next(false);
+              this.cleanMoveSteam();
+              this.lastMovingPointArray = [];
+              this.hasJoystickMoveRequest = false;
+              this.logger.log('move end');
+            }, 200);
+          } else {
+            this.logger.error(
+              `movesteam::当前帧:${res.frame}` + JSON.stringify(res),
+            );
+          }
+        } catch (error) {
+          this.logger.error('handleMoveSteam::error', error);
         }
       },
     );
   }
 
-  handleDataChanelOpen(channel: DataChannel): void {
+  handleDataChanelOpen(channel: DataChannel, peer: PeerConnection): void {
     this.channel = channel;
+    this.peer = peer;
     this.streamService.setChannel(channel);
+    this.startSteaming.next(true);
+    this.startStream();
+    this.handleStream();
   }
 
   handleDataChanelClose(): void {
@@ -925,8 +974,7 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
 
           const IDRflag = this._rotateCurrentFame % 5 === 0 ? 1 : 3;
           this.logger.log(
-            `当前rotate ,mainframeCnt:${this.frameCnt.getValue()}, _rotateCurrentFame:${
-              this._rotateCurrentFame
+            `当前rotate ,mainframeCnt:${this.frameCnt.getValue()}, _rotateCurrentFame:${this._rotateCurrentFame
             } IDRflag:${IDRflag}`,
           );
           stream.DIR = this.rotateFirstIDR ? 1 : IDRflag;
@@ -937,12 +985,12 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
 
           this.logger.log(
             '[media-rotate]: ' +
-              ', frame: ' +
-              stream.frame +
-              ', rotateframeCnt: ' +
-              this.rotateframeCnt +
-              ', clipPath: ' +
-              stream.clipPath,
+            ', frame: ' +
+            stream.frame +
+            ', rotateframeCnt: ' +
+            this.rotateframeCnt +
+            ', clipPath: ' +
+            stream.clipPath,
             // stream.metaData,
           );
           // this.logger.log(
@@ -993,12 +1041,22 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
   }
   handleStream() {
     this.logger.log('this.frameCntSubscription', this.frameCntSubscription);
+    let redisData;
     if (!this.frameCntSubscription) {
       this.frameCntSubscription = this.frameCnt.subscribe(async (frame) => {
         try {
           this.logger.log('frame', frame);
+          console.log(
+            'mock' +
+            ' maxMessageSize: ' +
+            this.channel.maxMessageSize() +
+            ' bytesReceived: ' +
+            this.peer.bytesReceived() +
+            ' bytesSent: ' +
+            this.peer.bytesSent(),
+          );
           if (frame === 1) {
-            const redisData = await this.rotateService.echo(this.user_id, true);
+            redisData = await this.rotateService.echo(this.user_id, true);
             this.logger.log('获取-首屏', redisData);
             this.onSteaming = true;
             this.holdSteam();
@@ -1006,14 +1064,11 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
               const mediaSrc: string = redisData.mediaSrc || '';
               if (mediaSrc.length > 0) {
                 const src = mediaSrc.split('?')[0];
-                // 临时本地替换路经
-                // src = src.replace('/10086/', '');
-                // const clipPath = join(__dirname, `../ws/${src}`);
                 const clipPath = this.configService.get('app.prefix') + src;
                 delete redisData.mediaSrc;
                 this.logger.log(
                   `user:${this.user_id}:first render stream` +
-                    JSON.stringify({ path: clipPath, meta: redisData }),
+                  JSON.stringify({ path: clipPath, meta: redisData }),
                 );
                 const status = await this.pushFirstRender(
                   clipPath,
@@ -1028,7 +1083,7 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
                 }
               }
             } else {
-              this.logger.error(`首屏::无数据:${frame}`);
+              this.logger.error(`first render problem:${frame}`);
             }
           }
           if (
@@ -1057,6 +1112,9 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
             }
           }
         } catch (error) {
+          if (this.frameCnt.getValue() === 1) {
+            this.logger.error('首屏读取redis有误:', redisData, error.message);
+          }
           this.stopStream();
           this.logger.error('handleStream', error.message);
         }

+ 1 - 0
src/scene/stream/stream.d.ts

@@ -77,6 +77,7 @@ interface StreamReplyType {
   // breakPointId?: number;
   startBreakPointId?: number;
   endBreakPointId?: number;
+  breakPointId?: number; //临时记录存在的点()
   mType?: string; //类型
   DIR: ?number;
 }

+ 12 - 2
src/scene/stream/stream.service.ts

@@ -1,7 +1,7 @@
 import { Injectable, Logger } from '@nestjs/common';
 import { DataChannel } from 'node-datachannel';
 // import * as path from 'path';
-import { readFileSync } from 'fs';
+import { existsSync, readFileSync } from 'fs';
 import * as streamBuffers from 'stream-buffers';
 import { BehaviorSubject } from 'rxjs';
 import { CacheService } from 'src/cache/cache.service';
@@ -19,7 +19,7 @@ export class StreamService {
     clipPath: '',
     metaData: '',
   });
-  constructor(private cacheService: CacheService) {}
+  // constructor() {}
 
   setChannel(channel: DataChannel) {
     this.channel = channel;
@@ -132,8 +132,14 @@ export class StreamService {
         // console.warn('coordBuff', coordBuff.byteLength);
         // const steamStat = statSync(clipPath);
         // const steamTotalSize = metaData.length + steamStat.size;
+        // 增加不存在帧数据中断数据,原因有太多不准确的路径。
+        if (!existsSync(clipPath)) {
+          this.logger.error('不存在的推流路径::' + clipPath);
+          return;
+        }
 
         const clipBuffer = readFileSync(clipPath);
+
         const steam = new streamBuffers.ReadableStreamBuffer({
           frequency: 1, // in milliseconds.
           chunkSize: this.chunk_size - this.block, // in bytes.
@@ -206,6 +212,10 @@ export class StreamService {
           }
           return resolve({ frame: stream.frame, done: true });
         });
+        steam.on('error', (error) => {
+          this.logger.error('steam-error', error.message);
+          return reject({ frame: stream.frame, done: false });
+        });
       } catch (error) {
         this.logger.error(error);
         return reject({ frame: stream.frame, done: false });

+ 4 - 4
yarn.lock

@@ -4456,10 +4456,10 @@ node-abi@^3.3.0:
   dependencies:
     semver "^7.3.5"
 
-node-datachannel@^0.3.2:
-  version "0.3.2"
-  resolved "https://registry.npmmirror.com/node-datachannel/-/node-datachannel-0.3.2.tgz"
-  integrity sha512-txUzjbqPDtjbxbgnO7PSwqv7KsmUcjIGZBF8zfG+B8oVcZFEPmBfyB4Sf9DBD2SCqGZ+TeZxeS2hmb0M1NUbHA==
+node-datachannel@^0.3.4:
+  version "0.3.4"
+  resolved "https://registry.yarnpkg.com/node-datachannel/-/node-datachannel-0.3.4.tgz#526fd245c3fdf9bcdcabb0c78ede3aa89531d67a"
+  integrity sha512-iIEUQNVmJ+N3KTpOoe3I+hhdl8lwdPjIT9019tipJ3YP6R0/rDlqh7yLtI5547aomANXV86XUUun/spv4FuHQQ==
   dependencies:
     prebuild-install "^7.0.1"