Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better connection lost handling #33

Merged
merged 2 commits into from
Nov 27, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 53 additions & 36 deletions js-src/Websocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,27 @@ export class Websocket {
private socketId: string;

private closing = false;
private hasConnected = false;

private pingInterval: NodeJS.Timeout;

private connect(host: string): void {
this.options.debug && console.log('Connecting');
this.options.debug && console.log('Trying to connect...');

this.websocket = new WebSocket(host)

this.websocket.onerror = () => {
if (!this.hasConnected) {
setTimeout(() => {
this.socketId = undefined
this.connect(host)
}, 3000);
}
}

this.websocket.onopen = () => {
this.options.debug && console.log('Connected !');
this.hasConnected = true;
this.send({
event: 'whoami',
})
Expand All @@ -42,66 +54,71 @@ export class Websocket {

this.buffer.splice(0, 1)
}
}

this.websocket.onmessage = (messageEvent: MessageEvent) => {
const message = this.parseMessage(messageEvent.data)
// Register events only once connected, or they won't be registered if connection failed/lost

if (!message) {
return
}
this.websocket.onmessage = (messageEvent: MessageEvent) => {
const message = this.parseMessage(messageEvent.data)
this.options.debug && console.log('onmessage', messageEvent.data)

if (!message) {
return
}

if (message.channel) {
this.options.debug && console.log(`Received event ${message.event} on channel ${message.channel}`)

if (message.channel) {
this.options.debug && console.log(`Received event ${message.event} on channel ${message.channel}`)
if (this.listeners[message.channel] && this.listeners[message.channel][message.event]) {
this.listeners[message.channel][message.event](message.data)
}

if (this.listeners[message.channel] && this.listeners[message.channel][message.event]) {
this.listeners[message.channel][message.event](message.data)
return
}

return
if (this.internalListeners[message.event]) {
this.internalListeners[message.event](message.data)
}
}

if (this.internalListeners[message.event]) {
this.internalListeners[message.event](message.data)
}

// send ping every 60 seconds to keep connection alive
this.pingInterval = setInterval(() => {
if (this.websocket.readyState === this.websocket.OPEN) {
this.options.debug && console.log('Sending ping')
this.send({
event: 'ping',
})
}
}, 60 * 1000)
}


this.websocket.onclose = () => {
if (this.socketId && !this.closing || !this.socketId) {
this.options.debug && console.info('Connection lost, reconnecting...');
setTimeout(() => {
this.socketId = undefined
this.connect(host)
}, 1000);
this.options.debug && console.info('Connection closed.');
if (this.closing){
return;
}
this.hasConnected = false
this.options.debug && console.info('Connection lost, reconnecting...');
setTimeout(() => {
this.socketId = undefined
this.connect(host)
}, 1000);
};

this.on('whoami', ({ socket_id: socketId }) => {
this.socketId = socketId

this.options.debug && console.log(`just set socketId to ${socketId}`)

while (this.channelBacklog.length) {
const channel = this.channelBacklog[0]

// Handle the backlog and don't empty it, we'll need it if we lose connection
let channel: Channel;
for(channel of this.channelBacklog){
this.actuallySubscribe(channel)

this.channelBacklog.splice(0, 1)
}
})

})

// send ping every 60 seconds to keep connection alive
this.pingInterval = setInterval(() => {
if (this.websocket.readyState === this.websocket.OPEN) {
this.options.debug && console.log('Sending ping')
this.send({
event: 'ping',
})
}
}, 60 * 1000)

}

Expand Down
Loading