feat(SmartsocketClient): Improve client reconnection logic with exponential backoff and jitter; update socket.io and @types/node dependencies
This commit is contained in:
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* autocreated commitinfo by @pushrocks/commitinfo
|
||||
* autocreated commitinfo by @push.rocks/commitinfo
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@push.rocks/smartsocket',
|
||||
version: '2.0.27',
|
||||
version: '2.1.0',
|
||||
description: 'Provides easy and secure websocket communication mechanisms, including server and client implementation, function call routing, connection management, and tagging.'
|
||||
}
|
||||
|
@ -18,6 +18,9 @@ export interface ISmartsocketClientOptions {
|
||||
url: string;
|
||||
alias: string; // an alias makes it easier to identify this client in a multo client environment
|
||||
autoReconnect?: boolean;
|
||||
maxRetries?: number; // maximum number of reconnection attempts
|
||||
initialBackoffDelay?: number; // initial backoff delay in ms
|
||||
maxBackoffDelay?: number; // maximum backoff delay in ms
|
||||
}
|
||||
|
||||
export class SmartsocketClient {
|
||||
@ -32,6 +35,11 @@ export class SmartsocketClient {
|
||||
public serverUrl: string;
|
||||
public serverPort: number;
|
||||
public autoReconnect: boolean;
|
||||
public maxRetries: number;
|
||||
public initialBackoffDelay: number;
|
||||
public maxBackoffDelay: number;
|
||||
public currentRetryCount = 0;
|
||||
public currentBackoffDelay: number;
|
||||
|
||||
// status handling
|
||||
public eventSubject = new plugins.smartrx.rxjs.Subject<interfaces.TConnectionStatus>();
|
||||
@ -79,6 +87,10 @@ export class SmartsocketClient {
|
||||
this.serverUrl = optionsArg.url;
|
||||
this.serverPort = optionsArg.port;
|
||||
this.autoReconnect = optionsArg.autoReconnect;
|
||||
this.maxRetries = optionsArg.maxRetries ?? 100; // Default to 100 retries
|
||||
this.initialBackoffDelay = optionsArg.initialBackoffDelay ?? 1000; // Default to 1 second
|
||||
this.maxBackoffDelay = optionsArg.maxBackoffDelay ?? 60000; // Default to 1 minute
|
||||
this.currentBackoffDelay = this.initialBackoffDelay;
|
||||
}
|
||||
|
||||
public addSocketFunction(socketFunction: SocketFunction<any>) {
|
||||
@ -89,6 +101,10 @@ export class SmartsocketClient {
|
||||
* connect the client to the server
|
||||
*/
|
||||
public async connect() {
|
||||
// Reset retry counters on new connection attempt
|
||||
this.currentRetryCount = 0;
|
||||
this.currentBackoffDelay = this.initialBackoffDelay;
|
||||
|
||||
const done = plugins.smartpromise.defer();
|
||||
const smartenvInstance = new plugins.smartenv.Smartenv();
|
||||
const socketIoClient: any = await smartenvInstance.getEnvAwareModule({
|
||||
@ -216,8 +232,27 @@ export class SmartsocketClient {
|
||||
|
||||
if (this.autoReconnect && useAutoReconnectSetting && this.eventStatus !== 'connecting') {
|
||||
this.updateStatus('connecting');
|
||||
console.log('debounced reconnect!');
|
||||
await plugins.smartdelay.delayForRandom(10000, 20000);
|
||||
|
||||
// Check if we've exceeded the maximum number of retries
|
||||
if (this.currentRetryCount >= this.maxRetries) {
|
||||
logger.log('warn', `Maximum reconnection attempts (${this.maxRetries}) reached. Giving up.`);
|
||||
this.disconnectRunning = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Increment retry counter
|
||||
this.currentRetryCount++;
|
||||
|
||||
// Calculate backoff with jitter (±20% randomness)
|
||||
const jitter = this.currentBackoffDelay * 0.2 * (Math.random() * 2 - 1);
|
||||
const delay = Math.min(this.currentBackoffDelay + jitter, this.maxBackoffDelay);
|
||||
|
||||
logger.log('info', `Reconnect attempt ${this.currentRetryCount}/${this.maxRetries} in ${Math.round(delay)}ms`);
|
||||
|
||||
// Apply exponential backoff for next time (doubling with each attempt)
|
||||
this.currentBackoffDelay = Math.min(this.currentBackoffDelay * 2, this.maxBackoffDelay);
|
||||
|
||||
await plugins.smartdelay.delayFor(delay);
|
||||
this.disconnectRunning = false;
|
||||
await this.connect();
|
||||
} else {
|
||||
@ -230,6 +265,8 @@ export class SmartsocketClient {
|
||||
*/
|
||||
public async stop() {
|
||||
this.autoReconnect = false;
|
||||
this.currentRetryCount = 0;
|
||||
this.currentBackoffDelay = this.initialBackoffDelay;
|
||||
await this.disconnect();
|
||||
}
|
||||
|
||||
@ -262,5 +299,19 @@ export class SmartsocketClient {
|
||||
this.eventSubject.next(statusArg);
|
||||
}
|
||||
this.eventStatus = statusArg;
|
||||
|
||||
// Reset reconnection state when connection is successful
|
||||
if (statusArg === 'connected') {
|
||||
this.currentRetryCount = 0;
|
||||
this.currentBackoffDelay = this.initialBackoffDelay;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the reconnection state
|
||||
*/
|
||||
public resetReconnectionState() {
|
||||
this.currentRetryCount = 0;
|
||||
this.currentBackoffDelay = this.initialBackoffDelay;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user