凌晨三点,我盯着屏幕上 Hyperliquid 的订单簿数据,看着买卖盘口的量价变化突然出现异常——这往往意味着大资金正在布局。作为一个专注加密货币量化策略的独立开发者,我需要实时获取订单簿快照来做市场微观结构分析。

这篇文章来自我个人的实战经验,记录如何用 Tardis.dev API 稳定获取 Hyperliquid 的 Level 2 订单簿数据,包括完整的代码实现、常见坑的解决方案,以及如何将数据对接到你的 AI 策略系统。

为什么需要订单簿快照数据

订单簿(Order Book)是一个交易所指定价格上所有挂单的集合,它实时反映市场供需关系。对于 Hyperliquid 这样的去中心化永续合约交易所,订单簿快照能帮助你:

Tardis.dev vs 其他数据源:为什么选它

在加密货币高频数据领域,可选的数据源主要有以下几类:

❌ 不支持
数据源数据深度延迟价格/月订单簿快照适合场景
Tardis.dev历史+实时<100ms$49起✅ 支持量化研究、策略回测、实时监控
Hyperliquid 官方实时<50ms免费✅ 支持基础交易、简单策略
CoinGecko API聚合分钟级免费/付费价格展示、非实时分析
CCXT 库实时<200ms免费✅ 部分支持多交易所交易、简单量化
Binance API实时+历史<30ms免费✅ 支持仅限 Binance,中心化交易所

Tardis.dev 核心优势

适合谁与不适合谁

✅ 强烈推荐使用 Tardis.dev 的场景

❌ 不适合的场景

价格与回本测算

Tardis.dev 的定价根据数据量和功能分为多个等级:

套餐价格数据限制适合规模
Free$07天历史,实时受限学习测试
Starter$49/月30天历史,1个交易所个人开发者
Pro$199/月1年历史,多交易所小团队
Enterprise定制无限制,定制支持机构用户

回本测算:假设你的量化策略通过订单簿数据分析,每月能捕捉 3 次有效套利机会,每次利润 $50,则月收益 $150。相比 $49 的 Starter 套餐投入,ROI 达到 206%。对于专业量化交易者来说,数据成本的回收周期通常在 1-2 周内。

为什么选 HolySheep AI

如果你需要将 Tardis 获取的订单簿数据对接到大模型做分析,HolySheep AI 是目前国内开发者的高性价比选择:

环境准备与依赖安装

在开始之前,确保你的开发环境满足以下要求:

# 安装必要的 Python 包
pip install aiohttp asyncio websockets pandas numpy

验证安装

python -c "import aiohttp, websockets, pandas; print('依赖安装成功')"

获取 Hyperliquid 订单簿快照:核心代码实现

方法一:REST API 获取历史订单簿快照

对于需要批量获取历史数据进行回测的场景,REST API 是最稳定的选择。

import aiohttp
import asyncio
import json
from datetime import datetime, timedelta

