Я хочу узнать, как правильно регистрировать и отменять регистрацию нескольких клиентов при использовании websockets-8.1 как производителя, так и потребителя.
Приведенный ниже код, использующий websockets-8.1, действующего как производителя, так и потребителя, вызывает исключение. когда клиент закрывает соединение (обновляя или закрывая окно браузера):
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')>
Внутренний код, по сути, код, склеенный из страницы проекта Начало работы :
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()
И передний конец:
<!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>