WebSocket连接无法手动关闭:close_connection函数无效求助
WebSocket连接无法手动关闭的问题解决方法
你的close_connection函数之所以毫无作用,核心问题是:它创建了一个全新的WebSocket连接然后关闭,和hello函数里正在运行的那个连接完全是两个独立的对象,自然无法影响到正在接收数据的连接。
下面给出两种可行的解决思路:
方法一:用全局变量管理连接对象
把hello函数中创建的WebSocket连接保存为全局变量,让close_connection直接操作这个变量:
import websockets from websockets.sync.client import connect URL = "wss://test.com/test" AUTHENTIFICATION = {'Authorization': 'Basic someToken'} ws_conn = None # 全局变量存储活跃连接 def hello(): global ws_conn # 不使用with语句,避免自动关闭连接 ws_conn = connect(URL, additional_headers=AUTHENTIFICATION) try: # 验证连接状态 if ws_conn.response.status_code == 101: print('Connection successful') else: print('Failure') # 循环接收数据,捕获连接关闭的异常 while True: try: message = ws_conn.recv() print(f"Received: {message}") except websockets.exceptions.ConnectionClosed: print("连接已关闭") break finally: # 确保异常场景下也能关闭连接 if ws_conn and not ws_conn.closed: ws_conn.close() def close_connection(): global ws_conn if ws_conn and not ws_conn.closed: ws_conn.close() print("已手动关闭连接")
方法二:用类封装连接(更优雅的方式)
通过类来管理WebSocket的连接状态,逻辑更清晰,也便于扩展:
import websockets from websockets.sync.client import connect import threading URL = "wss://test.com/test" AUTHENTIFICATION = {'Authorization': 'Basic someToken'} class WSClient: def __init__(self): self.connection = None def start_listen(self): # 创建连接 self.connection = connect(URL, additional_headers=AUTHENTIFICATION) if self.connection.response.status_code == 101: print('Connection successful') else: print('Failure') # 启动线程监听数据,避免阻塞主线程 threading.Thread(target=self._listen_loop, daemon=True).start() def _listen_loop(self): if not self.connection: return try: while True: message = self.connection.recv() print(f"Received: {message}") except websockets.exceptions.ConnectionClosed: print("连接已关闭") finally: self.close() def close(self): if self.connection and not self.connection.closed: self.connection.close() print("已手动关闭连接") # 使用示例 client = WSClient() client.start_listen() # 需要关闭时调用 # client.close()
关键注意点
- 原来的
hello函数用with语句包裹整个逻辑,会在代码块结束后自动关闭连接,但你的循环接收逻辑是无限的,with块永远不会执行到关闭步骤,所以手动关闭必须跳出这个上下文。 - 手动关闭连接后,
recv()操作会抛出ConnectionClosed异常,必须在监听逻辑中捕获,避免程序崩溃。
内容的提问来源于stack exchange,提问作者user16511234
相关产品推荐
相关产品推荐

