Vamos ver como configurar a comunicação entre um servidor e um cliente usando o protocolo Websockets em Python. O WebSockets é um protocolo de comunicação web simples e robusto para comunicação em tempo real.
Instalando a biblioteca Websockets
Para utilizar WebSockets com Python, instalamos o pacote necessário…
python3 -m pip install websockets
Também usamos a biblioteca asyncio, que permite a programação assíncrona para o desenvolvimento de servidores de alto desempenho.
Recuperar o endereço IP do servidor
Como em todas as comunicações na Internet, para estabelecer uma ligação entre o cliente e o servidor, é necessário conhecer o endereço IP do servidor.
Para obter o endereço IP da máquina do servidor, pode utilizar os comandos ipconfig (Windows) ou ifconfig/ ip addr (Linux) (aqui: 192.168.1.59).

Também pode utilizar o pacote socket no script Python
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()
Tome nota do endereço, que será utilizado no código de cliente.
Código Python para o servidor WebSocket
Para lançar o servidor, definimos uma função principal que abrirá o servidor na porta 8765 e o executará em um loop. Também chamamos a função de retorno de chamada echo(), que tratará da receção da mensagem. Neste exemplo, devolvemos a mensagem tal como está para o cliente.
#!/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())
Nota: para que o servidor seja visível na rede fora do computador, é necessário especificar o endereço “0.0.0.0” em vez de “localhost”.
Código Python para o cliente WebSocket
No código do cliente, ligamo-nos ao servidor especificando o endereço IP e a porta. De seguida, enviamos uma mensagem. Por fim, aguardamos que a mensagem de resposta seja apresentada.
#!/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()
Resultados
Em um terminal, primeiro execute o script do servidor: python websocket_server.py

Num segundo terminal, execute o script do cliente; python websocket_client.py

Troca de mensagens JSON via WebSocket
O JSON (JavaScript Object Notation) é um formato de intercâmbio de dados muito popular para a comunicação na Web. Para trocar dados JSON entre o servidor e o cliente, usamos a biblioteca json pré-instalada
No script do cliente, enviaremos um pedido em formato JSON. O servidor recebe este pedido, verifica os valores e envia uma resposta com o resultado da validação.
As funções que precisa de conhecer para gerir o formato JSON são:
- json.loads() para mudar de uma String para um dict
- json.dumps() para passar de um dict para uma String
Outros formatos Python podem ser convertidos no seu equivalente JSON
| Python | JSON |
|---|---|
dict | object |
list, tuple | array |
str | string |
int, float, int | number |
True | true |
False | false |
None | null |
guião do cliente
#!/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()
script do servidor
#!/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())
Resultados

