Disable ping/pong
MODIFY
src/server/ocpp/json/JsonCentralSystemServer.ts
src/server/ocpp/json/JsonCentralSystemServer.ts
@@ -23,6 +23,8 @@ export default class JsonCentralSystemServer extends CentralSystemServer {
private wsServer: WSServer;
private jsonChargingStationClients: Map<string, JsonWSConnection>;
private jsonRestClients: Map<string, JsonRestWSConnection>;
+ private keepAliveIntervalMillis: number;
+ private keepAliveInterval: NodeJS.Timeout;
constructor(centralSystemConfig: CentralSystemConfiguration, chargingStationConfig: ChargingStationConfiguration) {
// Call parent
@@ -30,6 +32,9 @@ export default class JsonCentralSystemServer extends CentralSystemServer {
// Keep local
this.jsonChargingStationClients = new Map<string, JsonWSConnection>();
this.jsonRestClients = new Map<string, JsonRestWSConnection>();
+ // Disable Ping/Pong
+ // this.keepAliveIntervalMillis = this.centralSystemConfig.keepAliveIntervalMillis ?
+ // this.centralSystemConfig.keepAliveIntervalMillis : Constants.WS_DEFAULT_KEEP_ALIVE_MILLIS;
}
public start(): void {
@@ -155,6 +160,25 @@ export default class JsonCentralSystemServer extends CentralSystemServer {
ws.close(WebSocketCloseEventStatusCode.CLOSE_UNSUPPORTED, error.message);
}
});
+ // Keep alive WebSocket connection
+ if (this.keepAliveIntervalMillis > 0 && !this.keepAliveInterval) {
+ this.keepAliveInterval = setInterval((): void => {
+ for (const jsonWSConnection of this.jsonChargingStationClients.values()) {
+ if (!jsonWSConnection.isConnectionAlive) {
+ void Logging.logError({
+ tenantID: jsonWSConnection.getTenantID(),
+ source: jsonWSConnection.getChargingStationID(),
+ action: ServerAction.WS_JSON_CONNECTION_CLOSED,
+ module: MODULE_NAME, method: 'createWSServer',
+ message: `WebSocket does not respond to ping (IP: ${jsonWSConnection.getClientIP().toString()}), terminating`
+ });
+ jsonWSConnection.getWSConnection().terminate();
+ }
+ jsonWSConnection.isConnectionAlive = false;
+ jsonWSConnection.getWSConnection().ping((): void => { });
+ }
+ }, this.keepAliveIntervalMillis);
+ }
}
}

MODIFY
src/server/ocpp/json/JsonWSConnection.ts
src/server/ocpp/json/JsonWSConnection.ts
@@ -21,6 +21,7 @@ import http from 'http';
const MODULE_NAME = 'JsonWSConnection';
export default class JsonWSConnection extends WSConnection {
+ public isConnectionAlive: boolean;
private chargingStationClient: ChargingStationClient;
private chargingStationService: JsonChargingStationService;
private headers: OCPPHeader;
@@ -48,6 +49,7 @@ export default class JsonWSConnection extends WSConnection {
message: `Protocol ${wsConnection.protocol} not supported`
});
}
+ this.isConnectionAlive = true;
// Handle Socket ping
this.getWSConnection().on('ping', this.onPing.bind(this));
// Handle Socket pong
@@ -128,6 +130,7 @@ export default class JsonWSConnection extends WSConnection {
}
public async onPong(): Promise<void> {
+ this.isConnectionAlive = true;
void Logging.logDebug({
tenantID: this.getTenantID(),
source: this.getChargingStationID(),

MODIFY
src/types/configuration/CentralSystemConfiguration.ts
src/types/configuration/CentralSystemConfiguration.ts
@@ -8,5 +8,5 @@ export enum CentralSystemImplementation {
export default interface CentralSystemConfiguration extends CentralSystemServerConfiguration {
implementation: CentralSystemImplementation;
debug: boolean;
- keepaliveinterval?: number;
+ keepAliveIntervalMillis?: number;
}

MODIFY
src/utils/Constants.ts
src/utils/Constants.ts
@@ -282,6 +282,7 @@ export default class Constants {
public static readonly ANONYMIZED_VALUE = '####';
+ public static readonly WS_DEFAULT_KEEP_ALIVE_MILLIS = 180 * 1000;
public static readonly WS_RECONNECT_DISABLED = 0;
public static readonly WS_RECONNECT_UNLIMITED = -1;
public static readonly WS_DEFAULT_RECONNECT_MAX_RETRIES = -1;

Disable ping/pong