Reputation: 175
In javascript, we have WebSocket.onclose()
for doing some stuff when a websocket connection is closed by the server. Is there a way to do the same in a Python server when the connection is closed by the client device? The server is run using the websockets
module itself using the websockets.serve()
method. Both the .Connected
& .ConnectionClosed
aren't attributes of WebSocketServerProtocol
(or so the error says). Any help would be appreciated.
Upvotes: 3
Views: 13193
Reputation: 4062
To monitor closed websocket client connections from the server:
async def browser_server(websocket, path):
closed = asyncio.ensure_future(websocket.wait_closed())
closed.add_done_callback(lambda task: your_on_close_action())
https://github.com/python-websockets/websockets/issues/243
Upvotes: 1
Reputation: 3363
Both recv() and send() will raise a websockets.exceptions.ConnectionClosed on a closed connection. Handle your cleanup there. See https://websockets.readthedocs.io/en/stable/howto/cheatsheet.html
Here's a slight modification of the websocket web example from the docs:
import asyncio
import datetime
import random
import websockets
async def time(websocket, path):
while True:
now = datetime.datetime.utcnow().isoformat() + "Z"
try:
await websocket.send(now)
except websockets.exceptions.ConnectionClosed:
print("Client disconnected. Do cleanup")
break
await asyncio.sleep(random.random() * 3)
start_server = websockets.serve(time, "127.0.0.1", 5678)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
Example client:
import asyncio
import websockets
async def hello():
uri = "ws://localhost:5678"
count = 5
async with websockets.connect(uri) as websocket:
while count > 0:
greeting = await websocket.recv()
print(f"< {greeting}")
count = count - 1
asyncio.get_event_loop().run_until_complete(hello())
Upvotes: 7