|
@@ -1,62 +1,84 @@
|
|
|
-import { Observable, Observer, Subject } from "rxjs";
|
|
|
+import { Observable, Observer, Subject, Subscriber, Unsubscribable } from "rxjs";
|
|
|
import dotenv from 'dotenv';
|
|
|
import { v4 as uuidv4 } from 'uuid';
|
|
|
-import { WebsocketTransportService } from "../transport/websocket";
|
|
|
import { ITransportReceiving, ITransportSuper, ITransportTransmitting, ReceiverProfile, TransportEventNotification, TransportManagerEventNotification, TransportManagerInterface, TransportMessage, TransportSettings, TransportType } from "../interface/ITransport.interface";
|
|
|
+import { AdaptorTransmissionRole, ConnectionAdaptorBase, ConnectionState } from "../interface/connector.interface";
|
|
|
+import { FisAppActor, FisMessage } from "../interface/transport.interface";
|
|
|
|
|
|
dotenv.config();
|
|
|
/* This transport manager will be instantiating the necessary transport to deal with tranmission and receiving from different receivers
|
|
|
So how?: */
|
|
|
-export class ConnectionManager {
|
|
|
- private incomingMessage: Subject<TransportMessage> = new Subject() // only for client roles usage. Servers will listen to event notification for incoming requests
|
|
|
- private outGoingMessage: Subject<FisMessage> = new Subject()
|
|
|
+export class ConnectionAdapter implements FisAppActor, ConnectionAdaptorBase<any> {
|
|
|
+ incomingMessageBus: Subject<any> = new Subject()
|
|
|
+ outgoingMessageBus: Subject<any> = new Subject()
|
|
|
+ connector: any;
|
|
|
+ connectorProfile: any;
|
|
|
+ connectionState!: ConnectionState;
|
|
|
+ connectionStateBus!: Observable<ConnectionState>;
|
|
|
+ adaptorTransmissionRole!: AdaptorTransmissionRole;
|
|
|
+
|
|
|
+ // For Manager, TBD
|
|
|
private connectedClients: ReceiverProfile[] = []
|
|
|
private transportEventNotification: Subject<TransportEventNotification> = new Subject()
|
|
|
// this is assuming that the application will do request response, otherwise, just one will do.
|
|
|
- private transportService!: ITransportSuper
|
|
|
- private transmittingService!: ITransportTransmitting
|
|
|
- private receivingService!: ITransportReceiving
|
|
|
private serverPort!: number
|
|
|
private serverUrl!: string
|
|
|
|
|
|
constructor(port?: number, url?: string) {
|
|
|
if (port) {
|
|
|
- this.serverPort = port
|
|
|
- this.establishTransportTransmitting(process.env.Transport as TransportType).then((transmissionService: ITransportTransmitting) => {
|
|
|
- transmissionService.getTransportEventNotification().subscribe((notification: TransportEventNotification) => {
|
|
|
- // Collect client information when they are connected
|
|
|
- if (notification.event == `Connection` && notification.description == 'New Client Connected') {
|
|
|
- this.connectedClients.push(notification.data?.payload)
|
|
|
- this.handleNewReceiver(notification.data?.payload)
|
|
|
- }
|
|
|
- })
|
|
|
- }).catch((error) => console.error(error))
|
|
|
+ // instantiate the transport service. Eg: socket, http. Try to use the same service. Then return TransmitterConnectionAdapter
|
|
|
+
|
|
|
}
|
|
|
/* For web browser ui, because this server can also act as a receiver, not just transmitter as well. */
|
|
|
if (url) {
|
|
|
- this.serverUrl = url
|
|
|
- this.establishTransportReceiving(process.env.Transport as TransportType).then((receivingService: ITransportReceiving) => {
|
|
|
- // logic here
|
|
|
- })
|
|
|
+ // if no transport service is instantiated, then instantiate a new one, otherwise use existying one.
|
|
|
}
|
|
|
+
|
|
|
if (!port && !url) console.error(`No role has assigned for transport service due to lack of information provided!`)
|
|
|
this.processOutputMessage()
|
|
|
}
|
|
|
|
|
|
- // use for as a transmitter
|
|
|
- public emit(message: TransportMessage): void {
|
|
|
- if(this.transmittingService) {
|
|
|
- this.transmittingService.transmit(message)
|
|
|
- }
|
|
|
+ subscribeConnectionState(): Observable<ConnectionState> {
|
|
|
+ throw new Error("Method not implemented.");
|
|
|
}
|
|
|
-
|
|
|
- // use for as a receiver
|
|
|
- public send(message: TransportMessage): Observable<TransportMessage> {
|
|
|
- return new Observable((response: Observer<TransportMessage>) => {
|
|
|
+ publishConnectionState(): void {
|
|
|
+ throw new Error("Method not implemented.");
|
|
|
+ }
|
|
|
+ connect(): void {
|
|
|
+ throw new Error("Method not implemented.");
|
|
|
+ }
|
|
|
+ disconnect(): void {
|
|
|
+ throw new Error("Method not implemented.");
|
|
|
+ }
|
|
|
+ send(message: any): Observable<any> {
|
|
|
+ return new Observable((response) => {
|
|
|
// logic here
|
|
|
})
|
|
|
+
|
|
|
+ }
|
|
|
+ emit(message: any): void {
|
|
|
+ // logic here
|
|
|
+ }
|
|
|
+ emitStream(message: any): void {
|
|
|
+ throw new Error("Method not implemented.");
|
|
|
+ }
|
|
|
+ subscribeMessages(messageFilter: any): Observable<any> {
|
|
|
+ throw new Error("Method not implemented.");
|
|
|
+ }
|
|
|
+ subscribe(subscriber: Subscriber<any>): Unsubscribable {
|
|
|
+ // Emit some value based on T (here for demonstration)
|
|
|
+ subscriber.next({} as any);
|
|
|
+ subscriber.complete();
|
|
|
+
|
|
|
+ // Return an Unsubscribable object to allow unsubscription
|
|
|
+ return {
|
|
|
+ unsubscribe: () => {
|
|
|
+ console.log('Unsubscribed');
|
|
|
+ }
|
|
|
+ };
|
|
|
}
|
|
|
|
|
|
+
|
|
|
public getTransportManagerEventNotification(): Observable<TransportManagerEventNotification> {
|
|
|
return new Observable((notification: Observer<TransportManagerEventNotification>) => {
|
|
|
this.transportEventNotification.subscribe((transportNotification: TransportEventNotification) => {
|
|
@@ -82,9 +104,7 @@ export class ConnectionManager {
|
|
|
}
|
|
|
}
|
|
|
if (tranportType == 'WEBSOCKET') {
|
|
|
- this.transportService = this.transportService ? this.transportService : new WebsocketTransportService(setting)
|
|
|
- this.transmittingService = this.transportService
|
|
|
- resolve(this.transmittingService)
|
|
|
+ // logic here
|
|
|
} else {
|
|
|
reject(`No such Transport Type Exist...`)
|
|
|
}
|
|
@@ -103,33 +123,32 @@ export class ConnectionManager {
|
|
|
}
|
|
|
// will be sharing one instance, This part may break the code
|
|
|
if (tranportType == 'WEBSOCKET') {
|
|
|
- this.receivingService = this.transportService ? this.transportService : new WebsocketTransportService(setting)
|
|
|
- resolve(this.receivingService)
|
|
|
+ // logic here
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
|
|
|
// This function will wrap the message to be delivered over to established transport to be sent over
|
|
|
private processOutputMessage(): void {
|
|
|
- this.outGoingMessage.subscribe({
|
|
|
+ this.outgoingMessageBus.subscribe({
|
|
|
next: (message: FisMessage) => {
|
|
|
if (message.header.messageName == 'NotificationMessage') {
|
|
|
// This is just here temporarily. Because The application will be concerned with whom the party is subcribed to, not this transport manager
|
|
|
- this.transmittingService.transmit({
|
|
|
- id: message.header.messageID,
|
|
|
- receiverID: '',
|
|
|
- payload: message,
|
|
|
- event: `notification`
|
|
|
- })
|
|
|
+ // this.transmittingService.transmit({
|
|
|
+ // id: message.header.messageID,
|
|
|
+ // receiverID: '',
|
|
|
+ // payload: message,
|
|
|
+ // event: `notification`
|
|
|
+ // })
|
|
|
}
|
|
|
if (message.header.messageName == 'ResponseMessage') {
|
|
|
// Map responses according to the requestID???
|
|
|
- this.transmittingService.transmit({
|
|
|
- id: message.header.messageID,
|
|
|
- receiverID: '',
|
|
|
- payload: message,
|
|
|
- event: `resposne`
|
|
|
- })
|
|
|
+ // this.transmittingService.transmit({
|
|
|
+ // id: message.header.messageID,
|
|
|
+ // receiverID: '',
|
|
|
+ // payload: message,
|
|
|
+ // event: `resposne`
|
|
|
+ // })
|
|
|
}
|
|
|
}
|
|
|
})
|
|
@@ -157,10 +176,3 @@ export class ConnectionManager {
|
|
|
}
|
|
|
|
|
|
|
|
|
-export interface FisMessage {
|
|
|
- header: {
|
|
|
- messageName: 'RequestMessage' | 'ResponseMessage' | 'NotificationMessage',
|
|
|
- messageID: string
|
|
|
- },
|
|
|
- data: any
|
|
|
-}
|