Skip to content

Commit db22679

Browse files
committed
Merge branch 'master' into breaking-changes
2 parents 7e3b6c5 + 3d8ea6b commit db22679

File tree

4 files changed

+35
-21
lines changed

4 files changed

+35
-21
lines changed

lib/client.js

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const { randomUUID} = require('crypto');
22
const { EventEmitter, once } = require('events');
33
const { setTimeout } = require('timers/promises');
4+
const { setTimeout: setTimeoutCb } = require('timers');
45
const WebSocket = require('ws');
56
const { ExponentialStrategy } = require('backoff');
67
const { CONNECTING, OPEN, CLOSING, CLOSED } = WebSocket;
@@ -30,7 +31,6 @@ class RPCClient extends EventEmitter {
3031
this._keepAliveAbortController = undefined;
3132
this._pendingPingResponse = false;
3233
this._lastPingTime = 0;
33-
this._skipNextPing = false;
3434
this._closePromise = undefined;
3535
this._protocolOptions = [];
3636
this._protocol = undefined;
@@ -407,12 +407,12 @@ class RPCClient extends EventEmitter {
407407
ws.on('error', err => this.emit('socketError', err));
408408
ws.on('ping', () => {
409409
if (this._options.deferPingsOnActivity) {
410-
this._skipNextPing = true;
410+
this._deferNextPing();
411411
}
412412
});
413413
ws.on('pong', () => {
414414
if (this._options.deferPingsOnActivity) {
415-
this._skipNextPing = true;
415+
this._deferNextPing();
416416
}
417417
this._pendingPingResponse = false;
418418
const rtt = Date.now() - this._lastPingTime;
@@ -566,10 +566,24 @@ class RPCClient extends EventEmitter {
566566
return this._connectPromise;
567567
}
568568

569+
_deferNextPing() {
570+
if (!this._nextPingTimeout) {
571+
return;
572+
}
573+
574+
this._nextPingTimeout.refresh();
575+
}
576+
569577
async _keepAlive() {
570578
// abort any previously running keepAlive
571579
this._keepAliveAbortController?.abort();
572580

581+
const timerEmitter = new EventEmitter();
582+
const nextPingTimeout = setTimeoutCb(()=>{
583+
timerEmitter.emit('next')
584+
}, this._options.pingIntervalMs);
585+
this._nextPingTimeout = nextPingTimeout;
586+
573587
try {
574588
if (this._state !== OPEN) {
575589
// don't start pinging if connection not open
@@ -583,20 +597,16 @@ class RPCClient extends EventEmitter {
583597

584598
// setup new abort controller
585599
this._keepAliveAbortController = new AbortController();
586-
600+
587601
while (true) {
588-
await setTimeout(this._options.pingIntervalMs, undefined, {signal: this._keepAliveAbortController.signal});
589-
602+
await once(timerEmitter, 'next', {signal: this._keepAliveAbortController.signal}),
603+
this._keepAliveAbortController.signal.throwIfAborted();
604+
590605
if (this._state !== OPEN) {
591606
// keepalive no longer required
592607
break;
593608
}
594609

595-
if (this._skipNextPing) {
596-
this._skipNextPing = false;
597-
continue;
598-
}
599-
600610
if (this._pendingPingResponse) {
601611
// we didn't get a response to our last ping
602612
throw Error("Ping timeout");
@@ -605,13 +615,17 @@ class RPCClient extends EventEmitter {
605615
this._lastPingTime = Date.now();
606616
this._pendingPingResponse = true;
607617
this._ws.ping();
618+
nextPingTimeout.refresh();
608619
}
609620

610621
} catch (err) {
622+
// console.log('keepalive failed', err);
611623
if (err.name !== 'AbortError') {
612624
// throws on ws.ping() error
613625
this._ws.terminate();
614626
}
627+
} finally {
628+
clearTimeout(nextPingTimeout);
615629
}
616630
}
617631

@@ -657,7 +671,7 @@ class RPCClient extends EventEmitter {
657671

658672
_onMessage(buffer) {
659673
if (this._options.deferPingsOnActivity) {
660-
this._skipNextPing = true;
674+
this._deferNextPing();
661675
}
662676

663677
const message = buffer.toString('utf8');

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ocpp-rpc",
3-
"version": "1.10.2",
3+
"version": "1.10.3",
44
"description": "A client & server implementation of the WAMP-like RPC-over-websocket system defined in the OCPP protcols (e.g. OCPP1.6-J and OCPP2.0.1).",
55
"main": "index.js",
66
"scripts": {

test/client.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2479,8 +2479,8 @@ describe('RPCClient', function(){
24792479
withClient: async (client) => {
24802480
// send some rapid activity from the server
24812481
for (let i = 0; i < 4; i++) {
2482-
await client.call('Echo', {});
24832482
await setTimeout(25);
2483+
await client.call('Echo', {});
24842484
}
24852485
await client.close();
24862486
}
@@ -2490,7 +2490,7 @@ describe('RPCClient', function(){
24902490
identity: 'X',
24912491
reconnect: false,
24922492
deferPingsOnActivity: true,
2493-
pingIntervalMs: 40
2493+
pingIntervalMs: 50
24942494
});
24952495
cli.handle('Echo', async ({params}) => {
24962496
return params;
@@ -2517,8 +2517,8 @@ describe('RPCClient', function(){
25172517
withClient: async (client) => {
25182518
// send some rapid activity from the server
25192519
for (let i = 0; i < 4; i++) {
2520-
await client.call('Echo', {});
25212520
await setTimeout(25);
2521+
await client.call('Echo', {});
25222522
}
25232523
await client.close();
25242524
}
@@ -2528,7 +2528,7 @@ describe('RPCClient', function(){
25282528
identity: 'X',
25292529
reconnect: false,
25302530
deferPingsOnActivity: false,
2531-
pingIntervalMs: 40
2531+
pingIntervalMs: 50
25322532
});
25332533
cli.handle('Echo', async ({params}) => {
25342534
return params;
@@ -2567,7 +2567,7 @@ describe('RPCClient', function(){
25672567
identity: 'X',
25682568
reconnect: false,
25692569
deferPingsOnActivity: true,
2570-
pingIntervalMs: 40
2570+
pingIntervalMs: 50
25712571
});
25722572

25732573
// count how many times we ping the server
@@ -2602,7 +2602,7 @@ describe('RPCClient', function(){
26022602
identity: 'X',
26032603
reconnect: false,
26042604
deferPingsOnActivity: false,
2605-
pingIntervalMs: 40
2605+
pingIntervalMs: 50
26062606
});
26072607

26082608
// count how many times we ping the server

0 commit comments

Comments
 (0)