Python Forum

Full Version: Client closing websocket connection - proof of concept
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
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()