class TardisOrderBookClient:
    """Tardis.dev API 客户端 - 获取 Hyperliquid 订单簿快照"""
    
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = "https://api.tardis.dev/v1"
    
    async def get_orderbook_snapshot(
        self, 
        exchange: str = "hyperliquid",
        symbol: str = "BTC-PERP",
        date: str = None
    ) -> dict:
        """
        获取指定日期的订单簿快照数据
        
        Args:
            exchange: 交易所名称,hyperliquid
            symbol: 交易对,如 BTC-PERP
            date: 日期,格式 YYYY-MM-DD,默认获取最近一天
        
        Returns:
            订单簿快照数据,包含 bids 和 asks
        """
        if date is None:
            date = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d")
        
        url = f"{self.base_url}/historical/{exchange}/{symbol}/orderbook_snapshots"
        params = {
            "date": date,
            "has_nested_data": "false",
            "symbols": symbol
        }
        headers = {
            "Authorization": f"Bearer {self.api_key}"
        }
        
        async with aiohttp.ClientSession() as session:
            async with session.get(url, params=params, headers=headers) as response:
                if response.status == 200:
                    data = await response.json()
                    return self._parse_orderbook(data)
                else:
                    error_text = await response.text()
                    raise Exception(f"API请求失败: {response.status} - {error_text}")
    
    def _parse_orderbook(self, raw_data: list) -> dict:
        """
        解析 Tardis 返回的订单簿数据
        
        返回格式:
        {
            "timestamp": "2026-05-03T04:30:00Z",
            "symbol": "BTC-PERP",
            "bids": [(price, size), ...],
            "asks": [(price, size), ...]
        }
        """
        if not raw_data or len(raw_data) == 0:
            return None
        
        snapshot = raw_data[0]  # 取第一条快照
        return {
            "timestamp": snapshot.get("timestamp"),
            "symbol": snapshot.get("symbol"),
            "exchange": snapshot.get("exchange"),
            "bids": snapshot.get("bids", []),
            "asks": snapshot.get("asks", []),
            "bid_depth": sum([float(b[1]) for b in snapshot.get("bids", [])]),
            "ask_depth": sum([float(a[1]) for a in snapshot.get("asks", [])])
        }
    
    async def get_orderbook_range(
        self,
        exchange: str = "hyperliquid",
        symbol: str = "BTC-PERP",
        start_date: str = None,
        end_date: str = None
    ) -> list:
        """
        获取日期范围内的订单簿快照(用于回测)
        
        重要:注意 Tardis API 的速率限制,避免短时间内大量请求
        """
        if start_date is None:
            start_date = (datetime.now() - timedelta(days=7)).strftime("%Y-%m-%d")
        if end_date is None:
            end_date = datetime.now().strftime("%Y-%m-%d")
        
        all_snapshots = []
        current_date = datetime.strptime(start_date, "%Y-%m-%d")
        end = datetime.strptime(end_date, "%Y-%m-%d")
        
        while current_date <= end:
            date_str = current_date.strftime("%Y-%m-%d")
            try:
                snapshot = await self.get_orderbook_snapshot(
                    exchange=exchange,
                    symbol=symbol,
                    date=date_str
                )
                if snapshot:
                    all_snapshots.append(snapshot)
                # 遵守 API 速率限制:每秒最多 1 个请求
                await asyncio.sleep(1.1)
            except Exception as e:
                print(f"获取 {date_str} 数据失败: {e}")
            
            current_date += timedelta(days=1)
        
        return all_snapshots


使用示例

async def main(): # 初始化客户端(请替换为你的实际 API Key) client = TardisOrderBookClient(api_key="YOUR_TARDIS_API_KEY") try: # 获取单日订单簿快照 snapshot = await client.get_orderbook_snapshot( exchange="hyperliquid", symbol="BTC-PERP", date="2026-05-03" ) if snapshot: print(f"📊 订单簿快照 - {snapshot['timestamp']}") print(f"交易对: {snapshot['symbol']}") print(f"买盘深度: {snapshot['bid_depth']:.4f} BTC") print(f"卖盘深度: {snapshot['ask_depth']:.4f} BTC") print("\n🏦 买方订单(前5档):") for price, size in snapshot['bids'][:5]: print(f" ${float(price):,.2f} | 数量: {float(size):.4f}") print("\n🏦 卖方订单(前5档):") for price, size in snapshot['asks'][:5]: print(f" ${float(price):,.2f} | 数量: {float(size):.4f}") else: print("未获取到数据,请检查 API Key 和参数") except Exception as e: print(f"发生错误: {e}") if __name__ == "__main__": asyncio.run(main())

方法二:WebSocket 实时订阅订单簿

对于需要实时监控的场景,WebSocket 推送是更高效的选择。

import asyncio
import json
import websockets
from typing import Callable, Optional

