Force a reconnect in case a heartbeat is missing (#569)
There seems to be cases where the connection is lost without the client being able to reconnect (e.g. active subscription -> system hibernation -> waking up system => not receiving any messages anymore).
This commit is contained in:
@@ -157,36 +157,32 @@ export class GraphQLClient extends BaseClient<
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected createClient() {
|
protected createClient() {
|
||||||
|
const heartbeatInterval = 1000 * 20;
|
||||||
|
|
||||||
this.wsClient = createClient({
|
this.wsClient = createClient({
|
||||||
url: () => this.getBaseUrl().replace(/http(|s)/g, 'ws'),
|
url: () => this.getBaseUrl().replace(/http(|s)/g, 'ws'),
|
||||||
keepAlive: 20000,
|
keepAlive: heartbeatInterval,
|
||||||
retryAttempts: Infinity,
|
retryAttempts: Infinity,
|
||||||
retryWait: async (retries) => {
|
|
||||||
const getDelayInMS = () => {
|
|
||||||
if (retries < 10) {
|
|
||||||
return 1000 * 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (retries < 50) {
|
|
||||||
return 1000 * 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (retries < 500) {
|
|
||||||
return 1000 * 30;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (retries < 1000) {
|
|
||||||
return 1000 * 60;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1000 * 60 * 5;
|
|
||||||
};
|
|
||||||
|
|
||||||
await new Promise((resolve) => {
|
|
||||||
setTimeout(resolve, getDelayInMS());
|
|
||||||
});
|
});
|
||||||
},
|
|
||||||
|
let lastHeartbeat: number = 0;
|
||||||
|
this.wsClient.on('connected', () => {
|
||||||
|
lastHeartbeat = Date.now();
|
||||||
});
|
});
|
||||||
|
this.wsClient.on('pong', () => {
|
||||||
|
lastHeartbeat = Date.now();
|
||||||
|
});
|
||||||
|
|
||||||
|
const checkHeartbeatInterval = heartbeatInterval + 1000 * 10;
|
||||||
|
// for some reason "this.wsClient" is undefined in the "setInterval" callback
|
||||||
|
const { wsClient } = this;
|
||||||
|
setInterval(() => {
|
||||||
|
const isHeartbeatMissing = Date.now() - lastHeartbeat > checkHeartbeatInterval * 1.1;
|
||||||
|
if (isHeartbeatMissing) {
|
||||||
|
// force a reconnect
|
||||||
|
wsClient.terminate();
|
||||||
|
}
|
||||||
|
}, checkHeartbeatInterval);
|
||||||
|
|
||||||
this.client = new ApolloClient({
|
this.client = new ApolloClient({
|
||||||
cache: new InMemoryCache({
|
cache: new InMemoryCache({
|
||||||
|
|||||||
Reference in New Issue
Block a user