How to wait for a WebSocket's readyState to change

Kendall Frey picture Kendall Frey · Nov 24, 2012 · Viewed 79.8k times · Source

I'm trying to implement a WebSocket with a fallback to polling. If the WebSocket connection succeeds, readyState becomes 1, but if it fails, readyState is 3, and I should begin polling.

I tried something like this:

var socket = new WebSocket(url);
socket.onmessage = onmsg;
while (socket.readyState == 0)
{
}
if (socket.readyState != 1)
{
    // fall back to polling
    setInterval(poll, interval);
}

I was expecting socket.readyState to update asynchronously, and allow me to read it immediately. However, when I run this, my browser freezes (I left it open for about half a minute before giving up).

I thought perhaps there was an onreadyStateChanged event, but I didn't see one in the MDN reference.

How should I be implementing this? Apparently an empty loop won't work, and there is no event for this.

Answer

user3215378 picture user3215378 · Jan 28, 2014

This is simple and it work perfectly... you can add condition about maximal time, or number of try to make it more robust...

function sendMessage(msg){
    // Wait until the state of the socket is not ready and send the message when it is...
    waitForSocketConnection(ws, function(){
        console.log("message sent!!!");
        ws.send(msg);
    });
}

// Make the function wait until the connection is made...
function waitForSocketConnection(socket, callback){
    setTimeout(
        function () {
            if (socket.readyState === 1) {
                console.log("Connection is made")
                if (callback != null){
                    callback();
                }
            } else {
                console.log("wait for connection...")
                waitForSocketConnection(socket, callback);
            }

        }, 5); // wait 5 milisecond for the connection...
}