Skip to content

Commit 8fd0151

Browse files
authored
Send Keep-Alive Ping Immediately When Previous Ping Is Overdue (#63195)
1 parent 0ad8374 commit 8fd0151

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

src/SignalR/clients/ts/signalr/src/HubConnection.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -721,24 +721,27 @@ export class HubConnection {
721721
// Set the timeout timer
722722
this._timeoutHandle = setTimeout(() => this.serverTimeout(), this.serverTimeoutInMilliseconds);
723723

724+
// Immediately fire Keep-Alive ping if nextPing is overdue to avoid dependency on JS timers
725+
let nextPing = this._nextKeepAlive - new Date().getTime();
726+
if (nextPing < 0) {
727+
if (this._connectionState === HubConnectionState.Connected) {
728+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
729+
this._trySendPingMessage();
730+
}
731+
return;
732+
}
733+
724734
// Set keepAlive timer if there isn't one
725735
if (this._pingServerHandle === undefined)
726736
{
727-
let nextPing = this._nextKeepAlive - new Date().getTime();
728737
if (nextPing < 0) {
729738
nextPing = 0;
730739
}
731740

732741
// The timer needs to be set from a networking callback to avoid Chrome timer throttling from causing timers to run once a minute
733742
this._pingServerHandle = setTimeout(async () => {
734743
if (this._connectionState === HubConnectionState.Connected) {
735-
try {
736-
await this._sendMessage(this._cachedPingMessage);
737-
} catch {
738-
// We don't care about the error. It should be seen elsewhere in the client.
739-
// The connection is probably in a bad or closed state now, cleanup the timer so it stops triggering
740-
this._cleanupPingTimer();
741-
}
744+
await this._trySendPingMessage();
742745
}
743746
}, nextPing);
744747
}
@@ -1149,4 +1152,14 @@ export class HubConnection {
11491152
private _createCloseMessage(): CloseMessage {
11501153
return { type: MessageType.Close };
11511154
}
1155+
1156+
private async _trySendPingMessage(): Promise<void> {
1157+
try {
1158+
await this._sendMessage(this._cachedPingMessage);
1159+
} catch {
1160+
// We don't care about the error. It should be seen elsewhere in the client.
1161+
// The connection is probably in a bad or closed state now, cleanup the timer so it stops triggering
1162+
this._cleanupPingTimer();
1163+
}
1164+
}
11521165
}

0 commit comments

Comments
 (0)