In live reloading, also reload if the server is being recycled. Plus rewrite LiveReloading.ts completely to be better organized.
This commit is contained in:
parent
de4d78f454
commit
f1283940b7
|
|
@ -1,38 +1,78 @@
|
|||
export function enableLiveReloading(endpointUri: string) {
|
||||
listenForReloadEvent(endpointUri);
|
||||
const pollIntervalMs = 500;
|
||||
const maxPollDurationMs = 10 * 1000;
|
||||
|
||||
export function enableLiveReloading(endpointUri: string) {
|
||||
new ReloadContext(endpointUri).start();
|
||||
}
|
||||
|
||||
function listenForReloadEvent(endpointUri: string) {
|
||||
if (!WebSocket) {
|
||||
console.log('Browser does not support WebSocket, so live reloading will be disabled.');
|
||||
return;
|
||||
class ReloadContext {
|
||||
private _websocketUri: string;
|
||||
private _didConnect = false;
|
||||
private _pollUntilConnectedThenReload = false;
|
||||
private _stopPollingAtTime: Date | null = null;
|
||||
|
||||
constructor(endpointUri: string) {
|
||||
this._websocketUri = toAbsoluteWebSocketUri(endpointUri);
|
||||
}
|
||||
|
||||
// First, connect to the endpoint
|
||||
const websocketUri = toAbsoluteWebSocketUri(endpointUri);
|
||||
const source = new WebSocket(websocketUri);
|
||||
let allowConnectionFailedErrorReporting = true;
|
||||
|
||||
source.onopen = e => {
|
||||
allowConnectionFailedErrorReporting = false;
|
||||
};
|
||||
|
||||
source.onerror = e => {
|
||||
if (allowConnectionFailedErrorReporting) {
|
||||
allowConnectionFailedErrorReporting = false;
|
||||
console.error(`The client app was compiled with live reloading enabled, but could not open `
|
||||
+ ` a WebSocket connection to the server at ${websocketUri}\n`
|
||||
+ `To fix this inconsistency, either run the server in development mode, or compile the `
|
||||
+ `client app in Release configuration.`);
|
||||
start() {
|
||||
if (typeof WebSocket !== 'undefined') {
|
||||
this._attemptToConnect(/* delay */ 0);
|
||||
} else {
|
||||
console.log('Browser does not support WebSocket, so live reloading will be disabled.');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// If we're notified that we should reload, then do so
|
||||
source.onmessage = e => {
|
||||
if (e.data === 'reload') {
|
||||
location.reload();
|
||||
private _attemptToConnect(delayMs: number) {
|
||||
setTimeout(() => {
|
||||
const source = new WebSocket(this._websocketUri);
|
||||
source.onopen = event => this._onOpen();
|
||||
source.onmessage = event => this._onMessage(event.data);
|
||||
source.onerror = event => this._onError();
|
||||
source.onclose = event => this._onClose();
|
||||
}, delayMs);
|
||||
}
|
||||
|
||||
private _onOpen() {
|
||||
this._didConnect = true;
|
||||
|
||||
if (this._pollUntilConnectedThenReload) {
|
||||
reloadNow();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private _onMessage(data: string) {
|
||||
if (data === 'reload') {
|
||||
reloadNow();
|
||||
}
|
||||
}
|
||||
|
||||
private _onClose() {
|
||||
if (this._didConnect) {
|
||||
// Looks like the server is being recycled (or possibly just shut down, but in the
|
||||
// absence of a graceful shutdown we have no way to tell the difference)
|
||||
// Wait until the server appears to be back, then reload
|
||||
this._pollUntilConnectedThenReload = true;
|
||||
this._stopPollingAtTime = new Date(new Date().valueOf() + maxPollDurationMs);
|
||||
this._attemptToConnect(/* delay */ pollIntervalMs);
|
||||
}
|
||||
}
|
||||
|
||||
private _onError() {
|
||||
if (!this._didConnect) {
|
||||
if (this._pollUntilConnectedThenReload) {
|
||||
if (new Date() < this._stopPollingAtTime!) {
|
||||
// Continue polling
|
||||
this._attemptToConnect(/* delay */ pollIntervalMs);
|
||||
}
|
||||
} else {
|
||||
console.error(`The client app was compiled with live reloading enabled, but could not open `
|
||||
+ ` a WebSocket connection to the server at ${this._websocketUri}\n`
|
||||
+ `To fix this inconsistency, either run the server in development mode, or compile the `
|
||||
+ `client app in Release configuration.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function toAbsoluteWebSocketUri(uri: string) {
|
||||
|
|
@ -46,3 +86,7 @@ function toAbsoluteWebSocketUri(uri: string) {
|
|||
// Scheme must be ws: or wss:
|
||||
return uri.replace(/^http/, 'ws');
|
||||
}
|
||||
|
||||
function reloadNow() {
|
||||
location.reload();
|
||||
}
|
||||
Loading…
Reference in New Issue