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:
2025-12-03 02:20:38 +00:00
parent ee59471e14
commit 1d62c9c695
14 changed files with 3901 additions and 3007 deletions

View File

@@ -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');
}
}