class HyperliquidWebSocketClient:
    """
    Hyperliquid WebSocket 客户端 - 实时订阅订单簿数据
    
    Tardis.dev 提供统一的 WebSocket 接口,可同时订阅多个交易所
    """
    
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.ws_url = "wss://api.tardis.dev/v1/feed"
        self.subscription_id = None
    
    async def subscribe_orderbook(
        self,
        exchange: str = "hyperliquid",
        symbol: str = "BTC-PERP",
        callback: Optional[Callable] = None
    ):
        """
        订阅订单簿实时数据
        
        Args:
            exchange: 交易所名称
            symbol: 交易对
            callback: 数据回调函数
        """
        subscribe_message = {
            "type": "subscribe",
            "exchange": exchange,
            "channel": "orderbookSnapshots",
            "symbol": symbol
        }
        
        try:
            async with websockets.connect(self.ws_url) as ws:
                # 发送订阅请求
                await ws.send(json.dumps(subscribe_message))
                
                # 接收订阅确认
                confirm = await ws.recv()
                confirm_data = json.loads(confirm)
                
                if confirm_data.get("status") == "subscribed":
                    print(f"✅ 订阅成功: {exchange}/{symbol} 订单簿快照")
                    self.subscription_id = confirm_data.get("id")
                else:
                    print(f"⚠️ 订阅状态: {confirm_data}")
                
                # 持续接收数据
                while True:
                    try:
                        message = await asyncio.wait_for(ws.recv(), timeout=30.0)
                        data = json.loads(message)
                        
                        # 处理订单簿快照数据
                        if data.get("type") == "snapshot":
                            processed = self._process_snapshot(data)
                            
                            if callback:
                                await callback(processed)
                            else:
                                self._default_handler(processed)
                                
                    except asyncio.TimeoutError:
                        # 发送心跳保活
                        await ws.send(json.dumps({"type": "ping"}))
                        
        except websockets.exceptions.ConnectionClosed as e:
            print(f"🔌 WebSocket 连接断开: {e}")
            # 自动重连逻辑
            await asyncio.sleep(5)
            await self.subscribe_orderbook(exchange, symbol, callback)
    
    def _process_snapshot(self, raw_data: dict) -> dict:
        """处理原始快照数据"""
        return {
            "timestamp": raw_data.get("timestamp"),
            "exchange": raw_data.get("exchange"),
            "symbol": raw_data.get("symbol"),
            "bids": raw_data.get("data", {}).get("bids", []),
            "asks": raw_data.get("data", {}).get("asks", []),
            "local_timestamp": asyncio.get_event_loop().time()
        }
    
    def _default_handler(self, data: dict):
        """默认数据处理器"""
        bid_ask_ratio = len(data['bids']) / max(len(data['asks']), 1)
        spread = 0
        if data['bids'] and data['asks']:
            spread = float(data['asks'][0][0]) - float(data['bids'][0][0])
        
        print(f"\n⏰ {data['timestamp']}")
        print(f"📈 {data['symbol']} | 买卖盘档数比: {bid_ask_ratio:.2f} | 价差: ${spread:.2f}")
        print(f"   最佳买: ${float(data['bids'][0][0]):,.2f} | 最佳卖: ${float(data['asks'][0][0]):,.2f}")


async def analyze_orderbook(data: dict):
    """
    AI 分析回调函数示例
    
    将订单簿数据发送给 HolySheep AI 进行市场情绪分析
    """
    if not data['bids'] or not data['asks']:
        return
    
    # 计算关键指标
    top_bid = float(data['bids'][0][0])
    top_ask = float(data['asks'][0][0])
    mid_price = (top_bid + top_ask) / 2
    spread_pct = ((top_ask - top_bid) / mid_price) * 100
    
    # 整理订单簿摘要
    bid_volumes = [float(b[1]) for b in data['bids'][:10]]
    ask_volumes = [float(a[1]) for a in data['asks'][:10]]
    
    analysis_prompt = f"""
    分析以下 Hyperliquid 订单簿数据的市场情绪:
    
    当前价格: ${mid_price:,.2f}
    买卖价差: {spread_pct:.4f}%
    前10档买方总量: {sum(bid_volumes):.4f} BTC
    前10档卖方总量: {sum(ask_volumes):.4f} BTC
    买卖比: {sum(bid_volumes)/max(sum(ask_volumes), 0.0001):.2f}
    
    请给出简短的市场情绪判断(看多/看空/中性)和关键支撑/阻力位。
    """
    
    # 此处可接入 HolySheep AI API 进行分析
    # base_url: https://api.holysheep.ai/v1
    # 推荐使用 DeepSeek V3.2 ($0.42/MTok),性价比最高
    print(f"\n🤖 AI分析提示词准备完成...")
    print(f"   买卖比: {sum(bid_volumes)/max(sum(ask_volumes), 0.0001):.2f}")


