🆙 Updates

- Added Test Coverage
- Fix Potential Memory Leaks
This commit is contained in:
DuckieTM
2026-01-31 13:21:59 +01:00
parent e263ce59bf
commit eb4fe80612
18 changed files with 1689 additions and 110 deletions
@@ -13,6 +13,10 @@ export class CommunicationManager implements ICommunicationManager
private _messages: IMessageConfiguration = new NitroMessages();
private _pongInterval: any = null;
private _messageEvents: IMessageEvent[] = [];
private _socketClosedCallback: () => void = null;
private _socketOpenedCallback: () => void = null;
private _socketErrorCallback: () => void = null;
private getGpu(): string {
const e = document.createElement('canvas');
@@ -88,44 +92,86 @@ export class CommunicationManager implements ICommunicationManager
public async init(): Promise<void>
{
GetEventDispatcher().addEventListener(NitroEventType.SOCKET_CLOSED, () =>
// Store callback for cleanup
this._socketClosedCallback = () =>
{
this.stopPong();
});
};
GetEventDispatcher().addEventListener(NitroEventType.SOCKET_CLOSED, this._socketClosedCallback);
return new Promise((resolve, reject) =>
{
GetEventDispatcher().addEventListener(NitroEventType.SOCKET_OPENED, () =>
// Store callback for cleanup
this._socketOpenedCallback = () =>
{
if(GetConfiguration().getValue<boolean>('system.pong.manually', false)) this.startPong();
const machineId = this.generateMachineID();
this._connection.send(new ClientHelloMessageComposer(null, null, null, null));
this._connection.send(new SSOTicketMessageComposer(GetConfiguration().getValue('sso.ticket', null), GetTickerTime()));
this._connection.send(new UniqueIDMessageComposer(machineId, '', ''));
});
};
GetEventDispatcher().addEventListener(NitroEventType.SOCKET_OPENED, this._socketOpenedCallback);
GetEventDispatcher().addEventListener(NitroEventType.SOCKET_ERROR, () =>
// Store callback for cleanup
this._socketErrorCallback = () =>
{
reject();
});
};
GetEventDispatcher().addEventListener(NitroEventType.SOCKET_ERROR, this._socketErrorCallback);
this._connection.addMessageEvent(new ClientPingEvent((event: ClientPingEvent) => this.sendPong()));
this._connection.addMessageEvent(new AuthenticatedEvent((event: AuthenticatedEvent) =>
// Store message events for cleanup
const pingEvent = new ClientPingEvent((event: ClientPingEvent) => this.sendPong());
const authEvent = new AuthenticatedEvent((event: AuthenticatedEvent) =>
{
this._connection.authenticated();
resolve();
event.connection.send(new InfoRetrieveMessageComposer());
}));
});
this._messageEvents.push(pingEvent, authEvent);
this._connection.addMessageEvent(pingEvent);
this._connection.addMessageEvent(authEvent);
this._connection.init(GetConfiguration().getValue<string>('socket.url'));
});
}
public dispose(): void
{
// Stop pong interval
this.stopPong();
// Remove event dispatcher listeners
if(this._socketClosedCallback)
{
GetEventDispatcher().removeEventListener(NitroEventType.SOCKET_CLOSED, this._socketClosedCallback);
this._socketClosedCallback = null;
}
if(this._socketOpenedCallback)
{
GetEventDispatcher().removeEventListener(NitroEventType.SOCKET_OPENED, this._socketOpenedCallback);
this._socketOpenedCallback = null;
}
if(this._socketErrorCallback)
{
GetEventDispatcher().removeEventListener(NitroEventType.SOCKET_ERROR, this._socketErrorCallback);
this._socketErrorCallback = null;
}
// Remove message events
for(const event of this._messageEvents)
{
this._connection.removeMessageEvent(event);
}
this._messageEvents = [];
}
protected startPong(): void
{
if(this._pongInterval) this.stopPong();
+46 -9
View File
@@ -17,6 +17,12 @@ export class SocketConnection implements IConnection
private _isAuthenticated: boolean = false;
// Store callbacks for cleanup
private _onOpenCallback: (event: Event) => void = null;
private _onCloseCallback: (event: Event) => void = null;
private _onErrorCallback: (event: Event) => void = null;
private _onMessageCallback: (event: MessageEvent) => void = null;
public init(socketUrl: string): void
{
if(!socketUrl || !socketUrl.length) return;
@@ -26,18 +32,49 @@ export class SocketConnection implements IConnection
this._socket = new WebSocket(socketUrl);
this._socket.binaryType = 'arraybuffer';
this._socket.addEventListener(WebSocketEventEnum.CONNECTION_OPENED, event => GetEventDispatcher().dispatchEvent(new NitroEvent(NitroEventType.SOCKET_OPENED)));
this._socket.addEventListener(WebSocketEventEnum.CONNECTION_CLOSED, event => GetEventDispatcher().dispatchEvent(new NitroEvent(NitroEventType.SOCKET_CLOSED)));
this._socket.addEventListener(WebSocketEventEnum.CONNECTION_ERROR, event => GetEventDispatcher().dispatchEvent(new NitroEvent(NitroEventType.SOCKET_ERROR)));
this._socket.addEventListener(WebSocketEventEnum.CONNECTION_MESSAGE, (event: MessageEvent) =>
// Store callbacks for cleanup
this._onOpenCallback = () => GetEventDispatcher().dispatchEvent(new NitroEvent(NitroEventType.SOCKET_OPENED));
this._onCloseCallback = () => GetEventDispatcher().dispatchEvent(new NitroEvent(NitroEventType.SOCKET_CLOSED));
this._onErrorCallback = () => GetEventDispatcher().dispatchEvent(new NitroEvent(NitroEventType.SOCKET_ERROR));
this._onMessageCallback = (event: MessageEvent) =>
{
this._dataBuffer = this.concatArrayBuffers(this._dataBuffer, event.data);
this.processReceivedData();
});
};
this._socket.addEventListener(WebSocketEventEnum.CONNECTION_OPENED, this._onOpenCallback);
this._socket.addEventListener(WebSocketEventEnum.CONNECTION_CLOSED, this._onCloseCallback);
this._socket.addEventListener(WebSocketEventEnum.CONNECTION_ERROR, this._onErrorCallback);
this._socket.addEventListener(WebSocketEventEnum.CONNECTION_MESSAGE, this._onMessageCallback);
}
public dispose(): void
{
if(this._socket)
{
// Remove all event listeners
if(this._onOpenCallback) this._socket.removeEventListener(WebSocketEventEnum.CONNECTION_OPENED, this._onOpenCallback);
if(this._onCloseCallback) this._socket.removeEventListener(WebSocketEventEnum.CONNECTION_CLOSED, this._onCloseCallback);
if(this._onErrorCallback) this._socket.removeEventListener(WebSocketEventEnum.CONNECTION_ERROR, this._onErrorCallback);
if(this._onMessageCallback) this._socket.removeEventListener(WebSocketEventEnum.CONNECTION_MESSAGE, this._onMessageCallback);
// Close socket if still open
if(this._socket.readyState === WebSocket.OPEN || this._socket.readyState === WebSocket.CONNECTING)
{
this._socket.close();
}
this._socket = null;
}
this._onOpenCallback = null;
this._onCloseCallback = null;
this._onErrorCallback = null;
this._onMessageCallback = null;
this._pendingClientMessages = [];
this._pendingServerMessages = [];
this._dataBuffer = null;
}
public ready(): void