From 073b93cbf6f2ced4f02fade1117b6546ee9dd673 Mon Sep 17 00:00:00 2001 From: BrennanConroy Date: Thu, 1 Jul 2021 13:08:26 -0700 Subject: [PATCH 1/4] Use a WebLock to prevent browser tab from sleeping --- .../clients/ts/signalr/src/HubConnection.ts | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/SignalR/clients/ts/signalr/src/HubConnection.ts b/src/SignalR/clients/ts/signalr/src/HubConnection.ts index 3afbb883b3e9..fc63761a42eb 100644 --- a/src/SignalR/clients/ts/signalr/src/HubConnection.ts +++ b/src/SignalR/clients/ts/signalr/src/HubConnection.ts @@ -8,7 +8,7 @@ import { ILogger, LogLevel } from "./ILogger"; import { IRetryPolicy } from "./IRetryPolicy"; import { IStreamResult } from "./Stream"; import { Subject } from "./Subject"; -import { Arg, getErrorString } from "./Utils"; +import { Arg, getErrorString, Platform } from "./Utils"; const DEFAULT_TIMEOUT_IN_MS: number = 30 * 1000; const DEFAULT_PING_INTERVAL_IN_MS: number = 15 * 1000; @@ -49,6 +49,7 @@ export class HubConnection { private _handshakeResolver!: (value?: PromiseLike<{}>) => void; private _handshakeRejecter!: (reason?: any) => void; private _stopDuringStartError?: Error; + private _lockResolver!: (value?: PromiseLike<{}>) => void; private _connectionState: HubConnectionState; // connectionStarted is tracked independently from connectionState, so we can check if the @@ -65,6 +66,11 @@ export class HubConnection { private _timeoutHandle?: any; private _pingServerHandle?: any; + private _freezeEventListener = () => + { + this._logger.log(LogLevel.Warning, "The page is being frozen, this will likely lead to the connection being closed and messages being lost."); + }; + /** The server timeout in milliseconds. * * If this timeout elapses without receiving any messages from the server, the connection will be terminated with an error. @@ -174,6 +180,27 @@ export class HubConnection { try { await this._startInternal(); + if (Platform.isBrowser) { + if (document) { + document.addEventListener("freeze", this._freezeEventListener); + } + + const promise = new Promise((res) => { + this._lockResolver = res; + }); + + // Chrome and Edge currently support Web Locks, it's also experimental, so let's be safe and check if the APIs exist + // https://developer.mozilla.org/en-US/docs/Web/API/Web_Locks_API + // This should prevent the browsers from sleeping the tab which would close the connection unexpectedly + if (navigator && (navigator as any).locks && (navigator as any).locks.request) { + // Use a 'shared' lock so multiple tabs to the same site can used the same lock + (navigator as any).locks.request('signalr_client_lock', { mode: "shared" }, () => { + // Keep lock until promise is resolved + return promise; + }); + } + } + this._connectionState = HubConnectionState.Connected; this._connectionStarted = true; this._logger.log(LogLevel.Debug, "HubConnection connected successfully."); @@ -721,6 +748,13 @@ export class HubConnection { this._connectionState = HubConnectionState.Disconnected; this._connectionStarted = false; + this._lockResolver(); + if (Platform.isBrowser) { + if (document) { + document.removeEventListener("freeze", this._freezeEventListener); + } + } + try { this._closedCallbacks.forEach((c) => c.apply(this, [error])); } catch (e) { From bb3649c7a9828f3010991f4d1973213d1d9f5ee0 Mon Sep 17 00:00:00 2001 From: BrennanConroy Date: Thu, 1 Jul 2021 14:48:55 -0700 Subject: [PATCH 2/4] fix condition --- src/SignalR/clients/ts/signalr/src/HubConnection.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/SignalR/clients/ts/signalr/src/HubConnection.ts b/src/SignalR/clients/ts/signalr/src/HubConnection.ts index fc63761a42eb..5904230062c2 100644 --- a/src/SignalR/clients/ts/signalr/src/HubConnection.ts +++ b/src/SignalR/clients/ts/signalr/src/HubConnection.ts @@ -185,14 +185,14 @@ export class HubConnection { document.addEventListener("freeze", this._freezeEventListener); } - const promise = new Promise((res) => { - this._lockResolver = res; - }); - // Chrome and Edge currently support Web Locks, it's also experimental, so let's be safe and check if the APIs exist // https://developer.mozilla.org/en-US/docs/Web/API/Web_Locks_API // This should prevent the browsers from sleeping the tab which would close the connection unexpectedly if (navigator && (navigator as any).locks && (navigator as any).locks.request) { + const promise = new Promise((res) => { + this._lockResolver = res; + }); + // Use a 'shared' lock so multiple tabs to the same site can used the same lock (navigator as any).locks.request('signalr_client_lock', { mode: "shared" }, () => { // Keep lock until promise is resolved @@ -748,8 +748,10 @@ export class HubConnection { this._connectionState = HubConnectionState.Disconnected; this._connectionStarted = false; - this._lockResolver(); if (Platform.isBrowser) { + if (this._lockResolver) { + this._lockResolver(); + } if (document) { document.removeEventListener("freeze", this._freezeEventListener); } From 5f5cffd57c70cabc1a68c47b6ad89ea6f16f5bc7 Mon Sep 17 00:00:00 2001 From: BrennanConroy Date: Mon, 19 Jul 2021 14:23:48 -0700 Subject: [PATCH 3/4] remove web lock --- .../clients/ts/signalr/src/HubConnection.ts | 22 ++----------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/src/SignalR/clients/ts/signalr/src/HubConnection.ts b/src/SignalR/clients/ts/signalr/src/HubConnection.ts index 5904230062c2..754fd729ccf4 100644 --- a/src/SignalR/clients/ts/signalr/src/HubConnection.ts +++ b/src/SignalR/clients/ts/signalr/src/HubConnection.ts @@ -49,7 +49,6 @@ export class HubConnection { private _handshakeResolver!: (value?: PromiseLike<{}>) => void; private _handshakeRejecter!: (reason?: any) => void; private _stopDuringStartError?: Error; - private _lockResolver!: (value?: PromiseLike<{}>) => void; private _connectionState: HubConnectionState; // connectionStarted is tracked independently from connectionState, so we can check if the @@ -68,7 +67,7 @@ export class HubConnection { private _freezeEventListener = () => { - this._logger.log(LogLevel.Warning, "The page is being frozen, this will likely lead to the connection being closed and messages being lost."); + this._logger.log(LogLevel.Warning, "The page is being frozen, this will likely lead to the connection being closed and messages being lost. For more information see the docs at https://docs.microsoft.com/aspnet/core/signalr/javascript-client#browser-sleeping-tab"); }; /** The server timeout in milliseconds. @@ -182,23 +181,9 @@ export class HubConnection { if (Platform.isBrowser) { if (document) { + // Log when the browser freezes the tab so users know why their connection unexpectedly stopped working document.addEventListener("freeze", this._freezeEventListener); } - - // Chrome and Edge currently support Web Locks, it's also experimental, so let's be safe and check if the APIs exist - // https://developer.mozilla.org/en-US/docs/Web/API/Web_Locks_API - // This should prevent the browsers from sleeping the tab which would close the connection unexpectedly - if (navigator && (navigator as any).locks && (navigator as any).locks.request) { - const promise = new Promise((res) => { - this._lockResolver = res; - }); - - // Use a 'shared' lock so multiple tabs to the same site can used the same lock - (navigator as any).locks.request('signalr_client_lock', { mode: "shared" }, () => { - // Keep lock until promise is resolved - return promise; - }); - } } this._connectionState = HubConnectionState.Connected; @@ -749,9 +734,6 @@ export class HubConnection { this._connectionStarted = false; if (Platform.isBrowser) { - if (this._lockResolver) { - this._lockResolver(); - } if (document) { document.removeEventListener("freeze", this._freezeEventListener); } From 48f49c6d777775b7f2b6eca20635afd92048b10e Mon Sep 17 00:00:00 2001 From: Brennan Date: Wed, 28 Jul 2021 13:48:08 -0700 Subject: [PATCH 4/4] Update src/SignalR/clients/ts/signalr/src/HubConnection.ts --- src/SignalR/clients/ts/signalr/src/HubConnection.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SignalR/clients/ts/signalr/src/HubConnection.ts b/src/SignalR/clients/ts/signalr/src/HubConnection.ts index 754fd729ccf4..31af92eba204 100644 --- a/src/SignalR/clients/ts/signalr/src/HubConnection.ts +++ b/src/SignalR/clients/ts/signalr/src/HubConnection.ts @@ -67,7 +67,7 @@ export class HubConnection { private _freezeEventListener = () => { - this._logger.log(LogLevel.Warning, "The page is being frozen, this will likely lead to the connection being closed and messages being lost. For more information see the docs at https://docs.microsoft.com/aspnet/core/signalr/javascript-client#browser-sleeping-tab"); + this._logger.log(LogLevel.Warning, "The page is being frozen, this will likely lead to the connection being closed and messages being lost. For more information see the docs at https://docs.microsoft.com/aspnet/core/signalr/javascript-client#bsleep"); }; /** The server timeout in milliseconds.