Python对接FTX Websocket首条消息接收延迟优化咨询
问题背景
通过Python编写加密货币交易脚本,满足特定条件时连续发送3笔FTX买单,采用multiprocessing.Process()异步发送POST请求,依赖提前建立的wallet频道Websocket接收成交通知触发下一笔订单。当前遇到的问题是:首条Websocket成交通知延迟约1秒,后续通知仅需毫秒级;已配置每20秒发送ping包、10秒等待pong,但仍无法解决首条消息延迟。
核心原因分析
首条消息延迟通常是因为Websocket在等待触发条件的阶段处于低活跃状态:交易所服务器可能将长期 idle(仅定期ping)的连接推送优先级降低,或者本地消息处理逻辑在等待触发条件时被阻塞,未及时处理 incoming 消息。
解决方案
1. 提前预热连接,保持持续活跃
在等待触发条件的循环中,除了ping,定期主动发送轻量请求或立即处理收到的所有消息,避免连接被服务器标记为低优先级,同时防止本地消息堆积。
示例代码:
import time import json from websocket import create_connection from multiprocessing import Event def websocket_warmup(trigger_event): ws = create_connection("wss://ftx.com/ws/") # 订阅wallet频道 ws.send(json.dumps({"op": "subscribe", "channel": "wallet"})) # 等待订阅确认 while True: msg = json.loads(ws.recv()) if msg["type"] == "subscribed" and msg["channel"] == "wallet": break # 预热阶段:保持连接活跃 while not trigger_event.is_set(): # 发送ping并立即处理响应 ws.send(json.dumps({"op": "ping"})) # 清空接收缓冲区,避免消息堆积 while ws.recv(): pass time.sleep(5) # 缩短间隔至5秒,提升活跃性 # 后续处理订单成交通知 return ws
2. 分离消息处理线程,避免主线程阻塞
将Websocket的消息接收逻辑放到独立线程,确保在等待触发条件期间,消息处理一直处于运行状态,不会因为主线程的循环等待而延迟处理首条消息。
示例代码:
import json import threading import websocket from multiprocessing import Process, Queue, Event def ws_worker(trigger_event, msg_queue): def on_message(ws, msg): msg_queue.put(json.loads(msg)) ws = websocket.WebSocketApp( "wss://ftx.com/ws/", on_message=on_message, on_error=lambda ws, err: print(f"WS错误: {err}"), on_close=lambda ws: print("WS连接关闭") ) # 订阅频道 ws.send(json.dumps({"op": "subscribe", "channel": "wallet"})) # 启动后台线程运行WS wst = threading.Thread(target=ws.run_forever, kwargs={"ping_interval": 10, "ping_timeout": 5}) wst.daemon = True wst.start() # 等待触发条件时,清理无关消息 while not trigger_event.is_set(): while not msg_queue.empty(): msg_queue.get() # 清空非目标消息,避免堆积 time.sleep(0.1) # 处理订单成交通知 order_count = 0 while order_count < 3: msg = msg_queue.get() if msg.get("type") == "update" and "filled" in msg.get("data", {}): # 触发下一笔订单逻辑 order_count += 1
3. 确保订阅完全建立后再进入等待
建立Websocket连接后,必须等待交易所返回subscribed确认消息,再进入触发条件的循环。避免因订阅未完成导致首条消息被延迟推送。
4. 调整ping参数,缩短交互间隔
将ping间隔从20秒缩短至5-10秒,让服务器更频繁地感知连接活跃性,降低被标记为 idle 的概率;同时设置更短的pong超时,确保连接异常时能及时重连。
总结
通过保持连接持续活跃、分离消息处理线程、确认订阅完成这几个核心手段,可有效消除首条Websocket消息的1秒延迟,让订单触发逻辑更高效。
内容的提问来源于stack exchange,提问作者apt45

