1

I have a javascript client that tries to send some data to a python websocket server, and it constantly hangs on the handshake. Here is the javascript code:

function sendData(data)
{ 
    document.getElementById('demo').innerHTML = data;
    var connection = new WebSocket('ws://localhost:10024');
    console.log(data.byteLength)
    try
    {
        connection.onopen = function ()
        {
            console.log("Attempting connection...")    
        }
        connection.onerror = function(error)
        {
            console.log("Error: " + error);
        }
        connection.onmessage = function (e) 
        {
            console.log("Server: " + e.data)
        }

        while(connection.readyState == WebSocket.CONNECTING)
        {
            console.log("Still connecting...")
        }

        if(connection.readyState == WebSocket.OPEN)
        {
            console.log("Connected succesfully!");

            for(var i = 0; i < data.byteLength; i*=256)
            {
                // a 256 byte chunk of the datafile
                var dataChunk = data.slice(i, i+256);
                connection.send(dataChunk);
                //console.log(dataChunk)
                console.log("Sending chunk: " + i + " bytes to " + (i+256) + "bytes");
            }
        }
    }
    catch(ex)
    {
        console.log("Exception: " + ex)
    }
}

The data I am trying to send is getting succesfully loaded as I check that before and inside of this function. The issue is that the 'Still connecting...' message gets printed thousands of times. If you abort the connection or try and send data without that check of the readyState, it tells me that it cannot connect because it is still in the process of connecting, leading me to believe there is some issue with the handshake part of this process.

and here is the Python server:

async def write_plain_file(websocket, path):
    index = 1
    file = open('received_'+str(index)+".jpg", 'wb')
    print("Waiting to receive some data...")
    while True:
        # we receive a generator of the data sent through
        dataChunkGen = await websocket.recv()
        print("Chunk received!");
        # we extract the data from the generator
        dataChunk = next(dataChunkGen)
        file.write(dataChunk)


start_server = websockets.serve(write_plain_file, 'localhost', '10024')

asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
print("session is finished")

It hangs on the await websocket.recv() due to the handshake never being completed. Do I need to manually send back the servers part of the handshake? How would I achieve that?

Edit: Here's the correct code, turns out I had been going about this the wrong way and needed to poll, not while loop as /u/Xufox suggested. Code is from here: How to wait for a WebSocket's readyState to change

function sendMessage(msg, ws){
    // 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();
                }
                return;

            } else {
                console.log("wait for connection...")
                waitForSocketConnection(socket, callback);
            }

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


/* Using websockets we connect to the SSL server and send the data through */
function sendData(data)
{ 
    document.getElementById('demo').innerHTML = data;
    var connection = new WebSocket('ws://localhost:10024');
    console.log(data.byteLength)
    try
    {
        connection.onopen = function ()
        {
            console.log("Attempting connection...")    
        }
        connection.onerror = function(error)
        {
            console.log("Error: " + error);
        }
        connection.onmessage = function (e) 
        {
            console.log("Server: " + e.data)
        }

        sendMessage(data, connection)
    }
    catch(ex)
    {
        console.log("Exception: " + ex)
    }
}

and the updated python server:

async def write_plain_file(websocket, path):
    index = 1
    file = open('received_'+str(index)+".jpg", 'wb')
    print("Waiting to receive some data...")
    while True:
        # we receive a generator of the data sent through
        dataChunk = await websocket.recv()
        print("Chunk received!");
        # we extract the data from the generator
        print(dataChunk)
        file.write(dataChunk)


start_server = websockets.serve(write_plain_file, 'localhost', '10024', subprotocols='wamp')

asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
print("session is finished")
J-'
  • 11
  • 3
  • Possible duplicate of [How to wait for a WebSocket's readyState to change](https://stackoverflow.com/questions/13546424/how-to-wait-for-a-websockets-readystate-to-change). You can’t wait for a state to change with a `while` loop. – Sebastian Simon Dec 21 '17 at 23:14
  • My question is different, even removing that code it still hangs on handshake. I'll update the question to clarify that. – J-' Dec 21 '17 at 23:17
  • Removing what code? If you remove the `while` loop, you don’t have any way to wait for `readyState` changes at all. You need at least a timeout or time interval. Also, did you really mean `i*=256` instead of `i+=256`? – Sebastian Simon Dec 21 '17 at 23:26
  • I updated the question to clarify what code I removed. You're right about that operation though, I did mean + – J-' Dec 21 '17 at 23:29
  • Okay, as I said, you can’t simply remove the `while` loop. In fact this is not what _any_ of the answers on that other question suggest. They all suggest something else. – Sebastian Simon Dec 21 '17 at 23:31
  • _“I've implemented the changes suggested in the link”_ — that’s not really reflected in your question or your comments. I can’t see how exactly you’ve rewritten the loop. – Sebastian Simon Dec 21 '17 at 23:36
  • Nevermind, thank you for your help, there was an error in how I had implemented the suggestions. I'll update the post with the correct code. – J-' Dec 21 '17 at 23:42

0 Answers0