Browse Source

Friday Commit

Enzo 1 month ago
parent
commit
370d64c61e
5 changed files with 1152 additions and 42 deletions
  1. 1015 42
      package-lock.json
  2. 7 0
      package.json
  3. 22 0
      src/interface/transport.interface.ts
  4. 58 0
      src/transport/websocket.ts
  5. 50 0
      src/utils/socket.utils.ts

File diff suppressed because it is too large
+ 1015 - 42
package-lock.json


+ 7 - 0
package.json

@@ -14,5 +14,12 @@
     "@types/express": "^5.0.0",
     "@types/node": "^22.7.4",
     "typescript": "^5.6.2"
+  },
+  "dependencies": {
+    "express": "^4.21.0",
+    "rxjs": "^7.8.1",
+    "socket.io": "^4.8.0",
+    "socket.io-client": "^4.8.0",
+    "uuid": "^10.0.0"
   }
 }

+ 22 - 0
src/interface/transport.interface.ts

@@ -0,0 +1,22 @@
+import { Observable } from "rxjs";
+
+export interface TransportInterface {
+    send(message: any): Observable<any>
+
+    emit(message: any): void
+
+    getTransportEventNotification(): Observable<any>
+}
+
+
+export interface TransportSettings {
+    role: 'Server' | 'Client',
+    profileInfo: ProfileInfo,
+}
+
+export interface ProfileInfo {
+    id: string,
+    name: string,
+    url?: string | null,
+    port?: number | null
+}

+ 58 - 0
src/transport/websocket.ts

@@ -0,0 +1,58 @@
+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";
+
+export class WebsocketTransport implements TransportInterface {
+    private websocketRole!: 'Server' | 'Client' | null
+    private clientSocket!: SocketClient
+    private serverSocket!: SocketServer
+    private responseSubject: Subject<any> = new Subject()
+    private eventNotification: Subject<any> = 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
+            })
+        }
+        if (setting.role == 'Client') {
+            startClientSocketConnection(setting.profileInfo.url as string).then((client: Socket) => {
+                this.clientSocket = client
+            })
+        }
+    }
+
+    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()
+                    }
+                })
+            }
+        })
+    }
+
+    emit(message: any): void {
+        if (this.clientSocket) {
+            this.clientSocket.emit(`event`, message)
+        }
+    }
+
+    getTransportEventNotification(): Observable<any> {
+        return this.eventNotification as Observable<any>
+    }
+
+}

+ 50 - 0
src/utils/socket.utils.ts

@@ -0,0 +1,50 @@
+import { createServer } from 'http';
+import { Server, Socket as ServerSocket } from 'socket.io';
+import { io, Socket as ClientSocket } from 'socket.io-client';
+
+export async function startSocketServer(port: number): Promise<ServerSocket> {
+    return new Promise((resolve, reject) => {
+        try {
+            let socketServer = new Server()
+
+            socketServer.on('connection', (socket) => {
+                resolve(socket)
+            })
+
+            socketServer.engine.on("connection_error", (err) => {
+                console.log(err.req);      // the request object
+                console.log(err.code);     // the error code, for example 1
+                console.log(err.message);  // the error message, for example "Session ID unknown"
+                console.log(err.context);  // some additional error context
+            });
+
+            // Start the socketServer
+            socketServer.listen(port)
+        } catch (error) {
+            reject(error)
+        }
+    })
+}
+
+export async function startClientSocketConnection(serverUrl: string): Promise<ClientSocket> {
+    return new Promise((resolve, reject) => {
+        try {
+            let clientSocket = io(serverUrl, {
+                reconnection: true,              // Enable automatic reconnections
+                reconnectionAttempts: 100,       // Retry up to 10 times
+                reconnectionDelay: 500,          // Start with a 500ms delay
+                reconnectionDelayMax: 10000,     // Delay can grow to a max of 10 seconds
+                randomizationFactor: 0.3,
+            })
+
+            // Listen for a connection event
+            clientSocket.on('connect', () => {
+                console.log('Connected to the server:', clientSocket.id)
+                resolve(clientSocket)
+            });
+        }
+        catch (error) {
+            reject(error)
+        }
+    })
+}

Some files were not shown because too many files changed in this diff