4

Using the following code I can create a Socket Server in my Raspberry Pi which works great if accessed via Socket clients like Android apps.

However, I would like to integrate websocket functionality to my website so I started trying to send a simple message via HTML textbox that the python script will receive and answer back.

The problem is I cant get the HTML code to open, send and keep open the socket for communication. I do acknowledge the html client connecting to python but cant get data as it seems the connection closes.

Python code

#!/usr/bin/env python

#python3
# https://pythonprogramming.net/client-server-python-sockets/

import socket               # Websocket 
import sys                  # 
from _thread import *       # Used for multi-threading      The thread module has been renamed to _thread in Python 3.
import time                 # Used to create delays

# ******* WEBSOCKET VARIABLES *******
numberClients = 0
host = ''
PORT = 2223
# ******* WEBSOCKET VARIABLES *******

# ************************** FUNCTIONS **************************
def threaded_client(conn,address):      # receive as parameters, the connection object (conn), and the address object that contains the ip and port
    global numberClients
    conn.send(str.encode('Welcome, type your info\n'))  # data should be bytes
    numberClients = numberClients + 1

    #           CHECK USER USING PASSWORD OR SOMETHING
    if ("192.168" in str(address[0])):
        print ("     VALID CLIENT!!")

        while True:
            data = conn.recv(2048)
            if (data):
                reply = "" + 'Server output: '+ data.decode('utf-8').rstrip() + "\n"
                print(str(address[0]) + " - Clients(" + str(numberClients) + ") -> Data received: >" + data.decode('utf-8').rstrip() + "<")
            if not data:
                #print("no data")
                #break
                foo = 2
            try:
                conn.sendall(str.encode(reply))     # data should be bytes
            except Exception as e:
                foo = 1
        print("Thread connection closed by client: " + address[0])
        conn.close()
        numberClients = numberClients - 1

    else:
        print ("     INVALID CLIENT -> Thread connection closed by USER VALIDATION: " + address[0])
        conn.close()
        numberClients = numberClients - 1
# ************************** FUNCTIONS **************************




# ************************** SETUP **************************
print ("\n----------- Starting Websocket Python Program -----------\n")

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)   # "s" here is being returned a "socket descriptor" by socket.socket.
print(s)

# we are simply attempeting to bind a socket locally, on PORT 5555.
try:
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)         # reuse the port number (in case we just got an error and port was not freed)
    s.bind((host, PORT))                # server side - take IN connections
    print ("Server started on port " + str(PORT))
except socket.error as e:
    print(str(e))
    print('Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1])
    #sys.exit()
print('Socket bind complete')

s.listen(5)     # the "5" stands for how many incoming connections we're willing to queue before denying any more.

print('Waiting for a connection.')
# ************************** SETUP **************************



# ************************** MAIN LOOP **************************
while True:
    conn, addr = s.accept()         # code will stop here whilst waiting for a new connection. Old connections will be running in the threads
    print('Connected to: '+addr[0]+':'+str(addr[1]))

    start_new_thread(threaded_client,(conn,addr))   
# ************************** MAIN LOOP **************************

One of the many HTML codes I have tried:

  <script type="text/javascript">
     function WebSocketTest()
     {
        if ("WebSocket" in window)
        {
           alert("WebSocket is supported by your Browser!");

           // Let us open a web socket
           var ws = new WebSocket("ws://192.168.1.20:5252/echo");
           ws.onopen = function()
           {
              // Web Socket is connected, send data using send()
              ws.send("133:L1");
              alert("Message is sent...");
           };

           ws.onmessage = function (evt) 
           { 
              var received_msg = evt.data;
              alert("Message is received...");
           };

           ws.onclose = function()
           { 
              // websocket is closed.
              alert("Connection is closed..."); 
           };
        }

        else
        {
           // The browser doesn't support WebSocket
           alert("WebSocket NOT supported by your Browser!");
        }
     }
  </script>
      </head>    <body>

  <div id="sse">
     <a href="javascript:WebSocketTest()">Run WebSocket</a>
  </div>
      </body> </html>

As you can see things which are working: - More than one client can connect - Clients connecting from android app can send and receive messages and keep connection open - html client is accepted but no message is send

enter image description here

Serge
  • 312
  • 5
  • 20

1 Answers1

4

That's not a Websocket application you create with Python but a Socket application. Websocket is a protocol on top of HTTP which sits on top of TCP which are the actual sockets you've used in your Python application. To create a Websockets server with python you might try the websockets library.

For more details about the difference see Difference between socket and websocket? or Differences between TCP sockets and web sockets, one more time for the difference. For server code see https://stackoverflow.com/questions/5839054/websocket-server-in-python.

Community
  • 1
  • 1
Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
  • wow! Big mistake on my side. I would like to keep the python "socket" script as it is already working great. Is it possible to create a html socket client? My second objective will be to create an Android App to communicate with python socket. – Serge Dec 05 '15 at 11:25
  • @Serge: There is no standard interface for plain sockets in HTML. For Chrome have a look at [sockets_tcp](https://developer.chrome.com/apps/sockets_tcp). – Steffen Ullrich Dec 05 '15 at 11:29
  • So given my objective: have a python script serving live fast information to an Android App and also to a HTML website. Should I modify my python script to use WebSocket instead of Sockets? – Serge Dec 05 '15 at 11:31
  • @Serge: if you want to support all (recent) browsers then you have to use WebSockets. For browser support see [caniuse](http://caniuse.com/#feat=websockets). – Steffen Ullrich Dec 05 '15 at 11:32
  • Will it be possible to communicate via an Android App also? Right now is very nice how I can use any android app client to connect to it. I would like to be able to continue doing this, but also html access. – Serge Dec 05 '15 at 11:35
  • seems like this is a good starting point: https://gist.github.com/jkp/3136208 I have managed to make the above html code work, and downloaded an Android app which works. Now time to find out how to allow multiple clients – Serge Dec 05 '15 at 11:53