Binance Websocket API连接后卡在OPEN状态无消息返回问题排查
问题原因
- 订阅地址参数错误:代码中填写的交易对为
ADABUSB属于笔误,Binance不存在该交易对,正确的ADA/BUSD现货交易对代码为ADABUSD;同时nav_kline是净值类理财产品专属的K线推送通道,普通现货交易对的1分钟K线通道标识为kline_1m。Binance Websocket服务遇到不存在的订阅主题时不会返回错误提示,只会静默停止推送消息。 - 网络链路阻断:Binance API服务在部分网络环境下存在访问限制,TCP连接握手成功后(因此触发on_open回调),后续的数据传输链路可能被中间节点静默丢弃,既收不到服务端推送,也不会触发连接断开报错。
- 缺少心跳保活机制:所用的
websocket-client库默认不会自动发送心跳包,连接建立后如果长时间无数据传输,会被运营商网关、路由等中间节点静默断开,且不会触发on_close回调,表现为程序卡住无响应。 - 缺少错误回调:原代码未实现
on_error回调,底层网络错误、参数错误等问题不会直接打印到控制台,导致问题无法被快速定位。
解决方法
- 修正订阅地址:如果要订阅普通现货ADA/BUSD的1分钟K线,将套接字地址改为
wss://stream.binance.com:9443/ws/adabusd@kline_1m,注意Binance要求订阅地址中的交易对部分必须为全小写。如果确实需要订阅净值类产品的nav_kline数据,先确认对应的产品代码准确无误。 - 验证网络连通性:先在运行代码的环境中测试到Binance Websocket服务的链路是否正常,确认网络可以正常访问服务后再运行代码。
- 添加心跳保活配置:调用
run_forever时传入心跳参数,让客户端定期发送ping帧维持连接,避免被中间节点静默切断。 - 补全错误回调:新增
on_error回调函数,捕获连接过程中的所有底层错误,方便定位问题。
修正后的可运行代码示例:
import websocket import json SOCKET = "wss://stream.binance.com:9443/ws/adabusd@kline_1m" def on_open(ws): print('opened connection') # 连接建立后主动发送订阅请求,比直接在URL拼接参数更易排查问题 sub_payload = { "method": "SUBSCRIBE", "params": ["adabusd@kline_1m"], "id": 1 } ws.send(json.dumps(sub_payload)) def on_close(ws, close_code, close_msg): print(f'connection closed, code: {close_code}, msg: {close_msg}') def on_error(ws, err): print(f'connection error: {err}') def on_message(ws, message): print('received message:') print(message) ws = websocket.WebSocketApp( SOCKET, on_open=on_open, on_close=on_close, on_message=on_message, on_error=on_error ) # 每20秒发送一次心跳,超时10秒未收到pong则判定连接断开 ws.run_forever(ping_interval=20, ping_timeout=10)
内容的提问来源于stack exchange,提问作者Zak Pinter
相关产品推荐
相关产品推荐

