Refactor smartsocket implementation for improved WebSocket handling and message protocol
- Updated test files to use new testing library and reduced test cycles for efficiency. - Removed dependency on smartexpress and integrated direct WebSocket handling. - Enhanced Smartsocket and SmartsocketClient classes to support new message types and authentication flow. - Implemented a new message interface for structured communication between client and server. - Added external server support for smartserve with appropriate WebSocket hooks. - Improved connection management and error handling in SocketConnection and SocketRequest classes. - Cleaned up code and removed deprecated socket.io references in favor of native WebSocket.
This commit is contained in:
@@ -26,7 +26,6 @@ export class Smartsocket {
|
||||
public alias: string;
|
||||
public smartenv = new plugins.smartenv.Smartenv();
|
||||
public options: ISmartsocketConstructorOptions;
|
||||
public io: pluginsTyped.socketIo.Server;
|
||||
public socketConnections = new plugins.lik.ObjectMap<SocketConnection>();
|
||||
public socketFunctions = new plugins.lik.ObjectMap<SocketFunction<any>>();
|
||||
public socketRequests = new plugins.lik.ObjectMap<SocketRequest<any>>();
|
||||
@@ -40,26 +39,62 @@ export class Smartsocket {
|
||||
this.alias = plugins.isounique.uni(this.options.alias);
|
||||
}
|
||||
|
||||
public async setExternalServer(serverType: 'smartexpress', serverArg: any) {
|
||||
await this.socketServer.setExternalServer(serverType, serverArg);
|
||||
/**
|
||||
* Set an external server (smartserve) for WebSocket handling
|
||||
*/
|
||||
public async setExternalServer(
|
||||
serverType: 'smartserve',
|
||||
serverArg: any,
|
||||
websocketHooks?: pluginsTyped.ISmartserveWebSocketHooks
|
||||
) {
|
||||
await this.socketServer.setExternalServer(serverType, serverArg, websocketHooks);
|
||||
}
|
||||
|
||||
/**
|
||||
* starts smartsocket
|
||||
*/
|
||||
public async start() {
|
||||
const socketIoModule = await this.smartenv.getSafeNodeModule('socket.io');
|
||||
this.io = new socketIoModule.Server(await this.socketServer.getServerForSocketIo(), {
|
||||
cors: {
|
||||
allowedHeaders: '*',
|
||||
methods: '*',
|
||||
origin: '*',
|
||||
},
|
||||
});
|
||||
await this.socketServer.start();
|
||||
this.io.on('connection', (socketArg) => {
|
||||
this._handleSocketConnection(socketArg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a new WebSocket connection
|
||||
* Called by SocketServer when a new connection is established
|
||||
*/
|
||||
public async handleNewConnection(socket: WebSocket | pluginsTyped.ws.WebSocket) {
|
||||
const socketConnection: SocketConnection = new SocketConnection({
|
||||
alias: undefined,
|
||||
authenticated: false,
|
||||
side: 'server',
|
||||
smartsocketHost: this,
|
||||
socket: socket,
|
||||
});
|
||||
|
||||
logger.log('info', 'Socket connected. Trying to authenticate...');
|
||||
this.socketConnections.add(socketConnection);
|
||||
|
||||
// Handle disconnection
|
||||
const handleClose = () => {
|
||||
this.socketConnections.remove(socketConnection);
|
||||
socketConnection.eventSubject.next('disconnected');
|
||||
};
|
||||
|
||||
socket.addEventListener('close', handleClose);
|
||||
socket.addEventListener('error', handleClose);
|
||||
|
||||
try {
|
||||
await socketConnection.authenticate();
|
||||
await socketConnection.listenToFunctionRequests();
|
||||
|
||||
// Signal that the server is ready
|
||||
socketConnection.sendMessage({
|
||||
type: 'serverReady',
|
||||
payload: {},
|
||||
});
|
||||
} catch (err) {
|
||||
logger.log('warn', `Authentication failed: ${err}`);
|
||||
this.socketConnections.remove(socketConnection);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,10 +112,9 @@ export class Smartsocket {
|
||||
}
|
||||
});
|
||||
this.socketConnections.wipe();
|
||||
this.io.close();
|
||||
|
||||
// stop the corresponging server
|
||||
this.socketServer.stop();
|
||||
// stop the corresponding server
|
||||
await this.socketServer.stop();
|
||||
}
|
||||
|
||||
// communication
|
||||
@@ -110,28 +144,4 @@ export class Smartsocket {
|
||||
public addSocketFunction(socketFunction: SocketFunction<any>) {
|
||||
this.socketFunctions.add(socketFunction);
|
||||
}
|
||||
|
||||
/**
|
||||
* the standard handler for new socket connections
|
||||
*/
|
||||
private async _handleSocketConnection(socketArg: pluginsTyped.socketIo.Socket) {
|
||||
const socketConnection: SocketConnection = new SocketConnection({
|
||||
alias: undefined,
|
||||
authenticated: false,
|
||||
side: 'server',
|
||||
smartsocketHost: this,
|
||||
socket: socketArg,
|
||||
});
|
||||
logger.log('info', 'Socket connected. Trying to authenticate...');
|
||||
this.socketConnections.add(socketConnection);
|
||||
const disconnectSubscription = socketConnection.eventSubject.subscribe((eventArg) => {
|
||||
if (eventArg === 'disconnected') {
|
||||
this.socketConnections.remove(socketConnection);
|
||||
disconnectSubscription.unsubscribe();
|
||||
}
|
||||
});
|
||||
await socketConnection.authenticate();
|
||||
await socketConnection.listenToFunctionRequests();
|
||||
await socketConnection.socket.emit('serverFullyReactive');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user