
本文将帮助开发者理解和解决在使用 Python websockets 库时遇到的 ConnectionClosedOK 错误。该错误通常发生在客户端发送一次请求后,服务端关闭连接的情况下。本文将介绍两种解决方案:第一种方案,客户端在每次请求时建立新的 WebSocket 连接,适用于客户端请求次数较少的情况。第二种方案,服务端通过循环保持 WebSocket 连接的活跃状态,允许客户端多次请求,并探讨了如何优雅地关闭连接。
在 websockets 库中,服务端在处理完一次客户端请求后默认会关闭连接,这会导致客户端在尝试后续请求时遇到 ConnectionClosedOK 错误。要解决这个问题,我们需要根据实际需求选择合适的方案。
方案一:客户端每次请求建立新连接
这种方案适用于客户端请求次数较少,或者每次请求都需要独立连接的场景。核心思想是移除客户端代码中的 while 循环,利用 async for 循环的特性,每次迭代都建立一个新的连接。
修改后的客户端代码如下:
import timeimport jsonimport asyncioimport websocketsimport nest_asyncionest_asyncio.apply()async def get_data(websocket, key): order = {'key': key} json_data = json.dumps(order) await websocket.send(json_data) res = await asyncio.wait_for(websocket.recv(), timeout=10) res = json.loads(res) return resasync def main(): i = 0 uri = "ws://localhost:8765" async for websocket in websockets.connect(uri, timeout=15, ping_timeout=None, ping_interval=None): if i < 10: i = i + 1 print(f'counter {i}') res = await get_data(websocket, 'key') print(f"res: {res}") time.sleep(3) # slow down for tests else: break print('main exit')if __name__ == "__main__": asyncio.get_event_loop().run_until_complete(main())
注意事项:
当退出 async for websocket 循环时,可能会抛出 GeneratorExit 异常。可以使用 try/except 块捕获该异常,进行必要的清理工作。
方案二:服务端保持连接活跃
如果需要客户端和服务端保持长时间的连接,以便进行多次数据交换,则需要在服务端代码中添加一个循环,使得 handle_request 函数持续运行。
修改后的服务端代码如下:
import jsonimport asyncioimport websocketsimport nest_asyncionest_asyncio.apply()async def handle_request(websocket): while True: try: message = await websocket.recv() data = json.loads(message) order = {'key': data['key'], 'val1': 1.0, 'val2': 2.0} json_data = json.dumps(order) await websocket.send(json_data) except websockets.ConnectionClosedOK: break print("handle_request")async def main(): async with websockets.serve(handle_request, "localhost", 8765, ping_interval=None): print('world running...') await asyncio.Future() # run forever print('world done')if __name__ == "__main__": asyncio.run(main())
代码解释:
while True 循环使得 handle_request 函数可以持续接收和处理客户端的请求。try/except 块用于捕获 websockets.ConnectionClosedOK 异常,当客户端关闭连接时,服务端会退出循环,避免程序崩溃。
注意事项:
客户端也需要相应的机制来退出 async for websocket 循环,例如设置最大请求次数或接收到特定的关闭消息。在长时间保持连接的情况下,需要考虑心跳机制,定期发送 ping 消息,以确保连接的有效性。
总结
ConnectionClosedOK 错误通常是由于客户端和服务端连接管理方式不匹配导致的。通过选择合适的解决方案,并结合 try/except 块进行异常处理,可以有效地解决该问题,构建稳定可靠的 WebSocket 应用。在实际开发中,应根据具体的业务需求和场景,选择最合适的连接管理策略。
以上就是解决 WebSocket 连接中 ConnectionClosedOK 错误的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1366634.html
微信扫一扫
支付宝扫一扫