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"; /* 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 = new Subject() constructor() { console.log(`WebsocketTransportService: Constructing socket transport service....`) // 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(this.transportEvent) }, error: error => console.error(error), }) } public startClient(url: string): void { // logic here startClientSocketConnection(url).then((socket: ClientSocket) => { handleClientSocketConnection(socket, this.connectedServer).subscribe(this.transportEvent) }).catch((error) => { console.error(`WebsocketTransport ERROR:`, error) }) } public getTransportEvent(): Observable { return this.transportEvent.asObservable() } // for transmission(Server Only, not applicable for client Socket) public emit(message: TransportMessage): void { /* Just a rough idea, Because this service still needs to be direct the mesage to be emiteed based on the client that send it earlier. For example, if it'd doing a request response, obviosuly, it needs to be identified whose respnses it belong to. */ let clientObj: ConnectedClientSocket | undefined = this.connectedClientSocket.find(obj => obj.id == message.target) if(clientObj && clientObj.connectionState.getValue() == 'ONLINE') { clientObj.socketInstance.emit(`message`, message) } } 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 }