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")