import { BehaviorSubject, filter, Observable, Subject } from "rxjs"; import { Socket as ClientSocket } from 'socket.io-client' import { Socket as SocketForConnectedClient } from "socket.io" import { handleClientSocketConnection, handleNewSocketClient, startClientSocketConnection, startSocketServer } from "../utils/socket.utils"; import { ClientObject, ConnectionState, Info, Transport, TransportEvent, TransportMessage, TransportService } from "../interface/connector.interface"; import { error } from "console"; import { subscribe } from "diagnostics_channel"; /* Just code in the context that this websocket service will be handling multiple UI clients. Can think about the server communication at a later time. */ export class WebsocketTransportService implements TransportService { private info: Transport = Transport.Websocket private connectedServer: ConnectedServerSocket[] = [] // to allow the possibility of having to communicate with multiple servers as a client private connectedClientSocket: ConnectedClientSocket[] = [] // to keep track of the all the clients that are connected // private incomingMessage: Subject = new Subject() // this is only for client roles only atm private transportEvent!: Subject constructor(event: Subject) { console.log(`WebsocketTransportService: Constructing socket transport service....`) this.transportEvent = event // logic here } public startServer(port: number): void { // logic here startSocketServer(port).subscribe({ next: (connectedClient: SocketForConnectedClient) => { console.log(`WebsocketTransport Server Started...`) handleNewSocketClient(connectedClient, this.connectedClientSocket).subscribe({ next: event => this.transportEvent.next(event), error: error => console.error(error), complete: () => console.log(`Client ${connectedClient.id} disconnected...`) }) }, error: error => console.error(error), complete: () => console.log(`...`) }) } public startClient(url: string): void { // logic here startClientSocketConnection(url).then((socket: ClientSocket) => { let clientName = '' // initiate a check in local file. If no client name, then this is new handleClientSocketConnection(socket, this.connectedServer).subscribe(this.transportEvent) }).catch((error) => { console.error(`WebsocketTransport ERROR:`, error) }) } // for transmission(Server Only, not applicable for client Socket) public emit(message: TransportMessage): void { let clientObj: ConnectedClientSocket | undefined = this.connectedClientSocket.find(obj => obj.id == message.target) if (clientObj && clientObj.connectionState.getValue() == 'ONLINE') { clientObj.socketInstance.emit(`message`, message.payload) } } // this returns the ref pointer for the TransportEvent instantiated at Supervisor. Socket will broadcast incoming messages as event public subscribe(): Observable { return this.transportEvent.asObservable() } public getInfo(): Transport { return this.info } } export interface ConnectedClientSocket extends ClientObject { socketInstance: SocketForConnectedClient } export interface ConnectedServerSocket extends ClientObject { socketInstance: ClientSocket }