Skip to content

Commit 0bdc3dc

Browse files
committed
Merge branch 'master' into breaking-changes
2 parents e04d44b + 0132274 commit 0bdc3dc

File tree

7 files changed

+178
-79
lines changed

7 files changed

+178
-79
lines changed

lib/client.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,15 @@ class RPCClient extends EventEmitter {
405405
_attachWebsocket(ws, leadMsgBuffer) {
406406
ws.once('close', (code, reason) => this._handleDisconnect({code, reason}));
407407
ws.on('error', err => this.emit('socketError', err));
408+
ws.on('ping', () => {
409+
if (this._options.deferPingsOnActivity) {
410+
this._skipNextPing = true;
411+
}
412+
});
408413
ws.on('pong', () => {
414+
if (this._options.deferPingsOnActivity) {
415+
this._skipNextPing = true;
416+
}
409417
this._pendingPingResponse = false;
410418
const rtt = Date.now() - this._lastPingTime;
411419
this.emit('ping', {rtt});

lib/server.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ class RPCServer extends EventEmitter {
237237
callConcurrency: this._options.callConcurrency,
238238
strictMode: this._options.strictMode,
239239
strictModeValidators: this._options.strictModeValidators,
240+
maxBadMessages: this._options.maxBadMessages,
240241
protocols: this._options.protocols,
241242
}, {
242243
ws: websocket,

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.0",
3+
"version": "1.10.1",
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: 87 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2472,16 +2472,14 @@ describe('RPCClient', function(){
24722472
});
24732473

24742474

2475-
it('should skip pinging client if other activity received with option deferPingsOnActivity', async () => {
2475+
it('should not auto-ping server if other activity received with option deferPingsOnActivity', async () => {
24762476

24772477
let pings = 0;
24782478
const {endpoint, close, server} = await createServer({}, {
24792479
withClient: async (client) => {
2480-
client.handle('Echo', async ({params}) => {
2481-
return params;
2482-
});
2480+
// send some rapid activity from the server
24832481
for (let i = 0; i < 4; i++) {
2484-
await cli.call('Echo', {});
2482+
await client.call('Echo', {});
24852483
await setTimeout(25);
24862484
}
24872485
await client.close();
@@ -2494,29 +2492,32 @@ describe('RPCClient', function(){
24942492
deferPingsOnActivity: true,
24952493
pingIntervalMs: 40
24962494
});
2495+
cli.handle('Echo', async ({params}) => {
2496+
return params;
2497+
});
24972498

2499+
// count how many times we ping the server
24982500
cli.on('ping', () => {++pings;});
24992501

25002502
try {
25012503
await cli.connect();
25022504
await once(cli, 'close');
2505+
// we shouldn't have pinged, because of the activity sent from the server
25032506
assert.equal(pings, 0);
25042507
} finally {
25052508
await cli.close();
25062509
close();
25072510
}
25082511
});
25092512

2510-
it('should allow pinging client if other activity received without option deferPingsOnActivity', async () => {
2513+
it('should auto-ping server even if other activity received without option deferPingsOnActivity', async () => {
25112514

25122515
let pings = 0;
25132516
const {endpoint, close, server} = await createServer({}, {
25142517
withClient: async (client) => {
2515-
client.handle('Echo', async ({params}) => {
2516-
return params;
2517-
});
2518+
// send some rapid activity from the server
25182519
for (let i = 0; i < 4; i++) {
2519-
await cli.call('Echo', {});
2520+
await client.call('Echo', {});
25202521
await setTimeout(25);
25212522
}
25222523
await client.close();
@@ -2529,12 +2530,88 @@ describe('RPCClient', function(){
25292530
deferPingsOnActivity: false,
25302531
pingIntervalMs: 40
25312532
});
2533+
cli.handle('Echo', async ({params}) => {
2534+
return params;
2535+
});
2536+
2537+
// count how many times we ping the server
2538+
cli.on('ping', () => {++pings;});
2539+
2540+
try {
2541+
await cli.connect();
2542+
await once(cli, 'close');
2543+
// we should have pinged multiple times, despite the activity sent from the server
2544+
assert.ok(pings > 0);
2545+
} finally {
2546+
await cli.close();
2547+
close();
2548+
}
2549+
});
2550+
2551+
2552+
it('should not auto-ping server if ping received with option deferPingsOnActivity', async () => {
2553+
2554+
let pings = 0;
2555+
const {endpoint, close, server} = await createServer({
2556+
pingIntervalMs: 25,
2557+
deferPingsOnActivity: false,
2558+
}, {
2559+
withClient: async (client) => {
2560+
// keep the client lingering long enough for the server to send several pings
2561+
await setTimeout(110);
2562+
await client.close();
2563+
}
2564+
});
2565+
const cli = new RPCClient({
2566+
endpoint,
2567+
identity: 'X',
2568+
reconnect: false,
2569+
deferPingsOnActivity: true,
2570+
pingIntervalMs: 40
2571+
});
2572+
2573+
// count how many times we ping the server
2574+
cli.on('ping', () => {++pings;});
2575+
2576+
try {
2577+
await cli.connect();
2578+
await once(cli, 'close');
2579+
// we shouldn't have pinged, because of the activity sent from the server
2580+
assert.equal(pings, 0);
2581+
} finally {
2582+
await cli.close();
2583+
close();
2584+
}
2585+
});
2586+
2587+
it('should auto-ping server even if ping received without option deferPingsOnActivity', async () => {
2588+
2589+
let pings = 0;
2590+
const {endpoint, close, server} = await createServer({
2591+
pingIntervalMs: 25,
2592+
deferPingsOnActivity: false,
2593+
}, {
2594+
withClient: async (client) => {
2595+
// keep the client lingering long enough for the server to send several pings
2596+
await setTimeout(110);
2597+
await client.close();
2598+
}
2599+
});
2600+
const cli = new RPCClient({
2601+
endpoint,
2602+
identity: 'X',
2603+
reconnect: false,
2604+
deferPingsOnActivity: false,
2605+
pingIntervalMs: 40
2606+
});
25322607

2608+
// count how many times we ping the server
25332609
cli.on('ping', () => {++pings;});
25342610

25352611
try {
25362612
await cli.connect();
25372613
await once(cli, 'close');
2614+
// we should have pinged multiple times, despite the activity sent from the server
25382615
assert.ok(pings > 0);
25392616
} finally {
25402617
await cli.close();

test/server-client.js

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,38 @@
11
const assert = require('assert/strict');
2-
const http = require('http');
32
const { once } = require('events');
43
const RPCClient = require("../lib/client");
5-
const { TimeoutError } = require('../lib/errors');
64
const RPCServer = require("../lib/server");
75
const { setTimeout } = require('timers/promises');
8-
const {CLOSING, CLOSED, CONNECTING} = RPCClient;
6+
const { createValidator } = require('../lib/validator');
7+
8+
function getEchoValidator() {
9+
return createValidator('echo1.0', [
10+
{
11+
"$schema": "http://json-schema.org/draft-07/schema",
12+
"$id": "urn:Echo.req",
13+
"type": "object",
14+
"properties": {
15+
"val": {
16+
"type": "string"
17+
}
18+
},
19+
"additionalProperties": false,
20+
"required": ["val"]
21+
},
22+
{
23+
"$schema": "http://json-schema.org/draft-07/schema",
24+
"$id": "urn:Echo.conf",
25+
"type": "object",
26+
"properties": {
27+
"val": {
28+
"type": "string"
29+
}
30+
},
31+
"additionalProperties": false,
32+
"required": ["val"]
33+
}
34+
]);
35+
}
936

1037
describe('RPCServerClient', function(){
1138
this.timeout(500);
@@ -61,4 +88,53 @@ describe('RPCServerClient', function(){
6188

6289
});
6390

91+
it('should inherit server options', async () => {
92+
93+
const inheritableOptions = {
94+
callTimeoutMs: Math.floor(Math.random()*99999),
95+
pingIntervalMs: Math.floor(Math.random()*99999),
96+
deferPingsOnActivity: true,
97+
respondWithDetailedErrors: true,
98+
callConcurrency: Math.floor(Math.random()*99999),
99+
strictMode: true,
100+
strictModeValidators: [
101+
getEchoValidator(),
102+
],
103+
maxBadMessages: Math.floor(Math.random()*99999),
104+
};
105+
106+
const server = new RPCServer({
107+
protocols: ['echo1.0'],
108+
...inheritableOptions
109+
});
110+
const httpServer = await server.listen(0);
111+
const port = httpServer.address().port;
112+
const endpoint = `ws://localhost:${port}`;
113+
114+
const test = new Promise((resolve, reject) => {
115+
server.on('client', cli => {
116+
const optionKeys = Object.keys(inheritableOptions);
117+
for (const optionKey of optionKeys) {
118+
const option = cli._options[optionKey];
119+
if (option !== inheritableOptions[optionKey]) {
120+
reject(Error(`RPCServerClient did not inherit option "${optionKey}" from RPCServer`));
121+
}
122+
}
123+
resolve();
124+
});
125+
});
126+
127+
const cli = new RPCClient({
128+
endpoint,
129+
identity: 'X',
130+
reconnect: false,
131+
deferPingsOnActivity: false,
132+
pingIntervalMs: 40
133+
});
134+
await cli.connect();
135+
await cli.close();
136+
await server.close();
137+
await test;
138+
});
139+
64140
});

test/server.js

Lines changed: 0 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -767,69 +767,6 @@ describe('RPCServer', function(){
767767
}
768768
});
769769

770-
it('should skip pinging client if other activity received with option deferPingsOnActivity', async () => {
771-
772-
let pings = 0;
773-
const {endpoint, close, server} = await createServer({
774-
pingIntervalMs: 40,
775-
deferPingsOnActivity: true,
776-
}, {
777-
withClient: async (client) => {
778-
client.on('ping', () => {++pings;});
779-
}
780-
});
781-
const cli = new RPCClient({
782-
endpoint,
783-
identity: 'X',
784-
reconnect: false,
785-
});
786-
787-
try {
788-
await cli.connect();
789-
for (let i = 0; i < 4; i++) {
790-
await cli.call('Echo', {});
791-
await setTimeout(25);
792-
}
793-
await cli.close();
794-
assert.equal(pings, 0);
795-
} finally {
796-
await cli.close();
797-
close();
798-
}
799-
});
800-
801-
it('should allow pinging client if other activity received without option deferPingsOnActivity', async () => {
802-
803-
let pings = 0;
804-
const {endpoint, close, server} = await createServer({
805-
pingIntervalMs: 40,
806-
deferPingsOnActivity: false,
807-
}, {
808-
withClient: async (client) => {
809-
client.on('ping', () => {++pings;});
810-
}
811-
});
812-
const cli = new RPCClient({
813-
endpoint,
814-
identity: 'X',
815-
reconnect: false,
816-
});
817-
818-
try {
819-
await cli.connect();
820-
for (let i = 0; i < 4; i++) {
821-
await cli.call('Echo', {});
822-
await setTimeout(25);
823-
}
824-
await cli.close();
825-
assert.ok(pings > 0);
826-
} finally {
827-
await cli.close();
828-
close();
829-
}
830-
});
831-
832-
833770
it('should reject non-websocket requests with a 404', async () => {
834771

835772
const {port, close, server} = await createServer();

0 commit comments

Comments
 (0)