程序接收到中断信号后WebSocket无法通信
我的服务器:
import websockets
async def handler(ws):
async for message in ws:
print(message)
await ws.send('received' + message)
server = await websockets.serve(handler, 'localhost', 22235)
我的客户端:
import websockets
import asyncio
import json
async def keep_recv():
ws = await websockets.connect('ws://localhost:22235')
while True:
try:
response = await ws.recv()
print(f"Received from server: {response}")
await asyncio.create_task(asyncio.sleep(10000))
finally:
print('cancelled')
await ws.send('client cancelled')
response = await ws.recv()
print(f"Received from server: {response}")
break
asyncio.run(keep_recv())
当我在客户端按下 ctrl+c 时,我希望客户端输出:
cancelled
Received from server: client cancelled
而服务器输出:
client cancelled
但实际上,输出是:
客户端:
cancelled
服务器没有任何输出。
过了一段时间(可能是在等待 ws.send),客户端会出现 KeyboardInterrupt 错误并退出,而服务器会输出 websockets.exceptions.ConnectionClosedError: no close frame received or sent
错误,并继续运行。
在程序收到中断信号后,websockets 会停止通信吗?
我该如何让它正常工作?
另外,尝试在客户端捕获任何错误根本没有用。我希望在客户端:
try:
response = await ws.recv()
print(f"Received from server: {response}")
await asyncio.create_task(asyncio.sleep(10000))
expect Exception as e:
print(e)
finally:
打印出错误(asyncio.CancelledError),但没有,它只是直接跳到 finally 部分。我也不太明白为什么会这样。
1 个回答
0
我建议在捕捉一般的异常之前,先使用一个明确的 asyncio 异常调用(比如 asyncio.CancelledError)。因为在异步代码中,异常可能会异步发生,这些异常可能需要单独处理才能捕捉到。
所以,你的代码可以修改成这样:
import websockets
import asyncio
import json
async def keep_recv():
async with websockets.connect('ws://localhost:22235') as ws:
try:
while True:
try:
response = await ws.recv()
print(f"Received from server: {response}")
await asyncio.create_task(asyncio.sleep(10000))
except websockets.exceptions.ConnectionClosedOK:
await ws.send('client cancelled')
print('Connection closed by server')
break
except asyncio.CancelledError:
print('Coroutine cancelled')
await ws.send('client cancelled')
break
except Exception as e:
print(f"Error: {e}")
break
finally:
await ws.close()
asyncio.run(keep_recv())