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).
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
In a second terminal, run the client script; python websocket_client.py
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
Python | JSON |
---|---|
dict | object |
list , tuple | array |
str | string |
int , float , int | number |
True | true |
False | false |
None | null |
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