|
@@ -6,7 +6,8 @@ import * as fs from 'fs'
|
|
|
import { v4 as uuidv4 } from 'uuid'
|
|
|
import { ConnectionState, Transport, TransportEvent, TransportMessage } from '../interface/connector.interface';
|
|
|
import { ConnectedClientSocket, ConnectedServerSocket } from '../transport/websocket';
|
|
|
-import { EventMessage } from '../interface/transport.interface';
|
|
|
+import { EventMessage, FisMessage } from '../interface/transport.interface';
|
|
|
+import { error } from 'console';
|
|
|
|
|
|
export function startSocketServer(port: number): Observable<SocketForConnectedClient> {
|
|
|
return new Observable((observer) => {
|
|
@@ -146,6 +147,7 @@ export function handleClientSocketConnection(socket: ClientSocket, serversConnec
|
|
|
// Update websocket instance record
|
|
|
let clientObj: ConnectedServerSocket | undefined = serversConnected.find(obj => obj.id === (data.message as ConnectedServerSocket).id)
|
|
|
if (clientObj) {
|
|
|
+ receiverProfileInfo.connectionState = clientObj.connectionState
|
|
|
clientObj.socketInstance = receiverProfileInfo.socketInstance
|
|
|
clientObj.connectionState.next('ONLINE')
|
|
|
}
|
|
@@ -210,33 +212,50 @@ export function handleNewSocketClient(socket: SocketForConnectedClient, connecte
|
|
|
})
|
|
|
// Update connected clientInstance info to adapter
|
|
|
connectedClientSocket.push(clientInstance)
|
|
|
+ addClientToDB(clientInstance)
|
|
|
startListening(socket, clientInstance, event)
|
|
|
} else {
|
|
|
// update first
|
|
|
- let clientInstance: ConnectedClientSocket | undefined = connectedClientSocket.find(obj => obj.id === message.data.id)
|
|
|
- if (clientInstance) {
|
|
|
- console.log(`Socket Client ${clientInstance.id} Found`)
|
|
|
- socket.emit('profile', { name: 'Adjusted Profile', message: { id: clientInstance.id } })
|
|
|
- // replace socket instance since the previous has been terminated
|
|
|
- clientInstance.socketInstance = socket
|
|
|
- // need to start listening again, because it's assigned a different socket instance this time round
|
|
|
- startListening(socket, clientInstance, event)
|
|
|
- event.next({
|
|
|
- id: uuidv4(),
|
|
|
- event: 'Client Reconnected',
|
|
|
- data: {
|
|
|
- clientId: clientInstance.id,
|
|
|
- message: `Client ${clientInstance.id} connection re-established`,
|
|
|
- payload: clientInstance
|
|
|
- } as EventMessage
|
|
|
- })
|
|
|
- // Resume operation
|
|
|
- if (clientInstance.connectionState.getValue() == 'OFFLINE') {
|
|
|
- clientInstance.connectionState.next(`ONLINE`)
|
|
|
- }
|
|
|
+ let clientInstance: ConnectedClientSocket | undefined
|
|
|
+ if (connectedClientSocket.length > 0) {
|
|
|
+ clientInstance = connectedClientSocket.find(obj => obj.id === message.data.id)
|
|
|
+ temp(clientInstance)
|
|
|
} else {
|
|
|
- console.log(`Profile Not Found`)
|
|
|
- socket.emit('profile', { name: 'Error', message: 'Receiver Profile Not found' })
|
|
|
+ // for the case server itself got shit down or something
|
|
|
+ checkIfClientExists(message.data.id).then((client: ConnectedClientSocket) => {
|
|
|
+ clientInstance = client
|
|
|
+ temp(clientInstance)
|
|
|
+ }).catch(error => console.error(error))
|
|
|
+ }
|
|
|
+ function temp(clientInstance: ConnectedClientSocket | undefined) {
|
|
|
+ if (clientInstance) {
|
|
|
+ console.log(`Socket Client ${clientInstance.id} Found`)
|
|
|
+ socket.emit('profile', { name: 'Adjusted Profile', message: { id: clientInstance.id } })
|
|
|
+ // replace socket instance since the previous has been terminated
|
|
|
+ clientInstance.socketInstance = socket
|
|
|
+ // some explanation here. For the case where the server reads from the DB, no need to terminate subject, since all instances would be destroyed alongside the server shut down. This case is specificd only when there's a need to read from local file
|
|
|
+ if (!clientInstance.connectionState) {
|
|
|
+ clientInstance.connectionState = new BehaviorSubject<ConnectionState>(`ONLINE`)
|
|
|
+ }
|
|
|
+ // need to start listening again, because it's assigned a different socket instance this time round
|
|
|
+ startListening(socket, clientInstance, event)
|
|
|
+ event.next({
|
|
|
+ id: uuidv4(),
|
|
|
+ event: 'Client Reconnected',
|
|
|
+ data: {
|
|
|
+ clientId: clientInstance.id,
|
|
|
+ message: `Client ${clientInstance.id} connection re-established`,
|
|
|
+ payload: clientInstance
|
|
|
+ } as EventMessage
|
|
|
+ })
|
|
|
+ // Resume operation
|
|
|
+ if (clientInstance.connectionState.getValue() == 'OFFLINE') {
|
|
|
+ clientInstance.connectionState.next(`ONLINE`)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ console.log(`Profile Not Found`)
|
|
|
+ socket.emit('profile', { name: 'Error', message: 'Receiver Profile Not found' })
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
})
|
|
@@ -260,6 +279,62 @@ export async function writeFile(data: ConnectedServerSocket, filename: string):
|
|
|
})
|
|
|
}
|
|
|
|
|
|
+/* For Internal Usage only. Temporary serve as a way for server to keep track of clients. To be replaced in the future with better alternatives. */
|
|
|
+function addClientToDB(entry: ConnectedClientSocket, filePath: string = 'clients.json'): void {
|
|
|
+ try {
|
|
|
+ let data: ConnectedClientSocket[] = [];
|
|
|
+
|
|
|
+ // Check if the file exists and load existing data
|
|
|
+ if (fs.existsSync(filePath)) {
|
|
|
+ const fileContent = fs.readFileSync(filePath, 'utf-8');
|
|
|
+ data = JSON.parse(fileContent);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Append the new object to the array
|
|
|
+ data.push({
|
|
|
+ id: entry.id,
|
|
|
+ dateCreated: entry.dateCreated,
|
|
|
+ connectionState: null,
|
|
|
+ socketInstance: null
|
|
|
+ } as unknown as ConnectedClientSocket);
|
|
|
+
|
|
|
+ // Write the updated array back to the file
|
|
|
+ fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8');
|
|
|
+ console.log(`Entry added successfully.`);
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Error writing to file:', error);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+async function checkIfClientExists(id: string, filePath: string = 'clients.json'): Promise<ConnectedClientSocket> {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ try {
|
|
|
+ // Check if the file exists
|
|
|
+ if (!fs.existsSync(filePath)) {
|
|
|
+ console.log("File does not exist.");
|
|
|
+ reject('File does not exist');
|
|
|
+ }
|
|
|
+
|
|
|
+ // Read and parse the data
|
|
|
+ const fileContent = fs.readFileSync(filePath, 'utf-8');
|
|
|
+ const data: any[] = JSON.parse(fileContent);
|
|
|
+
|
|
|
+ // Check if an object with the given id exists
|
|
|
+ let obj = data.find(entry => entry.id === id);
|
|
|
+
|
|
|
+ if (obj) {
|
|
|
+ console.log(`Client with ID ${id} exists.`);
|
|
|
+ } else {
|
|
|
+ console.log(`Client with ID ${id} does not exist.`);
|
|
|
+ }
|
|
|
+
|
|
|
+ resolve(obj);
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Error reading the file:', error);
|
|
|
+ reject(`Error reading the file`)
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
|
|
|
|
|
|
// Check if filename exists. Return profile information if there's any
|
|
@@ -321,4 +396,3 @@ export function startListening(socket: SocketForConnectedClient, client: Connect
|
|
|
eventListener.complete()
|
|
|
})
|
|
|
}
|
|
|
-
|