Client closing websockets connection

python

#1

I am trying just to do a “proof of concept”. My goal is to create a web GUI with buttons that when pressed will trigger the send of a command to a piece of equipment. So I thought about creating this GUI using HTML and javaScript and send the command using JSON through a websocket to a websocket server in Phyton that would receive the message, communicate with the equipment and return the information to the web page through the websocket. So I created a simple page with two buttons, one asking for an ID and another one asking for a status byte. Both buttons call the same function passing the specific item as parameter. I harcoded the answer from the server (two different answers depending on the command received), to simplify things. So, when I press the get ID button, I receive the correct information from the server and the client closes the websocket… If now I want to press the second button, the server does not receive the “request”. I have to refresh the client page in order to be able to press the second button and then I receive the correct information, but again the client closes the websocket… and I cannot press the first button again, as the websocket is closed. So my question is: why the websocket is closing? I am not experienced either with Python or with websockets. In my ignorance I thought that websockets should remain opened until I explicitly invoke the close() function, so I thought that I could implement as many buttons I wanted and the channel between client and server would remain always opened… Am I missing something? I am using Python 3.7. Everything is running under Windows10 and client html code is running in Chrome. Below you have the two files I created. Very basic GUI and even simpler server side.I would appreciate any light you can throw in my direction on what I am missing.

Code for client side in html/JavaScript:

<!DOCTYPE html>
<html>

<head>
<title>WebSocket</title>
<style>
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}

td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
</style>
</head>

<body> 
<script>
// open webSocket on port 8765
var ws = new WebSocket("ws://localhost:8765/");
var counter = 0; // just to check if function txCommand is executed...

/*** function executed when a button is pressed ***/
function txCommand(cmd) {
// initializing variable for message to be sent
var msg = {
type:" ",
command:" "
};

// see which button was pressed 
switch (cmd)
{
case 1: { // button to read identification
msg = {
type:"message",
command:"*IDN?"
};
break;
}
case 2: { // button to read status byte
msg = {
type:"message",
command:"*STB?"
};
break;
}
default:
} 

ws.send(JSON.stringify(msg));

counter = counter + 1;

document.getElementById("demo").innerHTML = "Message Sent, counter = " + counter; 
};

ws.onopen = function() {

// Web Socket is connected, send data using send()
alert("Connection is opened...");
};

ws.onmessage = function(event){

var rx_msg = JSON.parse(event.data)

switch(rx_msg.type)
{
case "msg1": { // answer for ID request
document.getElementById("IDField").value = rx_msg.answer;
document.getElementById("demo").innerHTML = "Message 1 Received";

break;
}
case "msg2": { // answer for ID request
document.getElementById("statusByte").value = rx_msg.answer;
document.getElementById("demo").innerHTML = "Message 2 Received";

break;
}
default:
} 
};

ws.onclose = function() { 

// websocket is closed.
alert("Connection is closed..."); 
};

ws.onerror = function (error) {

alert('WebSocket Error ' + error);
};

</script> 

<table>
<tr>
<th><button onclick="txCommand(1)">Get ID</button></th>
<th>Identification: <input type="text" id="IDField" name="IDField" value=""></th> 
</tr>
<tr>
<th><button onclick="txCommand(2)">Get Status Byte</button></th>
<th>Status Byte: <input type="text" id="statusByte" name="statusByte" value=""><br></th>
</tr>
</table> 

<p id="demo"></p>

</body>
</html>

Code for the server side:

#!/usr/bin/env python

import asyncio
import websockets
import json

async def answer_command(websocket, path):
    JSONcmd = await websocket.recv()

    info_requested = json.loads(JSONcmd)

    print(info_requested)
    print(info_requested["type"])
    print(info_requested["command"])

    if info_requested["command"] == "*IDN?":
        answer = {
            "type": "msg1", 
            "answer": "Bob Test1!"
        }
    elif info_requested["command"] == "*STB?":
        answer = {
            "type": "msg2",
            "answer": "Bob Test2!"
        }
    else:
        answer = {
            "type": "msg99",
            "answer": "Error!"
        }

    janswer = json.dumps(answer)
    print(janswer)

    await websocket.send(janswer)

    print("Answer Sent back")

start_server = websockets.serve(answer_command, 'localhost', 8765)

asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

#2

Hi rmdemattos, welcome to the forums!

I got the code formatted* for you by a moderator, but the wall of text is very hard to read when it’s not spaced into paragraphs.

Do you think you could re-post the text with new lines dividing the text into paragraphs for an easier understanding what you’re asking for?

No offence intended. :slight_smile:

*) The </> button formats selected code as code.


#3

Erik: Thanks for your quick reply. I am re-posting the initial text, with paragraphs. I hope that this time formatting will hold… :slight_smile:

I am trying just to do a “proof of concept”. My goal is to create a web GUI with buttons that when pressed will trigger the send of a command to a piece of equipment.

So I thought about creating this GUI using HTML and javaScript and send the command using JSON through a websocket to a websocket server in Phyton that would receive the message, communicate with the equipment and return the information to the web page through the same websocket.

I created a simple page with two buttons, one asking for an ID and another one asking for a status byte. Both buttons call the same function passing the specific item as parameter. I harcoded the answer from the server (two different answers depending on the command received), to simplify things.

What I see:
When I press the get ID button, I receive the correct information from the server and the client closes the websocket… If now I want to press the second button, the server does not receive the “request”. I have to refresh the client page in order to be able to press the second button and then I receive the correct information for the second button, but again the client closes the websocket… and I cannot press the first button again, as the websocket is closed.

My question is:
Why the websocket in the client side is closing? I am not experienced either with Python or with websockets. In my ignorance I thought that websockets should remain opened until I explicitly invoke the close() function, so I thought that I could implement as many buttons I wanted and the channel between client and server would remain always opened…

Am I missing something? I am using Python 3.7. Everything is running under Windows10 and client html code is running in Chrome.

In the previous post you have the two files I created. Very basic GUI and even simpler server side. I would appreciate any light you can throw in my direction on what I am missing.