async def main():
    """主函数:启动 WebSocket 订阅"""
    client = HyperliquidWebSocketClient(api_key="YOUR_TARDIS_API_KEY")
    
    print("🚀 启动 Hyperliquid 订单簿实时监控...")
    print("按 Ctrl+C 停止\n")
    
    try:
        await client.subscribe_orderbook(
            exchange="hyperliquid",
            symbol="BTC-PERP",
            callback=analyze_orderbook  # 传入 AI 分析回调
        )
    except KeyboardInterrupt:
        print("\n👋 停止监控")


if __name__ == "__main__":
    asyncio.run(main())

实战案例:将订单簿数据对接到 AI 模型

这是我实际使用的架构:Tardis 获取实时订单簿 → 数据预处理 → HolySheep AI 做市场情绪分析 → 交易信号输出。

import aiohttp
import asyncio
import json
from datetime import datetime

class OrderBookAIAnalyzer:
    """
    订单簿 AI 分析器
    
    使用 HolySheep AI 分析订单簿数据,输出市场情绪和交易信号
    """
    
    def __init__(self, tardis_key: str, holysheep_key: str):
        self.tardis_client = TardisOrderBookClient(tardis_key)
        self.holysheep_key = holysheep_key
        self.base_url = "https://api.holysheep.ai/v1"
    
    async def analyze_market_sentiment(
        self,
        exchange: str = "hyperliquid",
        symbol: str = "BTC-PERP"
    ) -> dict:
        """
        获取订单簿数据并调用 AI 分析
        
        完整流程:
        1. 从 Tardis 获取实时订单簿快照
        2. 计算订单簿特征
        3. 调用 HolySheep AI 进行分析
        """
        # Step 1: 获取订单簿数据
        snapshot = await self.tardis_client.get_orderbook_snapshot(
            exchange=exchange,
            symbol=symbol,
            date=datetime.now().strftime("%Y-%m-%d")
        )
        
        if not snapshot:
            return {"error": "无法获取订单簿数据"}
        
        # Step 2: 特征工程
        features = self._extract_features(snapshot)
        
        # Step 3: 构建分析提示词
        prompt = self._build_analysis_prompt(symbol, features)
        
        # Step 4: 调用 HolySheep AI
        analysis = await self._call_holysheep(prompt)
        
        return {
            "timestamp": snapshot["timestamp"],
            "symbol": symbol,
            "features": features,
            "analysis": analysis,
            "signal": self._extract_signal(analysis)
        }
    
    def _extract_features(self, snapshot: dict) -> dict:
        """提取订单簿特征"""
        bids = snapshot.get("bids", [])
        asks = snapshot.get("asks", [])
        
        if not bids or not asks:
            return {}
        
        # 价格计算
        top_bid = float(bids[0][0])
        top_ask = float(asks[0][0])
        mid_price = (top_bid + top_ask) / 2
        spread = top_ask - top_bid
        spread_pct = (spread / mid_price) * 100
        
        # 成交量计算(各10档)
        bid_vol = sum([float(b[1]) for b in bids[:10]])
        ask_vol = sum([float(a[1]) for a in asks[:10]])
        volume_imbalance = (bid_vol - ask_vol) / (bid_vol + ask_vol + 0.0001)
        
        # 加权平均价格
        def weighted_price(orders):
            total_vol = sum([float(o[1]) for o in orders])
            if total_vol == 0:
                return 0
            return sum([float(o[0]) * float(o[1]) for o in orders]) / total_vol
        
        vwap_bid = weighted_price(bids[:10])
        vwap_ask = weighted_price(asks[:10])
        
        return {
            "mid_price": mid_price,
            "spread": spread,
            "spread_pct": spread_pct,
            "bid_volume_10": bid_vol,
            "ask_volume_10": ask_vol,
            "volume_imbalance": volume_imbalance,
            "vwap_bid": vwap_bid,
            "vwap_ask": vwap_ask,
            "order_count_bid": len(bids[:10]),
            "order_count_ask": len(asks[:10])
        }
    
    def _build_analysis_prompt(self, symbol: str, features: dict) -> str:
        """构建 AI 分析提示词"""
        return f"""你是一个专业的加密货币市场分析师。请根据以下订单簿数据给出交易建议。

交易对: {symbol}
当前中间价: ${features.get('mid_price', 0):,.2f}
买卖价差: ${features.get('spread', 0):.2f} ({features.get('spread_pct', 0):.4f}%)
买方10档总量: {features.get('bid_volume_10', 0):.4f} BTC
卖方10档总量: {features.get('ask_volume_10', 0):.4f} BTC
成交量失衡度: {features.get('volume_imbalance', 0):.4f} (正值=买方主导,负值=卖方主导)
买方加权均价: ${features.get('vwap_bid', 0):,.2f}
卖方加权均价: ${features.get('vwap_ask', 0):,.2f}

请输出JSON格式的分析结果:
{{
    "sentiment": "看多/看空/中性",
    "confidence": 0-100,
    "support_levels": ["支撑位1", "支撑位2"],
    "resistance_levels": ["阻力位1", "阻力位2"],
    "reasoning": "分析逻辑说明",
    "risk_level": "低/中/高"
}}"""
    
    async def _call_holysheep(self, prompt: str) -> dict:
        """调用 HolySheep AI API"""
        url = f"{self.base_url}/chat/completions"
        headers = {
            "Authorization": f"Bearer {self.holysheep_key}",
            "Content-Type": "application/json"
        }
        
        payload = {
            "model": "deepseek-chat",  # DeepSeek V3.2,性价比最高 $0.42/MTok
            "messages": [
                {"role": "system", "content": "你是一个专业的加密货币交易分析师,输出简洁专业的分析。"},
                {"role": "user", "content": prompt}
            ],
            "temperature": 0.3,  # 较低温度保证分析稳定性
            "max_tokens": 500
        }
        
        async with aiohttp.ClientSession() as session:
            async with session.post(url, headers=headers, json=payload) as response:
                if response.status == 200:
                    result = await response.json()
                    content = result["choices"][0]["message"]["content"]
                    # 尝试解析 JSON
                    try:
                        return json.loads(content)
                    except:
                        return {"raw_response": content}
                else:
                    error = await response.text()
                    return {"error": f"API调用失败: {response.status} - {error}"}
    
    def _extract_signal(self, analysis: dict) -> str:
        """从分析结果中提取交易信号"""
        if "error" in analysis:
            return "HOLD"
        
        sentiment = analysis.get("sentiment", "中性")
        confidence = analysis.get("confidence", 50)
        
        if confidence < 60:
            return "HOLD"
        elif sentiment == "看多" and confidence >= 70:
            return "BUY"
        elif sentiment == "看空" and confidence >= 70:
            return "SELL"
        else:
            return "HOLD"


