'Copy EventListener

I have an object literal to create a websocket connection

let websocket;

const websocketConnect = {
    conn: null,
    start: function () {
        this.conn = new WebSocket('wss://.....');
        websocket = this.conn;

        this.conn.onopen = (e) => {};
        this.conn.onmessage = (e) => {};
        this.conn.onclose = (e) => {
            this.reconnect();
        };
    },

    reconnect: function () {
        this.start();
    },
};

websocketConnect.start();

websocket.addEventListener('message', function (e) {
    /***/
});

the websocket variable is global and is assigned the websocket connection, so that I can attach an eventListener outside of websocketConnect. if the connection is lost, i try to establish a new connection via reconnect().

the problem now is that websocket is reassigned in start() and the eventListener hangs on the old websocket and not on the new one. can I copy the eventListener and assign it to the new websocket-variable?



Solution 1:[1]

You could create an array of functions that you wish to use for processing incoming messages:

let websocket


const websocketConnect = {
    conn: null,
    messageFunctions: [],
    start: function () {
        this.conn = new WebSocket('wss://.....')
        this.conn.onmessage = (e) => {
            for (const func of messageFunctions) func(e)
        }
        websocket = this.conn
    },
    reconnect: function () {
        websocket = null
        this.start()
    }
}
websocketConnect.messageFunctions.push((event) => {
    console.log('handler1', event)
})

websocketConnect.messageFunctions.push((event) => {
    console.log('handler2', event)
})

websocketConnect.start()

This way, your functions are not attached directly to the WebSocket, and can be called for any new WebSocket connections without duplicating the anonymous functions.

Solution 2:[2]

You could define your own addEventListener method and forward calls to the actual method, but also keep track of them. That way you can apply them again when a new connection is made.

const websocket = {
    conn: null,
    listeners: [],
    start() {
        this.conn = new WebSocket('wss://.....');
        // Restore event listeners
        for (let {event, callback} of this.listeners) {
            this.conn.addEventListener(event, callback);
        }
        this.conn.onclose = (e) => {
            this.reconnect();
        };  
    },
    reconnect() {
        this.start();
    },
    addEventListener(event, callback) {
        // Save event listener
        this.listeners.push({event, callback});
        if (this.conn) this.conn.addEventListener(event, callback);
    }
}

websocket.start();
websocket.addEventListener('message', function (e) {
    /***/
});

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Larry Williamson
Solution 2 trincot