|
@@ -7,11 +7,13 @@ import { v4 as uuidv4 } from 'uuid'
|
|
import { ConnectionState, Transport, TransportEvent, TransportMessage } from '../interface/connector.interface';
|
|
import { ConnectionState, Transport, TransportEvent, TransportMessage } from '../interface/connector.interface';
|
|
import { ConnectedClientSocket, ConnectedServerSocket } from '../transport/websocket';
|
|
import { ConnectedClientSocket, ConnectedServerSocket } from '../transport/websocket';
|
|
import { EventMessage } from '../interface/transport.interface';
|
|
import { EventMessage } from '../interface/transport.interface';
|
|
|
|
+import ConsoleLogger from './log.utils';
|
|
|
|
+const console: ConsoleLogger = new ConsoleLogger(`SocketUtils`, ['transport'])
|
|
|
|
|
|
export function startSocketServer(port: number): Observable<SocketForConnectedClient> {
|
|
export function startSocketServer(port: number): Observable<SocketForConnectedClient> {
|
|
return new Observable((observer) => {
|
|
return new Observable((observer) => {
|
|
try {
|
|
try {
|
|
- console.log(`Socket Server ${port} Started....`)
|
|
|
|
|
|
+ console.log({ message: `Socket Server ${port} Started....` })
|
|
let httpServer = createServer();
|
|
let httpServer = createServer();
|
|
let socketServer = new Server(httpServer)
|
|
let socketServer = new Server(httpServer)
|
|
|
|
|
|
@@ -21,15 +23,15 @@ export function startSocketServer(port: number): Observable<SocketForConnectedCl
|
|
})
|
|
})
|
|
|
|
|
|
socketServer.engine.on("connection_error", (err) => {
|
|
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
|
|
|
|
|
|
+ console.log({ message: `Socket Server ${port} Connection Error`, details: err.req })
|
|
|
|
+ console.log({ message: `Socket Server ${port} Connection Error`, details: err.code })
|
|
|
|
+ console.log({ message: `Socket Server ${port} Connection Error`, details: err.message })
|
|
|
|
+ console.log({ message: `Socket Server ${port} Connection Error`, details: err.context })
|
|
});
|
|
});
|
|
|
|
|
|
// Start the HTTP server on 127.0.0.1 with the given port
|
|
// Start the HTTP server on 127.0.0.1 with the given port
|
|
httpServer.listen(port, '0.0.0.0', () => {
|
|
httpServer.listen(port, '0.0.0.0', () => {
|
|
- console.log(`Socket server listening on ${port}`);
|
|
|
|
|
|
+ console.log({ message: `Socket server listening on ${port}` });
|
|
});
|
|
});
|
|
} catch (error) {
|
|
} catch (error) {
|
|
observer.error(error);
|
|
observer.error(error);
|
|
@@ -64,7 +66,7 @@ export function handleClientSocketConnection(socket: ClientSocket, serversConnec
|
|
|
|
|
|
// Listen for a connection event
|
|
// Listen for a connection event
|
|
socket.on('connect', () => {
|
|
socket.on('connect', () => {
|
|
- console.log('Connected to the server:', socket.id)
|
|
|
|
|
|
+ console.log({ message: `Connected to the server ${socket.id} ` })
|
|
if (receiverProfileInfo?.id) {
|
|
if (receiverProfileInfo?.id) {
|
|
checkOwnClientInfo(receiverProfileInfo.id).then((profile: { id: string }) => {
|
|
checkOwnClientInfo(receiverProfileInfo.id).then((profile: { id: string }) => {
|
|
socket.emit('profile', {
|
|
socket.emit('profile', {
|
|
@@ -109,9 +111,8 @@ export function handleClientSocketConnection(socket: ClientSocket, serversConnec
|
|
})
|
|
})
|
|
|
|
|
|
socket.on('profile', (data: { name: string, message: any }) => {
|
|
socket.on('profile', (data: { name: string, message: any }) => {
|
|
- console.log(data)
|
|
|
|
if (data.name == 'New Profile') {
|
|
if (data.name == 'New Profile') {
|
|
- console.log(`Assigned client Name: ${data.message.id}`)
|
|
|
|
|
|
+ console.log({ message: `Assigned client Name: ${data.message.id}` })
|
|
// Update websocket instance record
|
|
// Update websocket instance record
|
|
receiverProfileInfo = {
|
|
receiverProfileInfo = {
|
|
id: data.message.id,
|
|
id: data.message.id,
|
|
@@ -120,7 +121,7 @@ export function handleClientSocketConnection(socket: ClientSocket, serversConnec
|
|
connectionState: new BehaviorSubject<ConnectionState>(`ONLINE`)
|
|
connectionState: new BehaviorSubject<ConnectionState>(`ONLINE`)
|
|
}
|
|
}
|
|
writeFile(data.message as ConnectedServerSocket, (data.message as ConnectedServerSocket).id).then(() => {
|
|
writeFile(data.message as ConnectedServerSocket, (data.message as ConnectedServerSocket).id).then(() => {
|
|
- // broadcast event to allow retransmission to release buffer
|
|
|
|
|
|
+ // broadcast event to allow transmission manager to instantiate transmission components
|
|
eventNotification.next({
|
|
eventNotification.next({
|
|
id: uuidv4(),
|
|
id: uuidv4(),
|
|
event: `New Server`,
|
|
event: `New Server`,
|
|
@@ -129,11 +130,20 @@ export function handleClientSocketConnection(socket: ClientSocket, serversConnec
|
|
message: `New Websocket Channel ${(data.message as ConnectedServerSocket).id} established.`
|
|
message: `New Websocket Channel ${(data.message as ConnectedServerSocket).id} established.`
|
|
} as EventMessage
|
|
} as EventMessage
|
|
})
|
|
})
|
|
|
|
+ // broadcast event to allow retransmission to relase buffered messages
|
|
|
|
+ eventNotification.next({
|
|
|
|
+ id: uuidv4(),
|
|
|
|
+ event: `Server Connected`,
|
|
|
|
+ data: {
|
|
|
|
+ clientId: (data.message as ConnectedServerSocket).id,
|
|
|
|
+ message: `Server ${(data.message as ConnectedServerSocket).id} connected and ready to go.`
|
|
|
|
+ } as EventMessage
|
|
|
|
+ })
|
|
}).catch((error) => { }) // do nothing at the moment.
|
|
}).catch((error) => { }) // do nothing at the moment.
|
|
serversConnected.push(receiverProfileInfo)
|
|
serversConnected.push(receiverProfileInfo)
|
|
}
|
|
}
|
|
if (data.name == 'Adjusted Profile') {
|
|
if (data.name == 'Adjusted Profile') {
|
|
- console.log(`Assigned client Name: ${(data.message as ConnectedServerSocket).id}`)
|
|
|
|
|
|
+ console.log({ message: `Adjusted client Name: ${(data.message as ConnectedServerSocket).id}` })
|
|
// Update websocket instance record
|
|
// Update websocket instance record
|
|
let clientObj: ConnectedServerSocket | undefined = serversConnected.find(obj => obj.id === data.message.id)
|
|
let clientObj: ConnectedServerSocket | undefined = serversConnected.find(obj => obj.id === data.message.id)
|
|
if (clientObj) {
|
|
if (clientObj) {
|
|
@@ -142,7 +152,9 @@ export function handleClientSocketConnection(socket: ClientSocket, serversConnec
|
|
clientObj.id = receiverProfileInfo.id
|
|
clientObj.id = receiverProfileInfo.id
|
|
clientObj.socketInstance = socket
|
|
clientObj.socketInstance = socket
|
|
clientObj.connectionState.next('ONLINE')
|
|
clientObj.connectionState.next('ONLINE')
|
|
- console.log(`Just to make sure they are pointed accurately:`, `This should be ONLINE: ${receiverProfileInfo.connectionState.getValue()}`, `Id match? ${receiverProfileInfo.id == clientObj.id ? true : false}`)
|
|
|
|
|
|
+ console.log({
|
|
|
|
+ message: `Just to make sure they are pointed accurately: This should be ONLINE: ${receiverProfileInfo.connectionState.getValue()} !! Id match? ${receiverProfileInfo.id == clientObj.id ? true : false}`,
|
|
|
|
+ })
|
|
}
|
|
}
|
|
writeFile(data.message as ConnectedServerSocket, (data.message as ConnectedServerSocket).id).then(() => {
|
|
writeFile(data.message as ConnectedServerSocket, (data.message as ConnectedServerSocket).id).then(() => {
|
|
// broadcast event to allow retransmission to release buffer
|
|
// broadcast event to allow retransmission to release buffer
|
|
@@ -157,7 +169,7 @@ export function handleClientSocketConnection(socket: ClientSocket, serversConnec
|
|
}).catch((error) => { }) // do nothing at the moment.
|
|
}).catch((error) => { }) // do nothing at the moment.
|
|
}
|
|
}
|
|
if (data.name == 'Error') {
|
|
if (data.name == 'Error') {
|
|
- console.log(`Server cannot find credentials`, data.message)
|
|
|
|
|
|
+ console.log({ message: `Server cannot find credentials`, details: data.message })
|
|
// logic to request for new credentials
|
|
// logic to request for new credentials
|
|
setTimeout(() => {
|
|
setTimeout(() => {
|
|
socket.emit('profile', {
|
|
socket.emit('profile', {
|
|
@@ -170,7 +182,7 @@ export function handleClientSocketConnection(socket: ClientSocket, serversConnec
|
|
|
|
|
|
// Handle disconnection
|
|
// Handle disconnection
|
|
socket.on('disconnect', () => {
|
|
socket.on('disconnect', () => {
|
|
- console.error(`Socket Server ${receiverProfileInfo.id} Disconnected`)
|
|
|
|
|
|
+ console.log({ message: `Socket Server ${receiverProfileInfo.id} Disconnected` })
|
|
if (receiverProfileInfo) {
|
|
if (receiverProfileInfo) {
|
|
eventNotification.next({
|
|
eventNotification.next({
|
|
id: uuidv4(),
|
|
id: uuidv4(),
|
|
@@ -189,7 +201,7 @@ export function handleClientSocketConnection(socket: ClientSocket, serversConnec
|
|
// For SERVER Usage: set up socket listeners to start listening for different events
|
|
// For SERVER Usage: set up socket listeners to start listening for different events
|
|
export function handleNewSocketClient(socket: SocketForConnectedClient, connectedClientSocket: ConnectedClientSocket[]): Observable<TransportEvent> {
|
|
export function handleNewSocketClient(socket: SocketForConnectedClient, connectedClientSocket: ConnectedClientSocket[]): Observable<TransportEvent> {
|
|
return new Observable((event: Observer<TransportEvent>) => {
|
|
return new Observable((event: Observer<TransportEvent>) => {
|
|
- console.log(`Setting up listeners for socket:${socket.id}`)
|
|
|
|
|
|
+ console.log({ message: `Setting up listeners for socket:${socket.id}` })
|
|
// returns the socket client instance
|
|
// returns the socket client instance
|
|
// listen to receiver's initiotion first before assigning 'credentials'
|
|
// listen to receiver's initiotion first before assigning 'credentials'
|
|
socket.on(`profile`, (message: { name: string, data: any }) => {
|
|
socket.on(`profile`, (message: { name: string, data: any }) => {
|
|
@@ -229,23 +241,21 @@ export function handleNewSocketClient(socket: SocketForConnectedClient, connecte
|
|
checkIfClientExists(message.data.id).then((client: ConnectedClientSocket) => {
|
|
checkIfClientExists(message.data.id).then((client: ConnectedClientSocket) => {
|
|
clientInstance = client
|
|
clientInstance = client
|
|
handleFoundClient(clientInstance)
|
|
handleFoundClient(clientInstance)
|
|
- }).catch(error => console.error(error))
|
|
|
|
|
|
+ }).catch(error => {
|
|
|
|
+ console.log({ message: `Promise Error`, details: error })
|
|
|
|
+ })
|
|
}
|
|
}
|
|
function handleFoundClient(clientInstance: ConnectedClientSocket | undefined) {
|
|
function handleFoundClient(clientInstance: ConnectedClientSocket | undefined) {
|
|
if (clientInstance) {
|
|
if (clientInstance) {
|
|
- console.log(`Socket Client ${clientInstance.id} Found`)
|
|
|
|
|
|
+ console.log({ message: `Socket Client ${clientInstance.id} Found` })
|
|
socket.emit('profile', { name: 'Adjusted Profile', message: { id: clientInstance.id } })
|
|
socket.emit('profile', { name: 'Adjusted Profile', message: { id: clientInstance.id } })
|
|
// replace socket instance since the previous has been terminated
|
|
// replace socket instance since the previous has been terminated
|
|
clientInstance.socketInstance = socket
|
|
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>(`OFFLINE`)
|
|
|
|
- }
|
|
|
|
// need to start listening again, because it's assigned a different socket instance this time round
|
|
// need to start listening again, because it's assigned a different socket instance this time round
|
|
- startListening(socket, clientInstance, event)
|
|
|
|
|
|
+ startListening(socket, clientInstance, event, true)
|
|
|
|
|
|
} else {
|
|
} else {
|
|
- console.log(`Profile Not Found`)
|
|
|
|
|
|
+ console.log({ message: `Profile Not Found` })
|
|
socket.emit('profile', { name: 'Error', message: 'Receiver Profile Not found' })
|
|
socket.emit('profile', { name: 'Error', message: 'Receiver Profile Not found' })
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -261,10 +271,10 @@ export async function writeFile(data: ConnectedServerSocket, filename: string):
|
|
// Write JSON data to a file
|
|
// Write JSON data to a file
|
|
fs.writeFile(`${filename}.json`, JSON.stringify(data, null, 2), (err) => {
|
|
fs.writeFile(`${filename}.json`, JSON.stringify(data, null, 2), (err) => {
|
|
if (err) {
|
|
if (err) {
|
|
- console.error('Error writing file', err);
|
|
|
|
|
|
+ console.log({ message: 'Error writing file', details: err })
|
|
reject(false)
|
|
reject(false)
|
|
} else {
|
|
} else {
|
|
- console.log('File has been written');
|
|
|
|
|
|
+ console.log({ message: 'File has been written', details: err })
|
|
resolve(true)
|
|
resolve(true)
|
|
}
|
|
}
|
|
});
|
|
});
|
|
@@ -282,7 +292,7 @@ export function addClientToDB(entry: ConnectedClientSocket, filePath: string = '
|
|
data = JSON.parse(fileContent);
|
|
data = JSON.parse(fileContent);
|
|
}
|
|
}
|
|
|
|
|
|
- // Append the new object to the array
|
|
|
|
|
|
+ // Append the new details to the array
|
|
data.push({
|
|
data.push({
|
|
id: entry.id,
|
|
id: entry.id,
|
|
dateCreated: entry.dateCreated,
|
|
dateCreated: entry.dateCreated,
|
|
@@ -292,9 +302,9 @@ export function addClientToDB(entry: ConnectedClientSocket, filePath: string = '
|
|
|
|
|
|
// Write the updated array back to the file
|
|
// Write the updated array back to the file
|
|
fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8');
|
|
fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8');
|
|
- console.log(`Entry added successfully.`);
|
|
|
|
|
|
+ console.log({ message: `Entry added successfully.` })
|
|
} catch (error) {
|
|
} catch (error) {
|
|
- console.error('Error writing to file:', error);
|
|
|
|
|
|
+ console.log({ message: 'Error writing to file:', details: error })
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -303,7 +313,7 @@ export async function checkIfClientExists(id: string, filePath: string = 'client
|
|
try {
|
|
try {
|
|
// Check if the file exists
|
|
// Check if the file exists
|
|
if (!fs.existsSync(filePath)) {
|
|
if (!fs.existsSync(filePath)) {
|
|
- console.log("File does not exist.");
|
|
|
|
|
|
+ console.log({ message: "File does not exist." })
|
|
reject('File does not exist');
|
|
reject('File does not exist');
|
|
}
|
|
}
|
|
|
|
|
|
@@ -311,18 +321,16 @@ export async function checkIfClientExists(id: string, filePath: string = 'client
|
|
const fileContent = fs.readFileSync(filePath, 'utf-8');
|
|
const fileContent = fs.readFileSync(filePath, 'utf-8');
|
|
const data: any[] = JSON.parse(fileContent);
|
|
const data: any[] = JSON.parse(fileContent);
|
|
|
|
|
|
- // Check if an object with the given id exists
|
|
|
|
|
|
+ // Check if an details with the given id exists
|
|
let obj = data.find(entry => entry.id === id);
|
|
let obj = data.find(entry => entry.id === id);
|
|
|
|
|
|
if (obj) {
|
|
if (obj) {
|
|
- console.log(`Client with ID ${id} exists.`);
|
|
|
|
|
|
+ console.log({ message: "Client with ID ${id} exists." })
|
|
} else {
|
|
} else {
|
|
- console.log(`Client with ID ${id} does not exist.`);
|
|
|
|
|
|
+ console.log({ message: `Client with ID ${id} does not exist.` })
|
|
}
|
|
}
|
|
-
|
|
|
|
resolve(obj);
|
|
resolve(obj);
|
|
} catch (error) {
|
|
} catch (error) {
|
|
- console.error('Error reading the file:', error);
|
|
|
|
reject(`Error reading the file`)
|
|
reject(`Error reading the file`)
|
|
}
|
|
}
|
|
})
|
|
})
|
|
@@ -349,34 +357,39 @@ export async function checkOwnClientInfo(filename?: string): Promise<{ id: strin
|
|
|
|
|
|
} catch (err) {
|
|
} catch (err) {
|
|
// Handle parsing errors or other file-related errors
|
|
// Handle parsing errors or other file-related errors
|
|
- console.error("Error reading or parsing file:", err);
|
|
|
|
|
|
+ console.log({ message: "Error reading or parsing file:", details: err })
|
|
reject('');
|
|
reject('');
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
- console.error("File does not exist");
|
|
|
|
|
|
+ console.log({ message: "File does not exist" })
|
|
reject('');
|
|
reject('');
|
|
}
|
|
}
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
// this is for server usage only
|
|
// this is for server usage only
|
|
-export function startListening(socket: SocketForConnectedClient, client: ConnectedClientSocket, eventListener: Observer<TransportEvent>): void {
|
|
|
|
|
|
+export function startListening(socket: SocketForConnectedClient, client: ConnectedClientSocket, eventListener: Observer<TransportEvent>, oldClient?: boolean): void {
|
|
// notify it's associated retransmission to start releaseing buffer
|
|
// notify it's associated retransmission to start releaseing buffer
|
|
eventListener.next({
|
|
eventListener.next({
|
|
id: uuidv4(),
|
|
id: uuidv4(),
|
|
- event: `Client Connected`,
|
|
|
|
|
|
+ event: oldClient ? 'Client Re-connected' : `Client Connected`,
|
|
data: {
|
|
data: {
|
|
clientId: client.id,
|
|
clientId: client.id,
|
|
- message: `Socket Client Connected. Adapter ID assigned: ${client.id}`,
|
|
|
|
|
|
+ message: `Socket Client ${oldClient ? `Re-Connected` : `Connected`}. Adapter ID assigned: ${client.id}`,
|
|
payload: client
|
|
payload: client
|
|
} as EventMessage
|
|
} as EventMessage
|
|
})
|
|
})
|
|
// Resume operation
|
|
// Resume operation
|
|
- if (client.connectionState.getValue() == 'OFFLINE') {
|
|
|
|
|
|
+ // 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 (!client.connectionState) {
|
|
|
|
+ client.connectionState = new BehaviorSubject<ConnectionState>(`ONLINE`)
|
|
|
|
+ } else {
|
|
client.connectionState.next(`ONLINE`)
|
|
client.connectionState.next(`ONLINE`)
|
|
}
|
|
}
|
|
|
|
+
|
|
/* Generally, we don't need this unless in the case of being the receiver */
|
|
/* Generally, we don't need this unless in the case of being the receiver */
|
|
socket.on('message', (message: any) => {
|
|
socket.on('message', (message: any) => {
|
|
|
|
+ console.log({ message: `Message from client ${client.id}`, details: message })
|
|
eventListener.next({
|
|
eventListener.next({
|
|
id: uuidv4(),
|
|
id: uuidv4(),
|
|
event: 'New Message',
|
|
event: 'New Message',
|