async def main():
    """完整分析流程示例"""
    analyzer = OrderBookAIAnalyzer(
        tardis_key="YOUR_TARDIS_API_KEY",
        holysheep_key="YOUR_HOLYSHEEP_API_KEY"
    )
    
    print("🔍 开始订单簿 AI 分析...\n")
    
    result = await analyzer.analyze_market_sentiment(
        exchange="hyperliquid",
        symbol="BTC-PERP"
    )
    
    if "error" in result:
        print(f"❌ 分析失败: {result['error']}")
        return
    
    print(f"📊 分析结果 - {result['timestamp']}")
    print(f"🪙 交易对: {result['symbol']}")
    print(f"\n📈 关键特征:")
    f = result['features']
    print(f"   中间价: ${f['mid_price']:,.2f}")
    print(f"   价差: ${f['spread']:.2f} ({f['spread_pct']:.4f}%)")
    print(f"   买卖比: {f['bid_volume_10']/max(f['ask_volume_10'], 0.0001):.2f}")
    print(f"   失衡度: {f['volume_imbalance']:.4f}")
    
    print(f"\n🤖 AI 分析:")
    a = result['analysis']
    print(f"   情绪: {a.get('sentiment', 'N/A')}")
    print(f"   置信度: {a.get('confidence', 'N/A')}%")
    print(f"   支撑位: {', '.join(a.get('support_levels', []))}")
    print(f"   阻力位: {', '.join(a.get('resistance_levels', []))}")
    print(f"   风险等级: {a.get('risk_level', 'N/A')}")
    
    print(f"\n🎯 交易信号: {result['signal']}")


if __name__ == "__main__":
    asyncio.run(main())

性能优化与最佳实践

1. 数据缓存策略

对于高频访问场景,建议使用 Redis 缓存订单簿数据:

import redis
import json
from functools import wraps

