fbpixel
Tags: ,

Let’s take a look at how to set up communication between a server and a client using the Websockets protocol in Python. WebSockets is a simple, robust web communication protocol for real-time communication.

Installing the Websockets library

To use WebSockets with Python, we install the necessary package…

python3 -m pip install websockets

We also use the asyncio library, which enables asynchronous programming for high-performance server development.

Retrieve server IP address

As in all Internet communications, to establish a connection between the client and the server, you need to know the server’s IP address.

To retrieve the IP address of the server machine you can use the ipconfig (Windows) or ifconfig/ ip addr (Linux) commands (here: 192.168.1.59).

window-ipconfig-ip-subnet-gateway WebSockets server-client communication with Python

You can also use the socket package in the Python script

def getIpAddress():
	import socket
	s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
	s.connect(("8.8.8.8", 80))
	ipaddress = s.getsockname()[0]
	s.close()
	return ipaddress

ipaddress = getIpAddress()

Make a note of the address, you’ll use it in the customer code.

Python code for the WebSocket server

To start the server, we define a main function that will open the server on port 8765 and run it in a loop. We also call the echo() callback function, which will handle message reception. In this example, we return the message as is to the client.

#!/usr/bin/env python
# python3 -m pip install websockets

import asyncio
from websockets.server import serve

def getIpAddress():
	import socket
	s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
	s.connect(("8.8.8.8", 80))
	ipaddress = s.getsockname()[0]
	s.close()
	return ipaddress

ipaddress = getIpAddress()
port = 8765

async def echo(websocket):
	async for message in websocket:
		print("received from {}:{} : ".format(websocket.remote_address[0],websocket.remote_address[1]) + message)
		await websocket.send(message)

async def main():
	print("Server is activated on ws://{}:{}".format(ipaddress,port))
	#async with serve(echo, "localhost", 8765):
	async with serve(echo, "0.0.0.0", port):
		await asyncio.Future()  # run forever

asyncio.run(main())

N.B.: for the server to be visible on the network outside the computer, you must specify the address “0.0.0.0” instead of “localhost”.

Python code for the WebSocket client

In the client code, we connect to the server by specifying the IP address and port. Then we send a message. Finally, we wait for the response message to be displayed.

#!/usr/bin/env python
# python3 -m pip install websockets

import asyncio
from websockets.sync.client import connect

def hello():
    #with connect("ws://localhost:8765") as websocket:
    with connect("ws://192.168.1.52:8765") as websocket:
    
        websocket.send("Hello world!")
        message = websocket.recv()
        print(f"Received from server : {message}")

hello()

Results

In a terminal, first run the server script: python websocket_server.py

python-websockets-server WebSockets server-client communication with Python

In a second terminal, run the client script; python websocket_client.py

python-websockets-client WebSockets server-client communication with Python

JSON message exchange via WebSocket

JSON (JavaScript Object Notation) is a popular data exchange format for web communication. To exchange JSON data between server and client, we use the pre-installed json library

In the client script, we’ll send a request in JSON format. The server will receive this request, check the values and send a response with the validation result.

The functions you need to know to manage the JSON format are:

  • json.loads() to switch from a String to a dict
  • json.dumps() to pass from a dict to a String

Other Python formats can be converted to their JSON equivalent

PythonJSON
dictobject
list, tuplearray
strstring
int, float, intnumber
Truetrue
Falsefalse
Nonenull

customer script

#!/usr/bin/env python
# python3 -m pip install websockets
import json
import asyncio
from websockets.sync.client import connect

jsondata = {"type": "setParam", "param1": 30, "param2": 2.3}
jsonwrong = {"type": "setParam", "param1": 30, "param2": -2.3}
jsonunkn = {"type": "setData", "param1": 30, "param2": 2.3}

def hello():
	with connect("ws://192.168.1.52:8765") as websocket:
		websocket.send("Hello world!")
		message = websocket.recv()
		print(f"Received from server : {message}")

		websocket.send(json.dumps(jsondata))
		message = websocket.recv()
		print(f"Received from server : {message}")

		websocket.send(json.dumps(jsonwrong))
		message = websocket.recv()
		print(f"Received from server : {message}")
				
		websocket.send(json.dumps(jsonunkn))
		message = websocket.recv()
		print(f"Received from server : {message}")

hello()

server script

#!/usr/bin/env python
# python3 -m pip install websockets

import json
import asyncio
from websockets.server import serve

def getIpAddress():
	import socket
	s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
	s.connect(("8.8.8.8", 80))
	ipaddress = s.getsockname()[0]
	s.close()
	return ipaddress

ipaddress = getIpAddress()
port = 8765

async def echo(websocket):
	async for message in websocket:
		print("received from {}:{} : ".format(websocket.remote_address[0],websocket.remote_address[1]) + message)
		
		if('{' not in message):
			await websocket.send(message)
		else:
			request = json.loads(message)
			answer = {}
			if(request['type'] == 'setParam'):
				answer['type'] = request['type']
				if(request['param1']<100 and request['param2']>1.2):
					answer['valid'] = True
					for key, val in request.items():
						print("\t"+key+": ", val)
				else:
					answer['valid'] = False
			else:
				answer['type'] = 'unknown'
				answer['valid'] = False
				
			await websocket.send(json.dumps(answer))

async def main():
	print("Server is activated on ws://{}:{}".format(ipaddress,port))
	#async with serve(echo, "localhost", 8765):
	async with serve(echo, "0.0.0.0", port):
		await asyncio.Future()  # run forever

asyncio.run(main())

Results

python-websockets-server-json WebSockets server-client communication with Python
python-websockets-client-json WebSockets server-client communication with Python

Sources