Browse Source

intergrade configurations modules

enzo 3 days ago
parent
commit
1e2dddc7cc

+ 18 - 8
apps/fis-fingerprint/src/fis-fingerprint.module.ts

@@ -2,18 +2,28 @@ import { Module } from '@nestjs/common';
 import { FisFingerprintController } from './fis-fingerprint.controller';
 import { FisFingerprintService } from './fis-fingerprint.service';
 import { ClientsModule, Transport } from '@nestjs/microservices';
-
+import { ConfigModule, ConfigService } from '@nestjs/config';
+import configuration from '../../../config/configurations';
+import 'dotenv/config'
 @Module({
   imports: [
-    ClientsModule.register([
+    ConfigModule.forRoot({
+      isGlobal: true,
+      load: [configuration]
+    }),
+    ClientsModule.registerAsync([
       {
         name: `SAMPLEAPP_SERVICE`,
-        transport: Transport.TCP,
-        options: {
-          host: `0.0.0.0`,
-          port: 3001
-        }
-      }
+        imports: [ConfigModule],
+        useFactory: async (configService: ConfigService) => ({
+          transport: Transport.TCP,
+          options: {
+            host: configService.get<string>(`sampleApp.host`) as string,
+            port: configService.get<number>(`sampleApp.tcpPort`) as number
+          }
+        }),
+        inject: [ConfigService]
+      },
     ])
   ],
   controllers: [FisFingerprintController],

+ 5 - 3
apps/fis-fingerprint/src/main.ts

@@ -1,7 +1,8 @@
 import { NestFactory } from '@nestjs/core';
-import { FisFingerprintModule } from './fis-fingerprint.module';
 import { MicroserviceOptions, Transport } from '@nestjs/microservices';
+import { ConfigService } from '@nestjs/config';
 import 'dotenv/config'
+import { FisFingerprintModule } from './fis-fingerprint.module';
 
 async function bootstrap() {
   const host: string = process.env.HOST as unknown as string
@@ -18,7 +19,8 @@ async function bootstrap() {
       },
     }
   );
-  await app.listen();
-  console.log(`Application is running on ${host}:${port}`);
+
+  await app.listen()
+  console.log(`Fingerprint microsservice is running on ${host}:${port}`);
 }
 bootstrap();

+ 21 - 11
apps/fis-verification/src/fis-verification.module.ts

@@ -2,21 +2,31 @@ import { Module } from '@nestjs/common';
 import { FisVerificationController } from './fis-verification.controller';
 import { FisVerificationService } from './fis-verification.service';
 import { ClientsModule, Transport } from '@nestjs/microservices';
-
+import configuration from '../../../config/configurations';
+import 'dotenv/config'
+import { ConfigModule, ConfigService } from '@nestjs/config';
 @Module({
   imports: [
-    ClientsModule.register([
-          {
-            name: `SAMPLEAPP_SERVICE`,
-            transport: Transport.TCP,
-            options: {
-              host: `0.0.0.0`,
-              port: 3001
-            }
+    ConfigModule.forRoot({
+      isGlobal: true,
+      load: [configuration]
+    }),
+    ClientsModule.registerAsync([
+      {
+        name: `SAMPLEAPP_SERVICE`,
+        imports: [ConfigModule],
+        useFactory: async (configService: ConfigService) => ({
+          transport: Transport.TCP,
+          options: {
+            host: configService.get<string>(`sampleApp.host`) as string,
+            port: configService.get<number>(`sampleApp.tcpPort`) as number
           }
-        ])
+        }),
+        inject: [ConfigService]
+      },
+    ])
   ],
   controllers: [FisVerificationController],
   providers: [FisVerificationService],
 })
-export class FisVerificationModule {}
+export class FisVerificationModule { }

+ 5 - 2
apps/fis-verification/src/main.ts

@@ -1,11 +1,13 @@
 import { NestFactory } from '@nestjs/core';
 import { FisVerificationModule } from './fis-verification.module';
 import { MicroserviceOptions, Transport } from '@nestjs/microservices';
+import { ConfigService } from '@nestjs/config';
 import 'dotenv/config'
 
 async function bootstrap() {
   const host: string = process.env.HOST as unknown as string
   const port: number = process.env.VERIFICATION_TCP_PORT as unknown as number
+
   const app = await NestFactory.createMicroservice<MicroserviceOptions>(
     FisVerificationModule,
     {
@@ -18,7 +20,8 @@ async function bootstrap() {
       },
     }
   );
-  await app.listen();
-  console.log(`Application is running on ${host}:${port}`);
+
+  await app.listen()
+  console.log(`Verification microsservice is running on ${host}:${port}`);
 }
 bootstrap();

+ 7 - 4
apps/sample-app/src/main.ts

@@ -1,15 +1,18 @@
 import { NestFactory } from '@nestjs/core';
 import { SampleAppModule } from './sample-app.module';
 import { MicroserviceOptions, Transport } from '@nestjs/microservices';
+import { ConfigService } from '@nestjs/config';
 import 'dotenv/config'
 
 async function bootstrap() {
   // This example contains a hybrid application (HTTP + TCP + Socket)
-  const host: string = process.env.HOST as unknown as string
-  const restPort: number = process.env.SAMPLEAPP_REST_PORT as unknown as number
-  const tcpPort: number = process.env.SAMPLEAPP_TCP_PORT as unknown as number
-
   const app = await NestFactory.create(SampleAppModule);
+  const config: ConfigService = app.get(ConfigService)
+
+  const host: string = config.get<string>(`sampleApp.host`) as string
+  const restPort: number = config.get<number>(`sampleApp.restPort`) as number
+  const tcpPort: number = config.get<number>(`sampleApp.tcpPort`) as number
+
   app.connectMicroservice<MicroserviceOptions>({
     transport: Transport.TCP,
     options: {

+ 43 - 9
apps/sample-app/src/sample-app.module.ts

@@ -2,21 +2,55 @@ import { Module } from '@nestjs/common';
 import { SampleAppController } from './sample-app.controller';
 import { SampleAppService } from './sample-app.service';
 import { ClientsModule, Transport } from '@nestjs/microservices';
-
+import { SampleEventsGateway } from './sample.gateway';
+import { ConfigModule, ConfigService } from '@nestjs/config';
+import configuration from '../../../config/configurations';
+import 'dotenv/config'
 @Module({
   imports: [
-    ClientsModule.register([
+    ConfigModule.forRoot({
+      isGlobal: true,
+      load: [configuration]
+    }),
+    ClientsModule.registerAsync([
       {
         name: `FINGERPRINT_SERVICE`,
-        transport: Transport.TCP,
-        options: {
-          host: `0.0.0.0`,
-          port: 3002
-        }
+        imports: [ConfigModule],
+        useFactory: async (configService: ConfigService) => ({
+          transport: Transport.TCP,
+          options: {
+            host: configService.get<string>(`fingerprint.host`) as string,
+            port: configService.get<number>(`fingerprint.tcpPort`) as number
+          }
+        }),
+        inject: [ConfigService]
+      },
+      {
+        name: `VERIFICATION_SERVICE`,
+        imports: [ConfigModule],
+        useFactory: async (configService: ConfigService) => ({
+          transport: Transport.TCP,
+          options: {
+            host: configService.get<string>(`verification.host`) as string,
+            port: configService.get<number>(`verification.tcpPort`) as number
+          }
+        }),
+        inject: [ConfigService]
       }
-    ])
+    ]),
+    /* Sync register version -- Use at your own risk.*/
+    // ClientsModule.register([
+    //   {
+    //     name: `FINGERPRINT_SERVICE`,
+    //     transport: Transport.TCP,
+    //     options: {
+    //       host: ConfigService.get<string>(`sampleApp.host`) as string,
+    //       port: process.env.FINGERPRINT_TCP_PORT as unknown as number
+    //     }
+    //   },
+    // ])
   ],
   controllers: [SampleAppController],
-  providers: [SampleAppService],
+  providers: [SampleAppService, SampleEventsGateway],
 })
 export class SampleAppModule { }

+ 7 - 3
apps/sample-app/src/sample-app.service.ts

@@ -4,7 +4,10 @@ import { ClientProxy } from '@nestjs/microservices';
 @Injectable()
 export class SampleAppService {
 
-  constructor(@Inject(`FINGERPRINT_SERVICE`) private client: ClientProxy) {
+  constructor(
+    @Inject(`FINGERPRINT_SERVICE`) private fingerprintClient: ClientProxy,
+    @Inject(`VERIFICATION_SERVICE`) private verificationClient: ClientProxy
+  ) {
     // logic here
   }
 
@@ -14,8 +17,9 @@ export class SampleAppService {
 
   // testing. Try to talk to Fingerprint App via microservice
   talkToFingerprint(message: string): any {
-    this.client.emit<string>(`eventTest`, message)
-    return this.client.send<string>({ cmd: `messageTest` }, message)
+    this.fingerprintClient.emit<string>(`eventTest`, message)
+    this.verificationClient.emit<string>(`eventTest`, message)
+    return this.fingerprintClient.send<string>({ cmd: `messageTest` }, message)
   }
 
 

+ 29 - 0
apps/sample-app/src/sample.gateway.ts

@@ -0,0 +1,29 @@
+import { ConnectedSocket, MessageBody, SubscribeMessage, WebSocketGateway, WebSocketServer, WsResponse, } from '@nestjs/websockets';
+import { from, Observable } from 'rxjs';
+import { map } from 'rxjs/operators';
+import { Server, Socket } from 'socket.io';
+
+@WebSocketGateway({
+    cors: {
+        origin: '*',
+    },
+    namespace: `Sample-App`
+})
+export class SampleEventsGateway {
+    @WebSocketServer()
+    server: Server;
+
+    constructor() {
+        // logic here
+    }
+
+    @SubscribeMessage('message')
+    handleMesage(@MessageBody() data: any, @ConnectedSocket() client: Socket): Observable<WsResponse<any>> {
+        throw new Error(`Method not implemented`)
+    }
+
+    @SubscribeMessage('test')
+    test(@MessageBody() data: string, @ConnectedSocket() client: Socket): void {
+        console.log(`${data} from ${client.id}`)
+    }
+}

+ 18 - 0
config/configurations.ts

@@ -0,0 +1,18 @@
+import { registerAs } from "@nestjs/config";
+import 'dotenv/config'
+
+export default () => ({
+    sampleApp: {
+        host: process.env.HOST,
+        restPort: process.env.SAMPLEAPP_REST_PORT,
+        tcpPort: process.env.SAMPLEAPP_TCP_PORT
+    },
+    fingerprint: {
+        host: process.env.HOST,
+        tcpPort: process.env.FINGERPRINT_TCP_PORT
+    },
+    verification: {
+        host: process.env.HOST,
+        tcpPort: process.env.VERIFICATION_TCP_PORT
+    }
+});

+ 331 - 2
package-lock.json

@@ -14,6 +14,8 @@
         "@nestjs/core": "^11.0.1",
         "@nestjs/microservices": "^11.0.12",
         "@nestjs/platform-express": "^11.0.1",
+        "@nestjs/platform-socket.io": "^11.0.12",
+        "@nestjs/websockets": "^11.0.12",
         "dotenv": "^16.4.7",
         "reflect-metadata": "^0.2.2",
         "rxjs": "^7.8.1",
@@ -2439,6 +2441,25 @@
         "@nestjs/core": "^11.0.0"
       }
     },
+    "node_modules/@nestjs/platform-socket.io": {
+      "version": "11.0.12",
+      "resolved": "https://registry.npmjs.org/@nestjs/platform-socket.io/-/platform-socket.io-11.0.12.tgz",
+      "integrity": "sha512-/irtuxzIHQqUTMazQpAHQXv/Dz2/hS0EhX+ZS4e4CfF8f6ly+pEqOrP3TNY2NjDkYs8T+ulXyuKgfJvT9p+U9w==",
+      "license": "MIT",
+      "dependencies": {
+        "socket.io": "4.8.1",
+        "tslib": "2.8.1"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/nest"
+      },
+      "peerDependencies": {
+        "@nestjs/common": "^11.0.0",
+        "@nestjs/websockets": "^11.0.0",
+        "rxjs": "^7.1.0"
+      }
+    },
     "node_modules/@nestjs/schematics": {
       "version": "11.0.2",
       "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-11.0.2.tgz",
@@ -2565,6 +2586,29 @@
         }
       }
     },
+    "node_modules/@nestjs/websockets": {
+      "version": "11.0.12",
+      "resolved": "https://registry.npmjs.org/@nestjs/websockets/-/websockets-11.0.12.tgz",
+      "integrity": "sha512-2DCHKMdNGdjgj1/H3Rd323HHsSogjM3sZMjrSpWJIACDQTLtHFdNiUgGk5OAHniDIgLatzXDrnikfv6zmhPb+w==",
+      "license": "MIT",
+      "dependencies": {
+        "iterare": "1.2.1",
+        "object-hash": "3.0.0",
+        "tslib": "2.8.1"
+      },
+      "peerDependencies": {
+        "@nestjs/common": "^11.0.0",
+        "@nestjs/core": "^11.0.0",
+        "@nestjs/platform-socket.io": "^11.0.0",
+        "reflect-metadata": "^0.1.12 || ^0.2.0",
+        "rxjs": "^7.1.0"
+      },
+      "peerDependenciesMeta": {
+        "@nestjs/platform-socket.io": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/@nodelib/fs.scandir": {
       "version": "2.1.5",
       "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -2679,6 +2723,12 @@
         "@sinonjs/commons": "^3.0.0"
       }
     },
+    "node_modules/@socket.io/component-emitter": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
+      "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==",
+      "license": "MIT"
+    },
     "node_modules/@swc/cli": {
       "version": "0.6.0",
       "resolved": "https://registry.npmjs.org/@swc/cli/-/cli-0.6.0.tgz",
@@ -3097,6 +3147,15 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/@types/cors": {
+      "version": "2.8.17",
+      "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz",
+      "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
     "node_modules/@types/eslint": {
       "version": "9.6.1",
       "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz",
@@ -3238,7 +3297,6 @@
       "version": "22.13.14",
       "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.14.tgz",
       "integrity": "sha512-Zs/Ollc1SJ8nKUAgc7ivOEdIBM8JAKgrqqUYi2J997JuKO7/tpQC+WCetQ1sypiKCQWHdvdg9wBNpUPEWZae7w==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "undici-types": "~6.20.0"
@@ -4316,6 +4374,15 @@
       ],
       "license": "MIT"
     },
+    "node_modules/base64id": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
+      "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
+      "license": "MIT",
+      "engines": {
+        "node": "^4.5.0 || >= 5.9"
+      }
+    },
     "node_modules/bin-version": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/bin-version/-/bin-version-6.0.0.tgz",
@@ -5397,6 +5464,104 @@
         "node": ">= 0.8"
       }
     },
+    "node_modules/engine.io": {
+      "version": "6.6.4",
+      "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.4.tgz",
+      "integrity": "sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/cors": "^2.8.12",
+        "@types/node": ">=10.0.0",
+        "accepts": "~1.3.4",
+        "base64id": "2.0.0",
+        "cookie": "~0.7.2",
+        "cors": "~2.8.5",
+        "debug": "~4.3.1",
+        "engine.io-parser": "~5.2.1",
+        "ws": "~8.17.1"
+      },
+      "engines": {
+        "node": ">=10.2.0"
+      }
+    },
+    "node_modules/engine.io-parser": {
+      "version": "5.2.3",
+      "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz",
+      "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "node_modules/engine.io/node_modules/accepts": {
+      "version": "1.3.8",
+      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+      "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+      "license": "MIT",
+      "dependencies": {
+        "mime-types": "~2.1.34",
+        "negotiator": "0.6.3"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/engine.io/node_modules/cookie": {
+      "version": "0.7.2",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
+      "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/engine.io/node_modules/debug": {
+      "version": "4.3.7",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+      "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+      "license": "MIT",
+      "dependencies": {
+        "ms": "^2.1.3"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/engine.io/node_modules/mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/engine.io/node_modules/mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "license": "MIT",
+      "dependencies": {
+        "mime-db": "1.52.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/engine.io/node_modules/negotiator": {
+      "version": "0.6.3",
+      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+      "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
     "node_modules/enhanced-resolve": {
       "version": "5.18.1",
       "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz",
@@ -8549,6 +8714,15 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/object-hash": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
+      "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 6"
+      }
+    },
     "node_modules/object-inspect": {
       "version": "1.13.4",
       "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
@@ -9741,6 +9915,141 @@
         "node": ">=8"
       }
     },
+    "node_modules/socket.io": {
+      "version": "4.8.1",
+      "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz",
+      "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==",
+      "license": "MIT",
+      "dependencies": {
+        "accepts": "~1.3.4",
+        "base64id": "~2.0.0",
+        "cors": "~2.8.5",
+        "debug": "~4.3.2",
+        "engine.io": "~6.6.0",
+        "socket.io-adapter": "~2.5.2",
+        "socket.io-parser": "~4.2.4"
+      },
+      "engines": {
+        "node": ">=10.2.0"
+      }
+    },
+    "node_modules/socket.io-adapter": {
+      "version": "2.5.5",
+      "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz",
+      "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==",
+      "license": "MIT",
+      "dependencies": {
+        "debug": "~4.3.4",
+        "ws": "~8.17.1"
+      }
+    },
+    "node_modules/socket.io-adapter/node_modules/debug": {
+      "version": "4.3.7",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+      "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+      "license": "MIT",
+      "dependencies": {
+        "ms": "^2.1.3"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/socket.io-parser": {
+      "version": "4.2.4",
+      "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
+      "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
+      "license": "MIT",
+      "dependencies": {
+        "@socket.io/component-emitter": "~3.1.0",
+        "debug": "~4.3.1"
+      },
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "node_modules/socket.io-parser/node_modules/debug": {
+      "version": "4.3.7",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+      "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+      "license": "MIT",
+      "dependencies": {
+        "ms": "^2.1.3"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/socket.io/node_modules/accepts": {
+      "version": "1.3.8",
+      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+      "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+      "license": "MIT",
+      "dependencies": {
+        "mime-types": "~2.1.34",
+        "negotiator": "0.6.3"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/socket.io/node_modules/debug": {
+      "version": "4.3.7",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+      "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+      "license": "MIT",
+      "dependencies": {
+        "ms": "^2.1.3"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/socket.io/node_modules/mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/socket.io/node_modules/mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "license": "MIT",
+      "dependencies": {
+        "mime-db": "1.52.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/socket.io/node_modules/negotiator": {
+      "version": "0.6.3",
+      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+      "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
     "node_modules/sort-keys": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
@@ -10812,7 +11121,6 @@
       "version": "6.20.0",
       "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
       "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/universalify": {
@@ -11303,6 +11611,27 @@
       "dev": true,
       "license": "ISC"
     },
+    "node_modules/ws": {
+      "version": "8.17.1",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
+      "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=10.0.0"
+      },
+      "peerDependencies": {
+        "bufferutil": "^4.0.1",
+        "utf-8-validate": ">=5.0.2"
+      },
+      "peerDependenciesMeta": {
+        "bufferutil": {
+          "optional": true
+        },
+        "utf-8-validate": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/xtend": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",

+ 2 - 0
package.json

@@ -25,6 +25,8 @@
     "@nestjs/core": "^11.0.1",
     "@nestjs/microservices": "^11.0.12",
     "@nestjs/platform-express": "^11.0.1",
+    "@nestjs/platform-socket.io": "^11.0.12",
+    "@nestjs/websockets": "^11.0.12",
     "dotenv": "^16.4.7",
     "reflect-metadata": "^0.2.2",
     "rxjs": "^7.8.1",

+ 4 - 1
startDev.bat

@@ -3,4 +3,7 @@
 cd /d "%~dp0"
 
 echo Starting services DEV MODE...
-start wt -M -d "." cmd /k "nest start sample-app --watch" ; split-pane -d "." cmd /k "nest start fis-fingerprint --watch" ; split-pane -d "." cmd /k "nest start fis-verification --watch"
+start wt -M -d "." cmd /k "nest start sample-app --watch" ; split-pane -d "." cmd /k "nest start fis-fingerprint --watch" ; split-pane -d "." cmd /k "nest start fis-verification --watch" 
+
+@REM to start with separate terminal windows
+@REM start wt -M -d "." cmd /k "nest start fis-verification --watch"