Python中Websockets关闭握手频繁报错问题求助
解决WebSocket频繁关闭握手错误的问题
嘿,我看了你的代码和报错信息,问题根源在于频繁创建/关闭WebSocket连接,再加上服务端只处理一次消息就结束协程,导致每次交互后都触发关闭握手,短时间内反复操作就容易出现错误。咱们一步步来改:
问题分析
- 客户端的
sendWebsocket函数每次调用都用async with websockets.connect(),这相当于每次发消息都新建一个连接,发完就自动关闭。短时间内频繁建立、断开连接,很容易引发关闭握手的异常。 - 服务端的
receiver协程只执行了一次await websocket.recv(),接收一条消息后就结束了,此时服务端会主动发起连接关闭,这也是错误频繁出现的原因之一。
修改后的服务端代码
让服务端持续监听同一个连接的消息,而不是接收一次就结束:
import asyncio import websockets import json async def receiver(websocket, path): # 循环接收当前连接的所有消息,直到连接正常关闭 try: async for message in websocket: print("< {}".format(message)) except websockets.exceptions.ConnectionClosedOK: print("客户端连接正常关闭") start_server = websockets.serve(receiver, 'localhost', 8765) asyncio.get_event_loop().run_until_complete(start_server) asyncio.get_event_loop().run_forever()
修改后的客户端代码
只建立一次长连接,在同一个连接里循环发送消息,避免频繁创建连接:
import asyncio import websockets import json from array import array import random async def randomNumbers(): # 只建立一次WebSocket长连接,整个循环复用这个连接 async with websockets.connect('ws://localhost:8765') as websocket: while True: numbers = array('i', [1, 2, 3, 4, 5, 6, 7, 8, 9]) random.shuffle(numbers) await sendWebsocket(websocket, numbers[0]) await asyncio.sleep(1) async def sendWebsocket(websocket, number): # 直接使用已建立的连接发送消息,不用每次新建 ws = json.dumps({"number": number}) await websocket.send(ws) print("> {}".format(ws)) loop = asyncio.get_event_loop() try: loop.run_until_complete(randomNumbers()) finally: print("Client1 closed") loop.close()
关键修改点说明
- 服务端:用
async for message in websocket替代单次recv(),这样可以持续接收当前连接的所有消息,直到客户端主动关闭连接,避免每次接收一条就触发关闭。 - 客户端:把WebSocket连接的创建移到消息循环外面,复用同一个长连接发送所有消息,彻底解决频繁创建/关闭连接的问题。
- 辅助调整:修改
sendWebsocket函数,直接传入已建立的连接对象,不用每次重新创建连接。
这样修改后,连接会保持打开状态,每秒发送一次消息,不会再频繁触发关闭握手,错误应该就消失了。
内容的提问来源于stack exchange,提问作者DavidG
相关产品推荐
相关产品推荐

