Explorar o código

udpate to send fingerprint data from C#

enzo hai 1 semana
pai
achega
ba926b7945

+ 5 - 0
apps/fis-fingerprint/src/fis-fingerprint.controller.ts

@@ -19,4 +19,9 @@ export class FisFingerprintController {
   eventTest(message: string): void {
     console.log(`Hello there. Just Responding to Event pattern`)
   }
+
+  @EventPattern(`message`)
+  handleMessage(message: any): void {
+    this.fisFingerprintService.verifyFingeprint(message)
+  }
 }

+ 12 - 0
apps/fis-fingerprint/src/fis-fingerprint.module.ts

@@ -24,6 +24,18 @@ import 'dotenv/config'
         }),
         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]
+      },
     ])
   ],
   controllers: [FisFingerprintController],

+ 12 - 3
apps/fis-fingerprint/src/fis-fingerprint.service.ts

@@ -1,14 +1,23 @@
-import { Inject, Injectable } from '@nestjs/common';
+import { Inject, Injectable, Logger } from '@nestjs/common';
 import { ClientProxy } from '@nestjs/microservices';
 
 @Injectable()
 export class FisFingerprintService {
+  private logger: Logger = new Logger(`FisFingerprintService`)
 
-  constructor(@Inject(`SAMPLEAPP_SERVICE`) private client: ClientProxy) {
+  constructor(
+    @Inject(`SAMPLEAPP_SERVICE`) private sampleAppClient: ClientProxy,
+    @Inject(`VERIFICATION_SERVICE`) private verificationClient: ClientProxy
+  ) {
     // logic here
     setTimeout(() => {
-      this.client.emit(`message`, `Fingeprint says HI`)
+      this.sampleAppClient.emit(`message`, `Fingeprint says HI`)
     }, 5000)
   }
 
+  verifyFingeprint(message: any): any {
+    this.logger.log(`Sending message to verification microservice`)
+    this.verificationClient.emit(`message`, message)
+  }
+
 }  

+ 5 - 0
apps/fis-verification/src/fis-verification.controller.ts

@@ -17,5 +17,10 @@ export class FisVerificationController {
     console.log(`Hello there. Just Responding to Event pattern.`)
   }
 
+  @EventPattern(`message`)
+  handleMessage(message: any): void {
+    this.fisVerificationService.handleMessage(message)
+  }
+
 }
 

+ 35 - 64
apps/fis-verification/src/fis-verification.service.ts

@@ -1,83 +1,49 @@
 import { Inject, Injectable } from '@nestjs/common';
 import { ClientProxy } from '@nestjs/microservices';
-import { interval } from 'rxjs';
+import { interval, Observable, Subject } from 'rxjs';
 import * as net from 'net'
 import { ConfigService } from '@nestjs/config';
