问题
I want to learn how to properly register and unregister multiple client when using websockets-8.1 as both producer and consumer.
The code below, using websockets-8.1 acting as both producer and consumer, throws an exception when a client closes the connection (refreshing or closing the browser window):
future: <Task finished coro=<WebSocketCommonProtocol.send() done, defined at .../site-packages/websockets/protocol.py:521> exception=ConnectionClosedError('code = 1006 (connection closed abnormally [internal]), no reason')>
Backend code, essentially code glued together from the project Getting Started page:
import asyncio
import websockets
connected_users = set()
async def ws_server(websocket, path):
await register(websocket)
try:
while True:
consumer_task = asyncio.ensure_future(consumer_handler(websocket, path))
producer_task = asyncio.ensure_future(producer_handler(websocket, path))
done, pending = await asyncio.wait([consumer_task, producer_task], return_when=asyncio.FIRST_COMPLETED, )
for task in pending:
task.cancel()
await asyncio.sleep(0.1)
finally:
await unregister(websocket)
async def register(websocket):
global connected_users
connected_users.add(websocket)
print("Connected clients: {}".format(connected_users))
async def unregister(websocket):
global connected_users
connected_users.remove(websocket)
async def consumer_handler(websocket, path):
print(f'Consumer Handler: Going to sleep')
await asyncio.sleep(1.0)
async def producer_handler(websocket, path):
global connected_users
await asyncio.wait([user.send("message") for user in connected_users])
print(f'Producer Handler: Going to sleep')
await asyncio.sleep(1.0)
if __name__ == "__main__":
start_server = websockets.server.serve(ws_server, "0.0.0.0", 8080)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
And front end:
<!doctype html>
<script>
var book_ws = new WebSocket("ws://127.0.0.1:8080/"), messages = "";
book_ws.onopen = function (event) {
book_ws.send( JSON.stringify({action: "subscribe_all"}) );
};
window.onbeforeunload = function(){
if (runOnce == false){
book_ws.send( JSON.stringify({action: "unsubscribe_all"}) );
}
};
</script>
</html>
来源:https://stackoverflow.com/questions/60836748/python-websockets-8-1-connectionclosederror