Обработка исключений и ошибок модуля веб-сокетов - PullRequest
0 голосов
/ 08 мая 2020

Я пытаюсь создать простой сервер WebSocket, используя модуль websockets в Python.

Моя задача - создать сервер WebSocket, который отправляет сообщение всем клиентам, которые его слушают. Проблема в том, что каждый раз, когда клиент отключается, веб-сокеты запускают исключение (ConnectionClosedOK или ConnectionClosedError, в зависимости от того, что произошло), которое мне нужно перехватить, потому что мне нужно отменить регистрацию отключившихся клиентов, чтобы WebSocket перестал отправлять сообщения. в эфире (и остановка сервера WebSocket, генерирующего эти исключения каждый раз, когда он пытается отправить сообщение закрытому клиенту).

Вот код сервера:

async def foo_call():
    await asyncio.sleep(3)
    print('Hi!')


async def register(websocket):
    users.add(websocket)
    await notify_users()


async def unregister(websocket):
    users.remove(websocket)


async def start(websocket, path):
    await register(websocket)

    try:
        await foo_call()
    except websockets.ConnectionClosedError:
        await unregister(websocket)


# WebSocket clients that are listening this WebSocket server
users = set()

# Open WebSocket server
start_server = websockets.serve(start, "localhost", 8765)

# Run asyncio event loop
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

А вот трассировка:

Task exception was never retrieved
future: <Task finished coro=<WebSocketCommonProtocol.send() done, defined at /home/vlado/Projects/dahua/venv/lib/python3.6/site-packages/websockets/protocol.py:521> exception=ConnectionClosedError('code = 1006 (connection closed abnormally [internal]), no reason',)>
Traceback (most recent call last):
  File "/home/vlado/Projects/dahua/venv/lib/python3.6/site-packages/websockets/protocol.py", line 827, in transfer_data
    message = await self.read_message()
  File "/home/vlado/Projects/dahua/venv/lib/python3.6/site-packages/websockets/protocol.py", line 895, in read_message
    frame = await self.read_data_frame(max_size=self.max_size)
  File "/home/vlado/Projects/dahua/venv/lib/python3.6/site-packages/websockets/protocol.py", line 971, in read_data_frame
    frame = await self.read_frame(max_size)
  File "/home/vlado/Projects/dahua/venv/lib/python3.6/site-packages/websockets/protocol.py", line 1051, in read_frame
    extensions=self.extensions,
  File "/home/vlado/Projects/dahua/venv/lib/python3.6/site-packages/websockets/framing.py", line 105, in read
    data = await reader(2)
  File "/usr/lib/python3.6/asyncio/streams.py", line 672, in readexactly
    raise IncompleteReadError(incomplete, n)
asyncio.streams.IncompleteReadError: 0 bytes read on a total of 2 expected bytes

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/vlado/Projects/dahua/venv/lib/python3.6/site-packages/websockets/protocol.py", line 555, in send
    await self.ensure_open()
  File "/home/vlado/Projects/dahua/venv/lib/python3.6/site-packages/websockets/protocol.py", line 803, in ensure_open
    raise self.connection_closed_exc()
websockets.exceptions.ConnectionClosedError: code = 1006 (connection closed abnormally [internal]), no reason

Я действительно не понимаю, как я могу поймать эти исключения, созданные модулем websockets .

...