|
@@ -2,57 +2,84 @@ import { Observable, Subject } from "rxjs";
|
|
|
import { io, Socket, Socket as SocketClient } from "socket.io-client";
|
|
|
import { Socket as SocketServer } from "socket.io"
|
|
|
import { startClientSocketConnection, startSocketServer } from "../utils/socket.utils";
|
|
|
-import { TransportInterface, TransportSettings } from "../interface/transport.interface";
|
|
|
+import { ITransport, ReceiverProfile, TransportEventNotification, TransportSettings } from "../interface/ITransport.interface";
|
|
|
+import { error } from "console";
|
|
|
+import { v4 as uuidv4 } from 'uuid'
|
|
|
|
|
|
-export class WebsocketTransport implements TransportInterface {
|
|
|
+export class WebsocketTransportService implements ITransport {
|
|
|
private websocketRole!: 'Server' | 'Client' | null
|
|
|
private clientSocket!: SocketClient
|
|
|
- private serverSocket!: SocketServer
|
|
|
+ private connectedClient: ReceiverProfile[] = []
|
|
|
private responseSubject: Subject<any> = new Subject()
|
|
|
- private eventNotification: Subject<any> = new Subject()
|
|
|
+ private eventNotification: Subject<TransportEventNotification> = new Subject()
|
|
|
|
|
|
constructor(setting: TransportSettings) {
|
|
|
this.websocketRole == setting.role
|
|
|
if (setting.role == 'Server') {
|
|
|
- startSocketServer(setting.profileInfo.port as number).then((server: SocketServer) => {
|
|
|
- this.serverSocket = server
|
|
|
+ startSocketServer(setting.profileInfo.port as number).subscribe({
|
|
|
+ next: (connectedClient: SocketServer) => {
|
|
|
+ // returns the socket client instance
|
|
|
+ let receiverProfile: ReceiverProfile = {
|
|
|
+ uuid: uuidv4(),
|
|
|
+ name: `Client`,
|
|
|
+ dateCreated: new Date(),
|
|
|
+ data: connectedClient
|
|
|
+ }
|
|
|
+ this.eventNotification.next({ event: 'WebsocketClientConnection', description: 'New Client Connected', data: receiverProfile })
|
|
|
+ this.connectedClient.push(receiverProfile)
|
|
|
+
|
|
|
+ // put here first, but can me mgirated to other parts of the code
|
|
|
+ connectedClient.on('disconnect', () => {
|
|
|
+ this.eventNotification.next({ event: 'WebscoketClientConnection', description: `Existing Client ${connectedClient.id} disonnected`, data: receiverProfile })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ error: error => console.error(error),
|
|
|
+ complete: () => { } // should not complete. Keep listening to new client connection
|
|
|
})
|
|
|
}
|
|
|
+ // just focus on receiving.
|
|
|
if (setting.role == 'Client') {
|
|
|
startClientSocketConnection(setting.profileInfo.url as string).then((client: Socket) => {
|
|
|
this.clientSocket = client
|
|
|
+ // Need to open to listen to incoming responses
|
|
|
+ this.clientSocket.on('message', (message) => {
|
|
|
+ // console.log(message)
|
|
|
+ this.responseSubject.next(message)
|
|
|
+ })
|
|
|
+ this.clientSocket.on('notification', (notification) => {
|
|
|
+ // console.log(notification)
|
|
|
+ if (notification.header.messageName == 'NotificationMessage') {
|
|
|
+ this.eventNotification.next({ event: 'Server Notification', description: 'Notification from server', data: notification })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ this.clientSocket.on('disconnect', () => {
|
|
|
+ this.eventNotification.next({ event: 'Websocket Client Connection Status', description: 'Server disconnected' })
|
|
|
+ })
|
|
|
})
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- send(message: any): Observable<any> {
|
|
|
- return new Observable((response) => {
|
|
|
- if (this.websocketRole == 'Server') {
|
|
|
-
|
|
|
- }
|
|
|
- if (this.websocketRole == 'Client') {
|
|
|
- // filter message
|
|
|
- this.clientSocket.emit('message', message)
|
|
|
- this.responseSubject.subscribe(responseMsg => {
|
|
|
- if (responseMsg.id == message.id && !responseMsg.complete) {
|
|
|
- response.next(responseMsg)
|
|
|
- }
|
|
|
- if (responseMsg.id == message.id && responseMsg.complete) {
|
|
|
- response.complete()
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
- })
|
|
|
+ // to be used to emulate request response. But only for sending request, since all the response are to be redirected to another output
|
|
|
+ send(message: any, target?: string): void {
|
|
|
+ let socket = this.connectedClient.find(object => object.uuid === target)
|
|
|
+ if (socket) {
|
|
|
+ socket.data.emit('message', message)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- emit(message: any): void {
|
|
|
- if (this.clientSocket) {
|
|
|
- this.clientSocket.emit(`event`, message)
|
|
|
- }
|
|
|
+ emit(event: string, message: any): void {
|
|
|
+ // for now just assume everyone is subscribed to this broacdcast
|
|
|
+ this.connectedClient.forEach(client => {
|
|
|
+ client.data.emit(event, message)
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ getResponse(): Observable<any> {
|
|
|
+ return this.responseSubject.asObservable()
|
|
|
}
|
|
|
|
|
|
- getTransportEventNotification(): Observable<any> {
|
|
|
- return this.eventNotification as Observable<any>
|
|
|
+ getEventNotification(): Observable<TransportEventNotification> {
|
|
|
+ return this.eventNotification as Observable<TransportEventNotification>
|
|
|
}
|
|
|
|
|
|
}
|