Python Websockets-8.1 ConnectionClosedError - PullRequest
0 голосов
/ 24 марта 2020

Я хочу узнать, как правильно регистрировать и отменять регистрацию нескольких клиентов при использовании 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>
...