Repository: dotnet/aspnetcore
File: src/SignalR/clients/ts/signalr/src/HubConnection.ts (TypeScript)

Code before:

    private _resetTimeoutPeriod() {
        if (!this.connection.features || !this.connection.features.inherentKeepAlive) {
            // Set the timeout timer
            this._timeoutHandle = setTimeout(() => this.serverTimeout(), this.serverTimeoutInMilliseconds);

            // Immediately fire Keep-Alive ping if nextPing is overdue to avoid dependency on JS timers
            let nextPing = this._nextKeepAlive - new Date().getTime();
            if (nextPing < 0) {
                if (this._connectionState === HubConnectionState.Connected) {
                    this._trySendPingMessage();
                }
                return;
            }

            // Set keepAlive timer if there isn't one
            if (this._pingServerHandle === undefined)
            {
                if (nextPing < 0) {
                    nextPing = 0;
                }

                // The timer needs to be set from a networking callback to avoid Chrome timer throttling from causing timers to run once a minute
                this._pingServerHandle = setTimeout(async () => {
                    if (this._connectionState === HubConnectionState.Connected) {
                        this._trySendPingMessage();
                    }
                }, nextPing);
            }
        }
    }

    // eslint-disable-next-line @typescript-eslint/naming-convention
    private serverTimeout() {
        // The server hasn't talked to us in a while. It doesn't like us anymore ... :(
        // Terminate the connection, but we don't need to wait on the promise. This could trigger reconnecting.
        // eslint-disable-next-line @typescript-eslint/no-floating-promises
        this.connection.stop(new Error("Server timeout elapsed without receiving a message from the server."));
    }

    private async _invokeClientMethod(invocationMessage: InvocationMessage) {
        const methodName = invocationMessage.target.toLowerCase();
        const methods = this._methods[methodName];
        if (!methods) {
            this._logger.log(LogLevel.Warning, `No client method with the name '${methodName}' found.`);

            // No handlers provided by client but the server is expecting a response still, so we send an error
            if (invocationMessage.invocationId) {
                this._logger.log(LogLevel.Warning, `No result given for '${methodName}' method and invocation ID '${invocationMessage.invocationId}'.`);
                await this._sendWithProtocol(this._createCompletionMessage(invocationMessage.invocationId, "Client didn't provide a result.", null));
            }

Review comment (suggestion):
```suggestion
                        await this._trySendPingMessage();
```

Code after:

    private _resetTimeoutPeriod() {
        if (!this.connection.features || !this.connection.features.inherentKeepAlive) {
            // Set the timeout timer
            this._timeoutHandle = setTimeout(() => this.serverTimeout(), this.serverTimeoutInMilliseconds);

            // Immediately fire Keep-Alive ping if nextPing is overdue to avoid dependency on JS timers
            let nextPing = this._nextKeepAlive - new Date().getTime();
            if (nextPing < 0) {
                if (this._connectionState === HubConnectionState.Connected) {
                    // eslint-disable-next-line @typescript-eslint/no-floating-promises
                    this._trySendPingMessage();
                }
                return;
            }

            // Set keepAlive timer if there isn't one
            if (this._pingServerHandle === undefined)
            {
                if (nextPing < 0) {
                    nextPing = 0;
                }

                // The timer needs to be set from a networking callback to avoid Chrome timer throttling from causing timers to run once a minute
                this._pingServerHandle = setTimeout(async () => {
                    if (this._connectionState === HubConnectionState.Connected) {
                        await this._trySendPingMessage();
                    }
                }, nextPing);
            }
        }
    }

    // eslint-disable-next-line @typescript-eslint/naming-convention
    private serverTimeout() {
        // The server hasn't talked to us in a while. It doesn't like us anymore ... :(
        // Terminate the connection, but we don't need to wait on the promise. This could trigger reconnecting.
        // eslint-disable-next-line @typescript-eslint/no-floating-promises
        this.connection.stop(new Error("Server timeout elapsed without receiving a message from the server."));
    }

    private async _invokeClientMethod(invocationMessage: InvocationMessage) {
        const methodName = invocationMessage.target.toLowerCase();
        const methods = this._methods[methodName];
        if (!methods) {
            this._logger.log(LogLevel.Warning, `No client method with the name '${methodName}' found.`);

            // No handlers provided by client but the server is expecting a response still, so we send an error
            if (invocationMessage.invocationId) {
                this._logger.log(LogLevel.Warning, `No result given for '${methodName}' method and invocation ID '${invocationMessage.invocationId}'.`);
                await this._sendWithProtocol(this._createCompletionMessage(invocationMessage.invocationId, "Client didn't provide a result.", null));