class OrderBookCache:
    """订单簿数据缓存层"""
    
    def __init__(self, redis_host="localhost", redis_port=6379):
        self.redis = redis.Redis(host=redis_host, port=redis_port, decode_responses=True)
        self.default_ttl = 5  # 缓存5秒
    
    def get_cached_orderbook(self, key: str) -> dict:
        """获取缓存的订单簿数据"""
        data = self.redis.get(f"orderbook:{key}")
        if data:
            return json.loads(data)
        return None
    
    def set_cached_orderbook(self, key: str, data: dict, ttl: int = None):
        """设置订单簿缓存"""
        ttl = ttl or self.default_ttl
        self.redis.setex(f"orderbook:{key}", ttl, json.dumps(data))
    
    def cache_and_return(self, key: str, data: dict):
        """缓存并返回数据(确保数据可用性)"""
        if data:
            self.set_cached_orderbook(key, data)
        return data


def with_cache(cache: OrderBookCache, ttl: int = 5):
    """缓存装饰器"""
    def decorator(func):
        @wraps(func)
        async def wrapper(*args, **kwargs):
            cache_key = f"{func.__name__}:{':'.join(str(a) for a in args)}"
            
            # 先查缓存
            cached = cache.get_cached_orderbook(cache_key)
            if cached:
                return cached
            
            # 缓存未命中,执行原函数
            result = await func(*args, **kwargs)
            
            # 写入缓存
            if result:
                cache.set_cached_orderbook(cache_key, result, ttl)
            
            return result
        return wrapper
    return decorator

2. 并发请求控制

import asyncio
from collections import deque
import time

class RateLimiter:
    """异步速率限制器"""
    
    def __init__(self, max_requests: int, time_window: float):
        self.max_requests = max_requests
        self.time_window = time_window
        self.requests = deque()
    
    async def acquire(self):
        """获取请求许可(阻塞直到可以执行)"""
        now = time.time()
        
        # 清理过期的请求记录
        while self.requests and self.requests[0] < now - self.time_window:
            self.requests.popleft()
        
        # 如果已达上限,等待
        if len(self.requests) >= self.max_requests:
            wait_time = self.time_window - (now - self.requests[0])
            if wait_time > 0:
                await asyncio.sleep(wait_time)
                return await self.acquire()
        
        self.requests.append(time.time())


使用示例

rate_limiter = RateLimiter(max_requests=10, time_window=1.0) # 每秒10个请求 async def throttled_api_call(): await rate_limiter.acquire() # 执行 API 调用 pass

常见报错排查

错误 1:API Key 无效或已过期

错误信息:
{"error": "Unauthorized", "message": "Invalid API key"}

原因分析:
- API Key 输入错误或包含多余空格
- API Key 已被撤销或过期
- 账户余额不足导致服务暂停

解决方案:

检查 API Key 格式是否正确

api_key = "your_key_here".strip() # 去除首尾空格

验证 Key 是否有效(以 Tardis 为例)

import aiohttp async def verify_tardis_key(api_key: str) -> bool: url = "https://api.tardis.dev/v1/account" headers = {"Authorization": f"Bearer {api_key}"} async with aiohttp.ClientSession() as session: async with session.get(url, headers=headers) as resp: return resp.status == 200

错误 2:数据日期超出范围

错误信息:
{"error": "Bad Request", "message": "Date out of range. Max historical data: 7 days"}

原因分析:
- 请求的历史数据日期超出套餐允许范围
- 免费套餐仅支持 7 天历史数据
- Starter 套餐仅支持 30 天

解决方案:

检查套餐限制并调整请求日期

from datetime import datetime, timedelta def get_valid_date_range(plan_type="free"): limits = { "free": 7, "starter": 30, "pro": 365, "enterprise": 9999 } max_days = limits.get(plan_type, 7) end_date = datetime.now() start_date = end_date - timedelta(days=max_days) return start_date.strftime("%Y-%m-%d"), end_date.strftime("%Y-%m-%d")

使用示例

start, end = get_valid_date_range("starter") print(f"有效日期范围: {start} ~ {end}")

错误 3:WebSocket 连接频繁断开

错误信息:
websockets.exceptions.ConnectionClosed: WebSocket connection closed

原因分析:
- 网络不稳定导致连接中断
- 服务器端主动断开(可能因请求频率过高)
- 心跳超时未响应

解决方案:
import asyncio
import websockets

async def resilient_connect(url,