pladaria / reconnecting-websocket

Reconnecting WebSocket. For Web, React Native, cli (Node.js)
MIT License
1.23k stars 199 forks source link

Old websockets do not seem to be terminated #170

Open chongma opened 3 years ago

chongma commented 3 years ago

I am having a strange issue with websockets. I have my websocket server behind an apache httpd 2.4.51 proxy and the sockets keep disconnecting after 30 seconds or so. I am trying to investigate the issue but in the meantime I have installed reconnecting-websockets and it seems to work.

But now I have discovered that the chrome tab eventually runs out of memory and looking into the network tab on chrome reveals that lots of duplicate websockets are being created and they have status "101" whereas sometimes i get one that says status "finished"

Screenshot from 2021-11-20 19-34-34

I am using VueX to try to store a single instance of each reconnecting websocket, essentially like this

function urlProviderAutorespond() {
    return `${process.env.VUE_APP_CT_WS_V1}/websockets/admin/autoreply?access_token=${Vue.prototype.$keycloak.token}`;
}

initialiseWsAutorespond({ state, commit }) {
        if (!state.wsAutorespond) {
            const ws = new ReconnectingWebSocket(urlProviderAutorespond);
            ws.onmessage = (event) => {
                commit('setAutorespond', JSON.parse(event.data));
            };
            ws.onopen = async () => {
                if (state.firstAutorespond) {
                    // fetch some data
                    commit('setFirstAutorespond', false);
                }
                console.log("Autorespond websocket opening...");
            };
            commit('setWsAutorespond', ws);
        }
    }

The issue may be related to the way that the server is terminating the connection but reconnecting-websockets shouldn't create a new one while the old one is still open?

dce99 commented 2 years ago

Can the authors comment on this?? Problem -> On reconnecting, ws.close is called and then trying to connect or making a new web socket connection.

Isn't this ambiguous as a connection might still be open, and we might be opening a new one. Then server may send the close frame and onclose will be fired on client side, closing the new working connection !!

chongma commented 2 years ago

My problem turned out to be ping pong

DamiToma commented 1 year ago

@chongma Could you please elaborate on this? Did the old connection keep pinging the server even after closing?

chongma commented 1 year ago

@DamiToma The problem was on the server side. It wasn't correctly handling the ping pong. Eventually I moved to graphql subscriptions. So I didn't need to manually configure websockets any more.

chongma commented 1 year ago

@DamiToma The server code is something like this where it keeps a heartbeat unless the socket is closed

function heartbeat() {
    this.isAlive = true;
}

function initialiseWebsocket(name) {
    const wss = new WebSocketServer({ noServer: true });
    wss.on('connection', function (ws) {
        ws.isAlive = true;
        ws.on('pong', heartbeat);
    });
    const interval = setInterval(function ping() {
        wss.clients.forEach(function each(ws) {
            if (ws.isAlive === false) return ws.terminate();
            ws.isAlive = false;
            ws.ping();
        });
    }, 30000);
    wss.on('close', function close() {
        clearInterval(interval);
    });
    console.log(`Creating websocket ${name}`)
    return wss
}