From 0f939e594bd2781acd621e4f6c79ac5d02e4b68c Mon Sep 17 00:00:00 2001 From: Javad Jazandari Date: Tue, 24 May 2022 19:31:24 +0430 Subject: [PATCH 1/8] close broken webSocket connection in LiveQuery server --- src/LiveQuery/ParseWebSocketServer.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/LiveQuery/ParseWebSocketServer.js b/src/LiveQuery/ParseWebSocketServer.js index a0d1e9891f..c5cad9a74c 100644 --- a/src/LiveQuery/ParseWebSocketServer.js +++ b/src/LiveQuery/ParseWebSocketServer.js @@ -14,6 +14,10 @@ export class ParseWebSocketServer { logger.info('Parse LiveQuery Server started running'); }; wss.onConnection = ws => { + ws.isAlive = true; + ws.on('pong', () => { + this.isAlive = true; + }); ws.on('error', error => { logger.error(error.message); logger.error(inspect(ws, false)); @@ -21,10 +25,12 @@ export class ParseWebSocketServer { onConnect(new ParseWebSocket(ws)); // Send ping to client periodically const pingIntervalId = setInterval(() => { - if (ws.readyState == ws.OPEN) { + if (ws.isAlive) { ws.ping(); + ws.isAlive = false; } else { clearInterval(pingIntervalId); + ws.terminate(); } }, config.websocketTimeout || 10 * 1000); }; From c429efb6a6d5d2002f102422d320773c576f217b Mon Sep 17 00:00:00 2001 From: Javad Jazandari Date: Sat, 28 May 2022 13:02:37 +0430 Subject: [PATCH 2/8] write test for handle broken connection --- spec/ParseWebSocketServer.spec.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/spec/ParseWebSocketServer.spec.js b/spec/ParseWebSocketServer.spec.js index 6050ea0f2f..68e553eaf9 100644 --- a/spec/ParseWebSocketServer.spec.js +++ b/spec/ParseWebSocketServer.spec.js @@ -23,6 +23,7 @@ describe('ParseWebSocketServer', function () { ws.readyState = 0; ws.OPEN = 0; ws.ping = jasmine.createSpy('ping'); + ws.terminate = () => {}; parseWebSocketServer.onConnection(ws); @@ -75,6 +76,35 @@ describe('ParseWebSocketServer', function () { expect(wssError).toBe('Invalid Packet'); }); + fit('can handle broken connection', function (done) { + const onConnectCallback = jasmine.createSpy('onConnectCallback'); + const http = require('http'); + const server = http.createServer(); + const parseWebSocketServer = new ParseWebSocketServer(server, onConnectCallback, { + websocketTimeout: 5, + }).server; + const ws = new EventEmitter(); + ws.readyState = 0; + ws.OPEN = 0; + ws.ping = jasmine.createSpy('ping'); + ws.terminate = jasmine.createSpy('terminate'); + + parseWebSocketServer.onConnection(ws); + + // Make sure callback is called + expect(onConnectCallback).toHaveBeenCalled(); + // Make sure we ping to the client + setTimeout(function () { + expect(ws.ping).toHaveBeenCalled(); + setTimeout(function () { + //make sure we close the connection after timeout cause we don't answer the ping + expect(ws.terminate).toHaveBeenCalled(); + server.close(); + done(); + }, 10); + }, 10); + }); + afterEach(function () { jasmine.restoreLibrary('ws', 'Server'); }); From 307a68409f24e94d116b698e516cb36fbf3aaeab Mon Sep 17 00:00:00 2001 From: Javad Jazandari Date: Sat, 28 May 2022 13:36:05 +0430 Subject: [PATCH 3/8] change all fit to it --- spec/ParseWebSocketServer.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/ParseWebSocketServer.spec.js b/spec/ParseWebSocketServer.spec.js index 68e553eaf9..cce0412f91 100644 --- a/spec/ParseWebSocketServer.spec.js +++ b/spec/ParseWebSocketServer.spec.js @@ -76,7 +76,7 @@ describe('ParseWebSocketServer', function () { expect(wssError).toBe('Invalid Packet'); }); - fit('can handle broken connection', function (done) { + it('can handle broken connection', function (done) { const onConnectCallback = jasmine.createSpy('onConnectCallback'); const http = require('http'); const server = http.createServer(); From 7154fd8facebe0341ee9404b871efd4685118fd6 Mon Sep 17 00:00:00 2001 From: Javad Jazandari Date: Sat, 28 May 2022 14:31:54 +0430 Subject: [PATCH 4/8] change test function name to closes interrupted connection --- spec/ParseWebSocketServer.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/ParseWebSocketServer.spec.js b/spec/ParseWebSocketServer.spec.js index cce0412f91..2f49615e4f 100644 --- a/spec/ParseWebSocketServer.spec.js +++ b/spec/ParseWebSocketServer.spec.js @@ -76,7 +76,7 @@ describe('ParseWebSocketServer', function () { expect(wssError).toBe('Invalid Packet'); }); - it('can handle broken connection', function (done) { + it('closes interrupted connection', function (done) { const onConnectCallback = jasmine.createSpy('onConnectCallback'); const http = require('http'); const server = http.createServer(); From 513486465ccf74ca967f91a28df8c5ddcee28ba0 Mon Sep 17 00:00:00 2001 From: Javad Jazandari Date: Sat, 28 May 2022 17:54:29 +0430 Subject: [PATCH 5/8] change test function to async --- spec/ParseWebSocketServer.spec.js | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/spec/ParseWebSocketServer.spec.js b/spec/ParseWebSocketServer.spec.js index 2f49615e4f..d5ef167a4a 100644 --- a/spec/ParseWebSocketServer.spec.js +++ b/spec/ParseWebSocketServer.spec.js @@ -76,7 +76,7 @@ describe('ParseWebSocketServer', function () { expect(wssError).toBe('Invalid Packet'); }); - it('closes interrupted connection', function (done) { + it('closes interrupted connection', async () => { const onConnectCallback = jasmine.createSpy('onConnectCallback'); const http = require('http'); const server = http.createServer(); @@ -93,16 +93,13 @@ describe('ParseWebSocketServer', function () { // Make sure callback is called expect(onConnectCallback).toHaveBeenCalled(); + await new Promise(resolve => setTimeout(resolve, 10)); // Make sure we ping to the client - setTimeout(function () { - expect(ws.ping).toHaveBeenCalled(); - setTimeout(function () { - //make sure we close the connection after timeout cause we don't answer the ping - expect(ws.terminate).toHaveBeenCalled(); - server.close(); - done(); - }, 10); - }, 10); + expect(ws.ping).toHaveBeenCalled(); + await new Promise(resolve => setTimeout(resolve, 10)); + // make sure connection close after we didn't answer the ping on time + expect(ws.terminate).toHaveBeenCalled(); + server.close(); }); afterEach(function () { From 509039009f1907ec0348064e0fcb9a8ccc925f20 Mon Sep 17 00:00:00 2001 From: Javad Jazandari Date: Sun, 29 May 2022 16:27:29 +0430 Subject: [PATCH 6/8] delete useless comments --- spec/ParseWebSocketServer.spec.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/spec/ParseWebSocketServer.spec.js b/spec/ParseWebSocketServer.spec.js index d5ef167a4a..4eb73695d1 100644 --- a/spec/ParseWebSocketServer.spec.js +++ b/spec/ParseWebSocketServer.spec.js @@ -94,10 +94,8 @@ describe('ParseWebSocketServer', function () { // Make sure callback is called expect(onConnectCallback).toHaveBeenCalled(); await new Promise(resolve => setTimeout(resolve, 10)); - // Make sure we ping to the client expect(ws.ping).toHaveBeenCalled(); await new Promise(resolve => setTimeout(resolve, 10)); - // make sure connection close after we didn't answer the ping on time expect(ws.terminate).toHaveBeenCalled(); server.close(); }); From 2aa616c6d4a711086ddc7125b0420b3872cbcd7c Mon Sep 17 00:00:00 2001 From: Javad Jazandari Date: Sun, 29 May 2022 20:17:48 +0430 Subject: [PATCH 7/8] change isAlive variable name to waitingForPong --- src/LiveQuery/ParseWebSocketServer.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/LiveQuery/ParseWebSocketServer.js b/src/LiveQuery/ParseWebSocketServer.js index c5cad9a74c..5953f01dfb 100644 --- a/src/LiveQuery/ParseWebSocketServer.js +++ b/src/LiveQuery/ParseWebSocketServer.js @@ -14,9 +14,9 @@ export class ParseWebSocketServer { logger.info('Parse LiveQuery Server started running'); }; wss.onConnection = ws => { - ws.isAlive = true; + ws.waitingForPong = true; ws.on('pong', () => { - this.isAlive = true; + this.waitingForPong = true; }); ws.on('error', error => { logger.error(error.message); @@ -25,9 +25,9 @@ export class ParseWebSocketServer { onConnect(new ParseWebSocket(ws)); // Send ping to client periodically const pingIntervalId = setInterval(() => { - if (ws.isAlive) { + if (ws.waitingForPong) { ws.ping(); - ws.isAlive = false; + ws.waitingForPong = false; } else { clearInterval(pingIntervalId); ws.terminate(); From 15e3ce3cf742c84a04f327f8731cbb95c6a28a09 Mon Sep 17 00:00:00 2001 From: Javad Jazandari Date: Sun, 29 May 2022 22:34:29 +0430 Subject: [PATCH 8/8] invert waitingForPong logic --- src/LiveQuery/ParseWebSocketServer.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/LiveQuery/ParseWebSocketServer.js b/src/LiveQuery/ParseWebSocketServer.js index 5953f01dfb..b8c66673ab 100644 --- a/src/LiveQuery/ParseWebSocketServer.js +++ b/src/LiveQuery/ParseWebSocketServer.js @@ -14,9 +14,9 @@ export class ParseWebSocketServer { logger.info('Parse LiveQuery Server started running'); }; wss.onConnection = ws => { - ws.waitingForPong = true; + ws.waitingForPong = false; ws.on('pong', () => { - this.waitingForPong = true; + this.waitingForPong = false; }); ws.on('error', error => { logger.error(error.message); @@ -25,9 +25,9 @@ export class ParseWebSocketServer { onConnect(new ParseWebSocket(ws)); // Send ping to client periodically const pingIntervalId = setInterval(() => { - if (ws.waitingForPong) { + if (!ws.waitingForPong) { ws.ping(); - ws.waitingForPong = false; + ws.waitingForPong = true; } else { clearInterval(pingIntervalId); ws.terminate();