[MM-63583] Send websocket ping immediately after connecting (#30579)

Этот коммит содержится в:
David Krauser
2025-04-11 09:59:22 -04:00
коммит произвёл GitHub
родитель b8bf2e235d
Коммит 88d5ad06b4
2 изменённых файлов: 53 добавлений и 30 удалений

Просмотреть файл

@@ -109,9 +109,11 @@ describe('websocketclient', () => {
const client = new WebSocketClient({ const client = new WebSocketClient({
newWebSocketFn: (url: string) => { newWebSocketFn: (url: string) => {
mockWebSocket.url = url; mockWebSocket.url = url;
if (mockWebSocket.onopen) { setTimeout(() => {
mockWebSocket.open(); if (mockWebSocket.onopen) {
} mockWebSocket.open();
}
}, 1);
return mockWebSocket; return mockWebSocket;
}, },
minWebSocketRetryTime: 50, minWebSocketRetryTime: 50,
@@ -120,7 +122,6 @@ describe('websocketclient', () => {
const initializeSpy = jest.spyOn(client, 'initialize'); const initializeSpy = jest.spyOn(client, 'initialize');
client.initialize('mock.url'); client.initialize('mock.url');
mockWebSocket.open();
mockWebSocket.close(); mockWebSocket.close();
jest.advanceTimersByTime(10); jest.advanceTimersByTime(10);
@@ -145,9 +146,11 @@ describe('websocketclient', () => {
const client = new WebSocketClient({ const client = new WebSocketClient({
newWebSocketFn: (url: string) => { newWebSocketFn: (url: string) => {
mockWebSocket.url = url; mockWebSocket.url = url;
if (mockWebSocket.onopen) { setTimeout(() => {
mockWebSocket.open(); if (mockWebSocket.onopen) {
} mockWebSocket.open();
}
}, 1);
return mockWebSocket; return mockWebSocket;
}, },
minWebSocketRetryTime: 50, minWebSocketRetryTime: 50,
@@ -156,7 +159,6 @@ describe('websocketclient', () => {
const initializeSpy = jest.spyOn(client, 'initialize'); const initializeSpy = jest.spyOn(client, 'initialize');
client.initialize('mock.url'); client.initialize('mock.url');
mockWebSocket.open();
mockWebSocket.close(); mockWebSocket.close();
jest.advanceTimersByTime(10); jest.advanceTimersByTime(10);
@@ -183,9 +185,11 @@ describe('websocketclient', () => {
const client = new WebSocketClient({ const client = new WebSocketClient({
newWebSocketFn: (url: string) => { newWebSocketFn: (url: string) => {
mockWebSocket.url = url; mockWebSocket.url = url;
if (mockWebSocket.onopen) { setTimeout(() => {
mockWebSocket.open(); if (mockWebSocket.onopen) {
} mockWebSocket.open();
}
}, 1);
return mockWebSocket; return mockWebSocket;
}, },
minWebSocketRetryTime: 50, minWebSocketRetryTime: 50,
@@ -194,7 +198,6 @@ describe('websocketclient', () => {
const initializeSpy = jest.spyOn(client, 'initialize'); const initializeSpy = jest.spyOn(client, 'initialize');
client.initialize('mock.url'); client.initialize('mock.url');
mockWebSocket.open();
mockWebSocket.close(); mockWebSocket.close();
jest.advanceTimersByTime(10); jest.advanceTimersByTime(10);
@@ -217,9 +220,11 @@ describe('websocketclient', () => {
const client = new WebSocketClient({ const client = new WebSocketClient({
newWebSocketFn: (url: string) => { newWebSocketFn: (url: string) => {
mockWebSocket.url = url; mockWebSocket.url = url;
if (mockWebSocket.onopen) { setTimeout(() => {
mockWebSocket.open(); if (mockWebSocket.onopen) {
} mockWebSocket.open();
}
}, 1);
return mockWebSocket; return mockWebSocket;
}, },
minWebSocketRetryTime: 1, minWebSocketRetryTime: 1,
@@ -252,7 +257,6 @@ describe('websocketclient', () => {
const closeSpy = jest.spyOn(mockWebSocket, 'close'); const closeSpy = jest.spyOn(mockWebSocket, 'close');
client.initialize('mock.url'); client.initialize('mock.url');
mockWebSocket.open();
jest.advanceTimersByTime(30); jest.advanceTimersByTime(30);
@@ -273,9 +277,11 @@ describe('websocketclient', () => {
const client = new WebSocketClient({ const client = new WebSocketClient({
newWebSocketFn: (url: string) => { newWebSocketFn: (url: string) => {
mockWebSocket.url = url; mockWebSocket.url = url;
if (mockWebSocket.onopen) { setTimeout(() => {
mockWebSocket.open(); if (mockWebSocket.onopen) {
} mockWebSocket.open();
}
}, 1);
return mockWebSocket; return mockWebSocket;
}, },
minWebSocketRetryTime: 1, minWebSocketRetryTime: 1,
@@ -321,7 +327,6 @@ describe('websocketclient', () => {
}); });
client.initialize('mock.url'); client.initialize('mock.url');
mockWebSocket.open();
jest.advanceTimersByTime(30); jest.advanceTimersByTime(30);
@@ -342,9 +347,11 @@ describe('websocketclient', () => {
const client = new WebSocketClient({ const client = new WebSocketClient({
newWebSocketFn: (url: string) => { newWebSocketFn: (url: string) => {
mockWebSocket.url = url; mockWebSocket.url = url;
if (mockWebSocket.onopen) { setTimeout(() => {
mockWebSocket.open(); if (mockWebSocket.onopen) {
} mockWebSocket.open();
}
}, 1);
return mockWebSocket; return mockWebSocket;
}, },
minWebSocketRetryTime: 1, minWebSocketRetryTime: 1,
@@ -362,8 +369,8 @@ describe('websocketclient', () => {
} }
numPings++; numPings++;
// don't respond to first ping // don't respond to second ping
if (numPings === 1) { if (numPings === 2) {
return; return;
} }
@@ -382,12 +389,20 @@ describe('websocketclient', () => {
const closeSpy = jest.spyOn(mockWebSocket, 'close'); const closeSpy = jest.spyOn(mockWebSocket, 'close');
client.initialize('mock.url'); client.initialize('mock.url');
mockWebSocket.open();
// Let first ping happen // Let first ping happen
jest.advanceTimersByTime(25); jest.advanceTimersByTime(10);
expect(numPings).toBe(1); expect(numPings).toBe(1);
expect(numPongs).toBe(0); expect(numPongs).toBe(1);
// Let second ping happen
jest.advanceTimersByTime(10);
expect(numPings).toBe(2);
expect(numPongs).toBe(1);
// Ensure we've still only connected once, and haven't disconnected, yet
expect(openSpy).toHaveBeenCalledTimes(1);
expect(closeSpy).toHaveBeenCalledTimes(0);
// Close and reopen connection before ping timeout // Close and reopen connection before ping timeout
mockWebSocket.close(); mockWebSocket.close();
@@ -396,7 +411,7 @@ describe('websocketclient', () => {
jest.advanceTimersByTime(100); jest.advanceTimersByTime(100);
client.close(); client.close();
expect(numPings).toBe(7); expect(numPings).toBe(9);
expect(numPongs).toBe(numPings - 1); // Ensure we only skipped the first response expect(numPongs).toBe(numPings - 1); // Ensure we only skipped the first response
expect(openSpy).toHaveBeenCalledTimes(2); // Initial open and one reconnect expect(openSpy).toHaveBeenCalledTimes(2); // Initial open and one reconnect
expect(closeSpy).toHaveBeenCalledTimes(2); // Manual close and final close expect(closeSpy).toHaveBeenCalledTimes(2); // Manual close and final close

Просмотреть файл

@@ -162,7 +162,15 @@ export default class WebSocketClient {
} }
this.stopPingInterval(); this.stopPingInterval();
var waitingForPong = false;
// Send a ping immediately to test the socket
var waitingForPong = true;
this.ping(() => {
waitingForPong = false;
});
// And every 30 seconds after, checking to ensure
// we're getting responses from the server
this.pingInterval = setInterval( this.pingInterval = setInterval(
() => { () => {
if (!waitingForPong) { if (!waitingForPong) {