import { v4 as uuidv4 } from 'uuid' import dotenv from 'dotenv'; import { TransportEvent, ConnectionManager as ConnectionManagerInterface, AdapterSet, Transport, TransportService, ClientObject } from "../interface/connector.interface" import { TransmitterConnectionAdapter } from './connector.transmitter' import { ReceiverConnectionAdapter } from './connector.receiver' import { EventMessage } from '../interface/transport.interface' import { Subject } from 'rxjs' import { WebsocketTransportService } from '../transport/websocket' import { RequestResponseConnectionAdapter } from './connector.request.response' import { HttpTransportService } from '../transport/http' /* now, this connection manager, after setting up the servers, will also need to start assigning receivers so to speak. From Provider's perspective: When instantiating a new server, there will be no doubt multiple clients connecting in. So that means, the connector instances that will be used from the transmission side, must already be configured and locked to their respective target so to speak. So for one client, there would only be one transmitter and receiver connector instances as well as request response. Let's go along with this line for now. */ export class ConnectionManager implements ConnectionManagerInterface { transportService!: TransportService; transportEvent: Subject = new Subject() // Every event goes through this boy, and it will be expose across differnet components adapterSet: AdapterSet[] = [] constructor() { console.log(`Connection Manager: Contructing ConnectionManager....`) // logic here this.getTransportService(process.env.Transport as unknown as Transport) this.setUpServer(process.env.PORT as unknown as number) // Everything that happens will go through here. Can also plug in logging service here at a later time this.transportEvent.subscribe((event: TransportEvent) => { console.log(`TranpsortEvent: `, event) if (event.event == 'New Client') { this.handleNewClient((event.data as EventMessage).payload) // payload is connectedclientInstance } }) } getAdapterSetById(adapterSetid: string): AdapterSet { let adapterSet: AdapterSet | undefined = this.adapterSet.find(obj => obj.id === adapterSetid) if (adapterSet) { return adapterSet } else { throw new Error(`Adapter Set not found!!!`) } } getTransportService(transportType: Transport): void { console.log(`Instantiating ${transportType} tranport service to be used.`) if (transportType === Transport.Websocket) { this.transportService = new WebsocketTransportService() this.triggerTransportEvent(`Setting up Websocket Transport Service`) } if (transportType === Transport.Http) { this.transportService = new HttpTransportService() this.triggerTransportEvent(`Setting up Http Transport Service`) } } private triggerTransportEvent(message: string): void { this.transportEvent.next({ id: uuidv4(), event: `New Transport`, data: { message } }); } // Server to be set up as well as acquiring client information if needed. Like in the case for grpc and socket. Http not requ`ired. private setUpServer(port: number): void { if (this.transportService instanceof WebsocketTransportService) { this.transportService.startServer(port); this.transportService.getTransportEvent().subscribe(this.transportEvent); } else if (this.transportService instanceof HttpTransportService) { this.transportService.startServer(port); this.transportService.getTransportEvent().subscribe(this.transportEvent); // Additional Http-specific setup if needed. } } private handleNewClient(clientInstance: ClientObject): void { // need to setup the adapters to be called by the transmission manager let transmitter: TransmitterConnectionAdapter = new TransmitterConnectionAdapter(this.transportService, clientInstance.id, this.transportEvent, clientInstance.connectionState.asObservable()) let receiver: ReceiverConnectionAdapter = new ReceiverConnectionAdapter(this.transportService, clientInstance.id, this.transportEvent) let requestResponse: RequestResponseConnectionAdapter = new RequestResponseConnectionAdapter(transmitter, receiver, clientInstance.id) let adapterSet: AdapterSet = { id: clientInstance.id, dateCreated: new Date(), transmitterAdapter: transmitter, receiverAdapter: receiver, requestResponsAdapter: requestResponse } this.adapterSet.push(adapterSet) this.transportEvent.next({ id: uuidv4(), event: `New Adapter`, data: { adapterId: adapterSet.id, message: `New Adapter Set${adapterSet.id} has been added`, payload: adapterSet } as EventMessage }) } }