+import { connectToAfisJava } from 'libs/java/afis.utils';
+import { FpVerificationPayload, FpVerificationResponse } from 'libs';
+import { v1 as uuid } from 'uuid'
 
 @Injectable()
 export class FisVerificationService {
+  private port: number
+  private host: string
+  private javaClient: net.Socket
+  private incomingMessageFromJava!: Subject<FpVerificationResponse>
+  private fpTemplate: any[] = []
 
   constructor(
     @Inject(`SAMPLEAPP_SERVICE`) private sampleClient: ClientProxy,
-    @Inject(`JAVA_AFIS`) private javaClient: ClientProxy, // this one cannot work unfortunately
     private configService: ConfigService
   ) {
-    // logic here
-    setTimeout(() => {
-      // logic here
-    }, 5000)
+    this.port = this.configService.get<number>('afis.tcpPort') as number
+    this.host = this.configService.get<string>('afis.host') as string
 
-    interval(3000).subscribe(interval => {
-      // this.sampleClient.emit(`message`, `Verification says HI`)
-      // this.javaClient.emit(`message`, `Testing Message  from Verification`)
-      // this.javaClient.send(`message`, `Testing Message  from Verification`)
+    this.javaClient = connectToAfisJava(this.host, this.port)
+    this.javaClient.on(`data`, (data) => {
+      let message: FpVerificationResponse = JSON.parse(data.toString())
+      console.log(message)
+      // this.incomingMessageFromJava.next(message)
     })
-
-    this.tryThis()
   }
 
-  tryThis() {
-    const port = this.configService.get<number>('afis.tcpPort')!;
-    const host = this.configService.get<string>('afis.host')!;
-    
-    const client = new net.Socket();
-  
-    const connectToServer = () => {
-      client.connect(port, host, () => {
-        console.log(`✅ Connected to Afis Java Server at ${host}:${port}`);
-      });
-    };
-  
-    // Attempt to connect initially
-    connectToServer();
-  
-    // Reconnect logic: try again after delay
-    client.on('error', (err) => {
-      console.error(`❌ TCP Error:`, err.message);
-      // Avoid crash on ECONNREFUSED etc.
-      setTimeout(connectToServer, 3000);
-    });
-  
-    client.on('close', (hadError) => {
-      console.warn(`⚠️ Connection closed${hadError ? ' due to error' : ''}. Reconnecting...`);
-      setTimeout(connectToServer, 3000);
-    });
-  
-    client.on('end', () => {
-      console.warn('⚠️ Server closed the connection.');
-    });
-  
-    // Optional: handle incoming data
-    client.on('data', (data) => {
-      console.log('📩 Received from server:', data.toString());
-    });
-  
-    // Message sending interval
-    interval(3000).subscribe(() => {
-      if (client.destroyed) {
-        console.warn('⚠️ Cannot send: socket is destroyed.');
-        return;
-      }
-  
-      const message = JSON.stringify({
-        pattern: 'get-user',
-        data: { id: 1 },
-      });
-  
-      client.write(message + '\n');
-    });
+  public handleMessage(message: any): void {
+    let data = JSON.parse(message)
+    // console.log(data)
+    let extractionMessage: FpVerificationPayload = {
+      id: uuid(),
+      cmd: `Registration`,
+      date: new Date(),
+      data: data.messageData,
+      fpTemplateArray: [],
+      message: `LOLz`
+    }
+    this.javaClient.write(JSON.stringify(extractionMessage) + `\n`)
   }
-  
+
 }
 
 /* Reason based on ChatGPT: Why ClientProxy.send() or emit() won't work 
@@ -86,4 +52,9 @@ A message envelope that wraps your pattern and data.
 Message IDs and event headers.
 A specific serialization/deserialization logic that is not plain JSON.
 NO newline character at the end.
-So when your Java server, which expects a newline-terminated JSON message, receives this custom binary format, it gets confused or sees null.*/
+So when your Java server, which expects a newline-terminated JSON message, receives this custom binary format, it gets confused or sees null.*/
+
+/* data: {
+messageData: string
+messageTemplateData: string
+deviceInfo: object} */

+ 1 - 1
apps/sample-app/src/main.ts

@@ -35,6 +35,6 @@ async function bootstrap() {
 
   await app.startAllMicroservices();
   await app.listen(restPort, host);
-  console.log(`REST API is running on: ${await app.getUrl()} and TCP is running on ${host}:${tcpPort} and Socket is running on ${host}:${socketPort}`);
+  mainLogger.log(`REST API is running on: ${await app.getUrl()} and TCP is running on ${host}:${tcpPort} and Socket is running on ${host}:${socketPort}`);
 }
 bootstrap();

+ 11 - 7
apps/sample-app/src/sample-app.gateway.ts

@@ -1,7 +1,10 @@
+import { Inject, Injectable, Logger } from '@nestjs/common';
+import { ClientProxy } from '@nestjs/microservices';
 import { ConnectedSocket, MessageBody, OnGatewayConnection, OnGatewayDisconnect, SubscribeMessage, WebSocketGateway, WebSocketServer, WsResponse, } from '@nestjs/websockets';
 import { from, Observable } from 'rxjs';
 import { map } from 'rxjs/operators';
 import { Server, Socket } from 'socket.io';
+import { SampleAppService } from './sample-app.service';
 
 @WebSocketGateway({
     cors: {
@@ -11,11 +14,11 @@ import { Server, Socket } from 'socket.io';
 })
 export class SampleEventsGateway implements OnGatewayConnection, OnGatewayDisconnect {
     @WebSocketServer()
-    server: Server;
+    server!: Server;
+    logger: Logger = new Logger(`SampleEventGateway`)
 
-    constructor() {
+    constructor(private readonly service: SampleAppService) {
         // logic here
-        // console.log(`Socket Server started??`)
     }
 
     @SubscribeMessage('test')
@@ -25,16 +28,17 @@ export class SampleEventsGateway implements OnGatewayConnection, OnGatewayDiscon
 
     @SubscribeMessage('message')
     handleMesage(@MessageBody() data: string, @ConnectedSocket() client: Socket): void {
-        console.log(data)
-        console.log(`${data} from ${client.id}`)
+        // console.log(data)
+        this.logger.log(`Received data from ${client.id}`)
+        this.service.emit(data)
     }
 
     // this two methods are non essential. as they are used to keep track of the local ui port 3000, not keeping track of the actual clients 
     handleConnection(client: any) {
-        console.log('Monitoring UI connected:', client.id);
+        this.logger.log(`Socket Client ${client.id} connected`);
     }
 
     handleDisconnect(client: any) {
-        console.log('Monitoring UI disconnected:', client.id);
+        this.logger.log(`Socket Client ${client.id} disconnected`);
     }
 }

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

@@ -22,5 +22,7 @@ export class SampleAppService {
     return this.fingerprintClient.send<string>({ cmd: `messageTest` }, message)
   }
 
-
+  emit(data: any): void {
+    this.fingerprintClient.emit(`message`, data)
+  }
 }

+ 74 - 0
libs/java/afis.utils.ts

@@ -0,0 +1,74 @@
+import * as net from 'net';
+import { interval, Subscription } from 'rxjs';
+
+export function connectToAfisJava(host: string, port: number, enableAutoPing = true): net.Socket {
+  const client = new net.Socket();
+  let reconnectTimeout: NodeJS.Timeout | null = null;
+  let pingSubscription: Subscription | null = null;
+
+  const connectToServer = () => {
+    client.connect(port, host, () => {
+      console.log(`✅ Connected to Afis Java Server at ${host}:${port}`);
+    });
+  };
+
+  const scheduleReconnect = () => {
+    if (!reconnectTimeout) {
+      reconnectTimeout = setTimeout(() => {
+        reconnectTimeout = null;
+        connectToServer();
+      }, 3000);
+    }
+  };
+
+  // Initial connection attempt
+  connectToServer();
+
+  // Reconnection logic
+  client.on('error', (err) => {
+    console.error(`❌ TCP Error:`, err.message);
+    scheduleReconnect();
+  });
+
+  client.on('close', (hadError) => {
+    console.warn(`⚠️ Connection closed${hadError ? ' due to error' : ''}. Reconnecting...`);
+    scheduleReconnect();
+  });
+
+  client.on('end', () => {
+    console.warn('⚠️ Server closed the connection.');
+  });
+
+  // Incoming data handler
+  client.on('data', (data) => {
+    // console.log('📩 Received from server:', data.toString());c
+    console.log(`Received 📩 From AfisServer` );
+  });
+
+  // Auto-message sending (optional)
+//   if (enableAutoPing) {
+//     pingSubscription = interval(3000).subscribe(() => {
+//       if (client.destroyed) {
+//         console.warn('⚠️ Cannot send: socket is destroyed.');
+//         return;
+//       }
+
+//       const message = JSON.stringify({
+//         pattern: 'get-user',
+//         data: { id: 1 },
+//       });
+
+//       client.write(message + '\n');
+//     });
+//   }
+
+  // Cleanup on destroy
+  client.on('destroy', () => {
+    if (pingSubscription) {
+      pingSubscription.unsubscribe();
+      pingSubscription = null;
+    }
+  });
+
+  return client;
+}

+ 0 - 1
libs/types/index.ts

@@ -1,2 +1 @@
-export * from './message'
 export * from './interface'

+ 29 - 1
libs/types/interface.ts

@@ -5,7 +5,7 @@ export interface Message {
 
 export interface ConnectionState {
     uuid?: string | number;
-    status: 'BUFFER' | 'DIRECT_PUBLISH' | 'LIMIT_EXCEEDED' ,
+    status: 'BUFFER' | 'DIRECT_PUBLISH' | 'LIMIT_EXCEEDED',
     reason?: string;
     payload?: any;
 }
@@ -16,4 +16,32 @@ export interface WrappedMessage {
     payload: any
     thisMessageID: string,
     previousMessageID: string | null,
+}
+
+export interface FpVerificationPayload {
+    id: string,
+    cmd: `Registration` | `Verification` | `Extract Template`,
+    date: Date,
+    data: any,
+    fpTemplate?: FingerprintTemplate,
+    fpTemplateArray: FingerprintTemplate[],
+    message?: string
+}
+
+export interface FpVerificationResponse {
+    id: string,
+    message: string,
+    data: FingerprintTemplate,
+    score?: number
+}
+export interface FingerprintTemplate {
+    id: string,
+    name: string,
+    org: string,
+    fingerprint: Fingerprint
+}
+
+export interface Fingerprint {
+    finger: number,
+    template: string
 }

+ 0 - 41
libs/types/message.ts

@@ -1,41 +0,0 @@
-/*  This Message constants and interfaces and function are mostly for GRPC microservice */
-import { GrpcMethod } from "@nestjs/microservices";
-import { Observable } from "rxjs";
-
-export const messageProtobufPackage = "message";
-
-export interface Request {
-    id: string;
-    message: string;
-}
-
-export interface Response {
-    id: string;
-    message: string;
-}
-
-export const MESSAGE_PACKAGE_NAME = "message";
-
-export interface MessageServiceClient {
-    returnResponse(request): Response
-    returnStreamResponse(request: Request): Observable<Response>;
-    bidirectionalStream(request: Observable<Request>): Observable<Response>
-}
-
-export interface GrpcMessageServiceController {
-    returnResponse(request): Response
-    returnStreamResponse(request: Request): Observable<Response>;
-    bidirectionalStream(request: Observable<Request>): Observable<Response>
-}
-
-export function GrpcMessageServiceControllerMethods() {
-    return function (constructor: Function) {
-        const grpcMethods: string[] = ["returnResponse", "returnStreamResponse", "bidirectionalStream"];
-        for (const method of grpcMethods) {
-            const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
-            GrpcMethod("GrpcMessageService", method)(constructor.prototype[method], method, descriptor);
-        }
-    };
-}
-
-export const MESSAGE_SERVICE_NAME = "GrpcMessageService";

+ 2 - 1
tsconfig.json

@@ -14,7 +14,8 @@
     "skipLibCheck": true,
     "strictNullChecks": true,
     "forceConsistentCasingInFileNames": true,
-    "noImplicitAny": false,
+    "noImplicitAny": true,
+    "strict": true,
     "strictBindCallApply": false,
     "noFallthroughCasesInSwitch": false,
     "paths": {