You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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()

关键注意点

  1. 原来的hello函数用with语句包裹整个逻辑,会在代码块结束后自动关闭连接,但你的循环接收逻辑是无限的,with块永远不会执行到关闭步骤,所以手动关闭必须跳出这个上下文。
  2. 手动关闭连接后,recv()操作会抛出ConnectionClosed异常,必须在监听逻辑中捕获,避免程序崩溃。

内容的提问来源于stack exchange,提问作者user16511234

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 13:07:12