package com.xcong.excoin.modules.okxApi.wsHandler; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.xcong.excoin.modules.okxApi.IOkxStrategy; import lombok.extern.slf4j.Slf4j; import org.java_websocket.client.WebSocketClient; /** * OKX 私有频道 WS 处理器的抽象基类。 * *

与 Gate 版本的关键区别

* * *

架构

* 公有频道(如 k-line)连接到 public WS 端点,无需认证。 * 私有频道(如 positions、orders-algo)连接到 private WS 端点,由 * {@link com.xcong.excoin.modules.okxApi.OkxKlineWebSocketClient} 负责 * 在连接建立时发送 login 消息认证。 * *

订阅格式

*
 * {"op":"subscribe","args":[{"channel":"positions","instType":"SWAP"}]}
 * {"op":"subscribe","args":[{"channel":"orders-algo","instType":"SWAP","instId":"ETH-USDT-SWAP"}]}
 * 
* *

取消订阅格式

*
 * {"op":"unsubscribe","args":[{"channel":"positions","instType":"SWAP"}]}
 * 
* * @author Administrator */ @Slf4j public abstract class AbstractOkxPrivateChannelHandler implements OkxChannelHandler { /** 频道名称,如 "positions"、"orders-algo" */ private final String channelName; /** OKX API Key */ protected final String apiKey; /** OKX API Secret(用于签名) */ protected final String apiSecret; /** OKX API Passphrase */ protected final String passphrase; /** 交易对标识,如 "ETH-USDT-SWAP" */ private final String instId; /** 策略服务实例 */ private final IOkxStrategy strategy; /** 订阅确认状态 */ private volatile boolean subscribed = false; /** * 构造私有频道处理器。 * * @param channelName 频道名称(如 "positions"、"orders-algo") * @param apiKey OKX API Key * @param apiSecret OKX API Secret * @param passphrase OKX API Passphrase * @param instId 交易对标识(如 "ETH-USDT-SWAP") * @param strategy OKX 交易策略服务实例 */ public AbstractOkxPrivateChannelHandler(String channelName, String apiKey, String apiSecret, String passphrase, String instId, IOkxStrategy strategy) { this.channelName = channelName; this.apiKey = apiKey; this.apiSecret = apiSecret; this.passphrase = passphrase; this.instId = instId; this.strategy = strategy; } /** * @return 频道名称(如 "positions") */ @Override public String getChannelName() { return channelName; } /** * @return 交易对标识(如 "ETH-USDT-SWAP") */ @Override public String getInstId() { return instId; } /** * 发送订阅请求。 * 默认实现发送 {@code {"op":"subscribe","args":[{"channel":channelName,"instType":"SWAP"}]}}。 * 子类可覆盖以添加额外参数(如 instId)。 * * @param ws 私有频道 WebSocket 客户端 */ @Override public void subscribe(WebSocketClient ws) { JSONObject msg = new JSONObject(); msg.put("op", "subscribe"); JSONArray args = new JSONArray(); JSONObject arg = new JSONObject(); arg.put("channel", channelName); arg.put("instType", "SWAP"); args.add(arg); msg.put("args", args); ws.send(msg.toJSONString()); log.info("[OKX-WS] 订阅私有频道: {}, instType: SWAP", channelName); } /** * 发送取消订阅请求。 * * @param ws 私有频道 WebSocket 客户端 */ @Override public void unsubscribe(WebSocketClient ws) { JSONObject msg = new JSONObject(); msg.put("op", "unsubscribe"); JSONArray args = new JSONArray(); JSONObject arg = new JSONObject(); arg.put("channel", channelName); arg.put("instType", "SWAP"); args.add(arg); msg.put("args", args); ws.send(msg.toJSONString()); log.info("[OKX-WS] 取消订阅私有频道: {}", channelName); } /** * @return 策略服务实例 */ protected IOkxStrategy getStrategy() { return strategy; } // ==================== 订阅状态 ==================== @Override public boolean isSubscribed() { return subscribed; } @Override public void setSubscribed(boolean subscribed) { this.subscribed = subscribed; } }