使用websocket-client对接Binance API遇Ping帧触发1008错误断开求助
问题描述
使用Python的websocket-client库对接Binance API的WebSocket端点,实时获取指定交易对的最优买卖报价更新。原本运行正常,但收到Binance发送的Ping帧时,连接会以错误码1008断开。尝试过以下操作均无效:
- 移除
on_ping处理器,期望库自动处理Ping消息 - 设置
ping_interval参数 - 在
on_ping中发送'PING'或反射收到的消息 - 在
on_ping中发送websocket.ABNF.OPCODE_PING
相关代码片段:
WebSocket初始化代码
ws = websocket.WebSocketApp( self.SOCKET_URL, on_message=_on_message, on_open=_on_open, on_error=_on_error, on_close=_on_close, on_ping=_on_ping, )
连接与处理逻辑代码
def _reconnect(self, ws: websocket.WebSocketApp): if ws.sock is not None: if ws.sock.connected: return else: ws.close() self.clear_database() ws.run_forever(http_proxy_port=8080, ping_interval=60) if ws.sock is not None and ws.sock.connected: return logger.info("[SOCKET Close] %s provider. Unable to reconnect, need to do it manually", self.provider.name) ws.close() def _on_error(self, ws, error): self._reconnect(ws) logger.info('[SOCKET Err] %s provider: %s', self.provider.name, error) def _on_close(self, ws, _, close_msg): logger.info("[SOCKET Close] %s provider: %s. Code %s", self.provider.name, close_msg, _) self._reconnect(ws) def _on_ping(self, ws, *_): ws.send(websocket.ABNF.OPCODE_PING)
解决方法
错误码1008属于WebSocket协议违规,核心原因是收到Ping帧后回复了Ping而非协议要求的Pong帧。
方案1:让库自动处理Ping/Pong
移除自定义的on_ping处理器,同时在run_forever中明确设置ping_timeout参数,确保库的自动Ping/Pong机制生效:
ws.run_forever(http_proxy_port=8080, ping_interval=60, ping_timeout=10)
方案2:自定义正确的Ping处理逻辑
如果必须保留on_ping处理器,要回复Pong帧而非Ping:
def _on_ping(self, ws, ping_data): # 方法1:用库提供的pong方法 ws.pong(ping_data) # 方法2:手动指定opcode发送Pong # ws.send(ping_data, opcode=websocket.ABNF.OPCODE_PONG)
额外优化建议
- 修正
_reconnect方法:不需要在重新连接前手动调用ws.close(),库会自动处理已断开的连接 - 测试时可暂时移除代理配置,排查是否是代理干扰了WebSocket的Ping/Pong交互
- 确保使用的websocket-client库是最新版本,旧版本可能存在自动Ping/Pong的逻辑bug
内容的提问来源于stack exchange,提问作者Aleksandr Tynianov
相关产品推荐
相关产品推荐

