From 15f9f41c686c0dc05889ecfd62ad620ff38e1610 Mon Sep 17 00:00:00 2001 From: guoyingcheng Date: Sat, 25 Apr 2020 15:50:00 +0800 Subject: [PATCH 1/3] add http proxy support --- pom.xml | 6 + .../com/huobi/client/SubscriptionOptions.java | 17 +- .../com/huobi/client/impl/RestApiInvoker.java | 206 +++++++++++------- .../client/impl/WebSocketConnection.java | 68 +++--- .../client/examples/SubscribeTradeEvent.java | 58 ++++- .../client/impl/MockWebsocketConnection.java | 1 + 6 files changed, 229 insertions(+), 127 deletions(-) diff --git a/pom.xml b/pom.xml index 8880f7c5..4cf693a5 100644 --- a/pom.xml +++ b/pom.xml @@ -61,6 +61,12 @@ commons-lang 2.6 + + org.jetbrains + annotations + 13.0 + compile + diff --git a/src/main/java/com/huobi/client/SubscriptionOptions.java b/src/main/java/com/huobi/client/SubscriptionOptions.java index f315d858..8b68118d 100644 --- a/src/main/java/com/huobi/client/SubscriptionOptions.java +++ b/src/main/java/com/huobi/client/SubscriptionOptions.java @@ -1,6 +1,8 @@ package com.huobi.client; import com.huobi.client.exception.HuobiApiException; + +import java.net.Proxy; import java.net.URI; /** @@ -12,16 +14,25 @@ public class SubscriptionOptions { private boolean isAutoReconnect = true; private int receiveLimitMs = 60_000; private int connectionDelayOnFailure = 15; + private Proxy proxy; public SubscriptionOptions( - SubscriptionOptions options) { + SubscriptionOptions options) { this.uri = options.uri; this.isAutoReconnect = options.isAutoReconnect; this.receiveLimitMs = options.receiveLimitMs; this.connectionDelayOnFailure = options.connectionDelayOnFailure; + this.proxy=options.proxy; + } + public void setProxy(Proxy proxy) + { + this.proxy=proxy; + } + public Proxy getProxy() + { + return this.proxy; } - public SubscriptionOptions() { } @@ -36,7 +47,7 @@ public void setUri(String uri) { } catch (Exception e) { throw new HuobiApiException( - HuobiApiException.INPUT_ERROR, "The URI is incorrect: " + e.getMessage()); + HuobiApiException.INPUT_ERROR, "The URI is incorrect: " + e.getMessage()); } this.uri = uri; } diff --git a/src/main/java/com/huobi/client/impl/RestApiInvoker.java b/src/main/java/com/huobi/client/impl/RestApiInvoker.java index 1e33d7cb..f05299d4 100644 --- a/src/main/java/com/huobi/client/impl/RestApiInvoker.java +++ b/src/main/java/com/huobi/client/impl/RestApiInvoker.java @@ -1,22 +1,5 @@ package com.huobi.client.impl; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import com.sun.istack.internal.NotNull; -import okhttp3.Call; -import okhttp3.Callback; -import okhttp3.Interceptor; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; -import okhttp3.WebSocket; -import okhttp3.WebSocketListener; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.huobi.client.AsyncResult; import com.huobi.client.ResponseCallback; import com.huobi.client.exception.HuobiApiException; @@ -24,6 +7,20 @@ import com.huobi.client.impl.utils.FailedAsyncResult; import com.huobi.client.impl.utils.JsonWrapper; import com.huobi.client.impl.utils.SucceededAsyncResult; +import okhttp3.*; +import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.net.Proxy; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +//import com.sun.istack.internal.NotNull; + +//import com.sun.istack.internal.NotNull; public abstract class RestApiInvoker { @@ -34,31 +31,66 @@ public abstract class RestApiInvoker { public static final String END_TIME_KEY = "endTime"; private static boolean PERFORMANCE_SWITCH = false; + private static Proxy proxy; + + + + private static OkHttpClient client = getBuilder(proxy).build(); + + @NotNull + private static OkHttpClient.Builder getBuilder(Proxy proxy) { + if (proxy!=null) { + + return new OkHttpClient.Builder() + .pingInterval(20, TimeUnit.SECONDS) + .readTimeout(10, TimeUnit.SECONDS) + .proxy(proxy) + .addInterceptor(new Interceptor() { + @NotNull + @Override + public Response intercept(@NotNull Chain chain) throws IOException { + Request request = chain.request(); + + Long startTime = System.currentTimeMillis(); + Response response = chain.proceed(request); + Long endTime = System.currentTimeMillis(); + + if (PERFORMANCE_SWITCH) { + EXECUTE_COST_MAP.clear(); + EXECUTE_COST_MAP.put(START_TIME_KEY,startTime); + EXECUTE_COST_MAP.put(END_TIME_KEY,endTime); + } + + return response; + } + }); + }else + { + return new OkHttpClient.Builder() + .pingInterval(20, TimeUnit.SECONDS) + .readTimeout(10, TimeUnit.SECONDS) + .addInterceptor(new Interceptor() { + @NotNull + @Override + public Response intercept(@NotNull Chain chain) throws IOException { + Request request = chain.request(); + + Long startTime = System.currentTimeMillis(); + Response response = chain.proceed(request); + Long endTime = System.currentTimeMillis(); + + if (PERFORMANCE_SWITCH) { + EXECUTE_COST_MAP.clear(); + EXECUTE_COST_MAP.put(START_TIME_KEY,startTime); + EXECUTE_COST_MAP.put(END_TIME_KEY,endTime); + } + + return response; + } + }); + } - - private static OkHttpClient client = new OkHttpClient.Builder() - .pingInterval(20, TimeUnit.SECONDS) - .readTimeout(10, TimeUnit.SECONDS) - .addInterceptor(new Interceptor() { - @NotNull - @Override - public Response intercept(@NotNull Chain chain) throws IOException { - Request request = chain.request(); - - Long startTime = System.currentTimeMillis(); - Response response = chain.proceed(request); - Long endTime = System.currentTimeMillis(); - - if (PERFORMANCE_SWITCH) { - EXECUTE_COST_MAP.clear(); - EXECUTE_COST_MAP.put(START_TIME_KEY,startTime); - EXECUTE_COST_MAP.put(END_TIME_KEY,endTime); - } - - return response; - } - }) - .build(); + } static void checkResponse(JsonWrapper json) { try { @@ -68,10 +100,10 @@ static void checkResponse(JsonWrapper json) { String err_code = json.getString("err-code"); String err_msg = json.getString("err-msg"); throw new HuobiApiException(HuobiApiException.EXEC_ERROR, - "[Executing] " + err_code + ": " + err_msg); + "[Executing] " + err_code + ": " + err_msg); } else if (!"ok".equals(status)) { throw new HuobiApiException( - HuobiApiException.RUNTIME_ERROR, "[Invoking] Response is not expected: " + status); + HuobiApiException.RUNTIME_ERROR, "[Invoking] Response is not expected: " + status); } } else if (json.containKey("success")) { boolean success = json.getBoolean("success"); @@ -82,7 +114,7 @@ static void checkResponse(JsonWrapper json) { throw new HuobiApiException(HuobiApiException.EXEC_ERROR, "[Executing] " + err_msg); } else { throw new HuobiApiException(HuobiApiException.EXEC_ERROR, - "[Executing] " + err_code + ": " + err_msg); + "[Executing] " + err_code + ": " + err_msg); } } } else if (json.containKey("code")) { @@ -94,52 +126,52 @@ static void checkResponse(JsonWrapper json) { } } else { throw new HuobiApiException( - HuobiApiException.RUNTIME_ERROR, "[Invoking] Status cannot be found in response."); + HuobiApiException.RUNTIME_ERROR, "[Invoking] Status cannot be found in response."); } } catch (HuobiApiException e) { throw e; } catch (Exception e) { throw new HuobiApiException( - HuobiApiException.RUNTIME_ERROR, "[Invoking] Unexpected error: " + e.getMessage()); + HuobiApiException.RUNTIME_ERROR, "[Invoking] Unexpected error: " + e.getMessage()); } } static T callSync(RestApiRequest request) { return callSync(request, Boolean.TRUE); } - + static T callSync(RestApiRequest request, boolean ifCheck) { - try { - String str; - log.debug("Request URL " + request.request.url()); - Response response = client.newCall(request.request).execute(); - if (response.code() != 200) { - throw new HuobiApiException( - HuobiApiException.EXEC_ERROR, "[Invoking] Response Status Error : "+response.code()+" message:"+response.message()); - } - if (response != null && response.body() != null) { - str = response.body().string(); - response.close(); - } else { - throw new HuobiApiException( - HuobiApiException.ENV_ERROR, "[Invoking] Cannot get the response from server"); - } - log.debug("Response =====> " + str); - JsonWrapper jsonWrapper = JsonWrapper.parseFromString(str); - - if (ifCheck) { - checkResponse(jsonWrapper); - } - return request.jsonParser.parseJson(jsonWrapper); - } catch (HuobiApiException e) { - throw e; - } catch (Exception e) { - throw new HuobiApiException( - HuobiApiException.ENV_ERROR, "[Invoking] Unexpected error: " + e.getMessage()); - } - } - - + try { + String str; + log.debug("Request URL " + request.request.url()); + Response response = client.newCall(request.request).execute(); + if (response.code() != 200) { + throw new HuobiApiException( + HuobiApiException.EXEC_ERROR, "[Invoking] Response Status Error : "+response.code()+" message:"+response.message()); + } + if (response != null && response.body() != null) { + str = response.body().string(); + response.close(); + } else { + throw new HuobiApiException( + HuobiApiException.ENV_ERROR, "[Invoking] Cannot get the response from server"); + } + log.debug("Response =====> " + str); + JsonWrapper jsonWrapper = JsonWrapper.parseFromString(str); + + if (ifCheck) { + checkResponse(jsonWrapper); + } + return request.jsonParser.parseJson(jsonWrapper); + } catch (HuobiApiException e) { + throw e; + } catch (Exception e) { + throw new HuobiApiException( + HuobiApiException.ENV_ERROR, "[Invoking] Unexpected error: " + e.getMessage()); + } + } + + static void callASync(RestApiRequest request, ResponseCallback> callback) { try { Call call = client.newCall(request.request); @@ -147,8 +179,8 @@ static void callASync(RestApiRequest request, ResponseCallback result = new FailedAsyncResult<>( - new HuobiApiException(HuobiApiException.RUNTIME_ERROR, - "[Invoking] Rest api call failed")); + new HuobiApiException(HuobiApiException.RUNTIME_ERROR, + "[Invoking] Rest api call failed")); try { callback.onResponse(result); } catch (Exception exception) { @@ -174,14 +206,14 @@ public void onResponse(Call call, Response response) { return; } catch (Exception e) { FailedAsyncResult result = new FailedAsyncResult<>( - new HuobiApiException( - HuobiApiException.RUNTIME_ERROR, "[Invoking] Rest api call failed")); + new HuobiApiException( + HuobiApiException.RUNTIME_ERROR, "[Invoking] Rest api call failed")); callback.onResponse(result); return; } try { SucceededAsyncResult result = new SucceededAsyncResult<>( - request.jsonParser.parseJson(jsonWrapper)); + request.jsonParser.parseJson(jsonWrapper)); callback.onResponse(result); } catch (Exception e) { log.error("[Invoking] Unexpected error: " + e.getMessage(), e); @@ -191,7 +223,7 @@ public void onResponse(Call call, Response response) { }); } catch (Throwable e) { throw new HuobiApiException( - HuobiApiException.ENV_ERROR, "[Invoking] Unexpected error: " + e.getMessage()); + HuobiApiException.ENV_ERROR, "[Invoking] Unexpected error: " + e.getMessage()); } } @@ -202,6 +234,12 @@ public static void enablePerformanceSwitch(boolean performanceSwitch) { static WebSocket createWebSocket(Request request, WebSocketListener listener) { return client.newWebSocket(request, listener); } + + static WebSocket createWebSocket(Request request, WebSocketListener listener, Proxy proxy) { + client=getBuilder(proxy).build(); + return client.newWebSocket(request, listener); + + } } diff --git a/src/main/java/com/huobi/client/impl/WebSocketConnection.java b/src/main/java/com/huobi/client/impl/WebSocketConnection.java index af74168f..86cb7023 100644 --- a/src/main/java/com/huobi/client/impl/WebSocketConnection.java +++ b/src/main/java/com/huobi/client/impl/WebSocketConnection.java @@ -1,10 +1,12 @@ package com.huobi.client.impl; -import java.io.IOException; -import java.net.URI; - import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; +import com.huobi.client.SubscriptionOptions; +import com.huobi.client.exception.HuobiApiException; +import com.huobi.client.impl.utils.InternalUtils; +import com.huobi.client.impl.utils.JsonWrapper; +import com.huobi.client.impl.utils.UrlParamsBuilder; import okhttp3.Request; import okhttp3.Response; import okhttp3.WebSocket; @@ -13,11 +15,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.huobi.client.SubscriptionOptions; -import com.huobi.client.exception.HuobiApiException; -import com.huobi.client.impl.utils.InternalUtils; -import com.huobi.client.impl.utils.JsonWrapper; -import com.huobi.client.impl.utils.UrlParamsBuilder; +import java.io.IOException; +import java.net.Proxy; +import java.net.URI; import static com.huobi.client.impl.utils.InternalUtils.decode; @@ -68,28 +68,30 @@ public enum ConnectionState { private String subscriptionMarketUrl = "wss://api.huobi.pro/ws"; private String subscriptionTradingUrl = "wss://api.huobi.pro/ws/v1"; private String tradingHost; + private Proxy proxy; WebSocketConnection( - String apiKey, - String secretKey, - SubscriptionOptions options, - WebsocketRequest request, - WebSocketWatchDog watchDog) { + String apiKey, + String secretKey, + SubscriptionOptions options, + WebsocketRequest request, + WebSocketWatchDog watchDog) { this(apiKey, secretKey, options, request, watchDog, false); } WebSocketConnection( - String apiKey, - String secretKey, - SubscriptionOptions options, - WebsocketRequest request, - WebSocketWatchDog watchDog, - boolean autoClose) { + String apiKey, + String secretKey, + SubscriptionOptions options, + WebsocketRequest request, + WebSocketWatchDog watchDog, + boolean autoClose) { this.connectionId = WebSocketConnection.connectionCounter++; this.apiKey = apiKey; this.secretKey = secretKey; this.request = request; this.autoClose = autoClose; + this.proxy=options.getProxy(); try { String host = new URI(options.getUri()).getHost(); this.tradingHost = host; @@ -106,12 +108,12 @@ public enum ConnectionState { } this.okhttpRequest = request.authHandler == null - ? new Request.Builder().url(subscriptionMarketUrl).build() - : new Request.Builder().url(subscriptionTradingUrl).build(); + ? new Request.Builder().url(subscriptionMarketUrl).build() + : new Request.Builder().url(subscriptionTradingUrl).build(); this.watchDog = watchDog; log.info("[Sub] Connection [id: " - + this.connectionId - + "] created for " + request.name); + + this.connectionId + + "] created for " + request.name); } int getConnectionId() { @@ -124,12 +126,12 @@ void connect() { return; } log.info("[Sub][" + this.connectionId + "] Connecting..."); - webSocket = RestApiInvoker.createWebSocket(okhttpRequest, this); + webSocket = RestApiInvoker.createWebSocket(okhttpRequest, this,this.proxy); } void reConnect(int delayInSecond) { log.warn("[Sub][" + this.connectionId + "] Reconnecting after " - + delayInSecond + " seconds later"); + + delayInSecond + " seconds later"); if (webSocket != null) { webSocket.cancel(); webSocket = null; @@ -158,7 +160,7 @@ void send(String str) { } if (!result) { log.error("[Sub][" + this.connectionId - + "] Failed to send message"); + + "] Failed to send message"); closeOnError(); } } @@ -201,7 +203,7 @@ public void onMessage(WebSocket webSocket, ByteString bytes) { try { if (request == null) { log.error("[Sub][" + this.connectionId - + "] request is null"); + + "] request is null"); closeOnError(); return; } @@ -213,19 +215,19 @@ public void onMessage(WebSocket webSocket, ByteString bytes) { data = new String(decode(bytes.toByteArray())); } catch (IOException e) { log.error("[Sub][" + this.connectionId - + "] Receive message error: " + e.getMessage()); + + "] Receive message error: " + e.getMessage()); closeOnError(); return; } log.debug("[On Message][{}] {}", connectionId, data); JsonWrapper jsonWrapper = JsonWrapper.parseFromString(data); if ((jsonWrapper.containKey("status") && !"ok".equals(jsonWrapper.getString("status"))) || - (jsonWrapper.containKey("err-code") && jsonWrapper.getIntegerOrDefault("err-code",999999) > 0)) { + (jsonWrapper.containKey("err-code") && jsonWrapper.getIntegerOrDefault("err-code",999999) > 0)) { String errorCode = jsonWrapper.getStringOrDefault("err-code", ""); String errorMsg = jsonWrapper.getStringOrDefault("err-msg", ""); onError(errorCode + ": " + errorMsg, null); log.error("[Sub][" + this.connectionId - + "] Got error from server: " + errorCode + "; " + errorMsg); + + "] Got error from server: " + errorCode + "; " + errorMsg); close(); } else if (jsonWrapper.containKey("op")) { String op = jsonWrapper.getString("op"); @@ -255,7 +257,7 @@ public void onMessage(WebSocket webSocket, ByteString bytes) { private void onError(String errorMessage, Throwable e) { if (request.errorHandler != null) { HuobiApiException exception = new HuobiApiException( - HuobiApiException.SUBSCRIPTION_ERROR, errorMessage, e); + HuobiApiException.SUBSCRIPTION_ERROR, errorMessage, e); request.errorHandler.onError(exception); } log.error("[Sub][" + this.connectionId + "] " + errorMessage); @@ -280,7 +282,7 @@ private void onReceive(JsonWrapper jsonWrapper) { request.updateCallback.onReceive(obj); } catch (Exception e) { onError("Process error: " + e.getMessage() - + " You should capture the exception in your error handler", e); + + " You should capture the exception in your error handler", e); } } @@ -385,7 +387,7 @@ private void sendAuthV2() { return; } builder.putToUrl(ApiSignature.op, ApiSignature.opValue) - .putToUrl("cid", System.currentTimeMillis()); + .putToUrl("cid", System.currentTimeMillis()); send(builder.buildUrlToJsonString()); } diff --git a/src/test/java/com/huobi/client/examples/SubscribeTradeEvent.java b/src/test/java/com/huobi/client/examples/SubscribeTradeEvent.java index e369a2c7..8bef1e58 100644 --- a/src/test/java/com/huobi/client/examples/SubscribeTradeEvent.java +++ b/src/test/java/com/huobi/client/examples/SubscribeTradeEvent.java @@ -1,8 +1,14 @@ package com.huobi.client.examples; import com.alibaba.fastjson.JSON; - import com.huobi.client.SubscriptionClient; +import com.huobi.client.SubscriptionOptions; +import org.apache.commons.lang.StringUtils; + +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.util.ArrayList; +import java.util.List; public class SubscribeTradeEvent { @@ -10,26 +16,64 @@ public class SubscribeTradeEvent { public static void main(String[] args) { String symbol = "htusdt"; - SubscriptionClient subscriptionClient = SubscriptionClient.create(); - subscriptionClient.subscribeTradeEvent(symbol, tradeEvent -> { + String symbol2 = "btcusdt"; + String symbol3 = "ltcusdt"; + String symbol4 = "etcusdt"; + String symbol5 = "ethusdt"; + String symbol6 = "trxusdt"; + String symbol7 = "xrpusdt"; + String symbol8 = "bsvusdt"; + String symbol9 = "bchusdt"; + String symbol10 = "eosusdt"; + String symbol11= "dashusdt"; + String symbol12 = "ckbusdt"; + SubscriptionOptions options=new SubscriptionOptions(); + String proxyHost="proxy.huobidev.com"; + int proxyPort=3129; + Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort)); + options.setProxy(proxy); + SubscriptionClient subscriptionClient = SubscriptionClient.create("","",options); + List symbols=new ArrayList<>(); + symbols.add(symbol); + symbols.add(symbol2); + symbols.add(symbol3); + symbols.add(symbol4); + symbols.add(symbol5); + symbols.add(symbol6); + symbols.add(symbol7); + symbols.add(symbol8); + symbols.add(symbol9); + symbols.add(symbol10); + symbols.add(symbol11); + String join = StringUtils.join(symbols, ','); + subscriptionClient.subscribeTradeEvent(join, tradeEvent -> { - System.out.println("------------Subscribe Trade Event-------------"); + System.out.println("------------Subscribe Trade Event-------------symbol:"+tradeEvent.getSymbol()); tradeEvent.getTradeList().forEach(trade -> { System.out.println(JSON.toJSONString(trade)); System.out.println("id:" + trade.getTradeId() + " price:" + trade.getPrice() + " amount:" + trade.getAmount() + " direction:" + trade.getDirection()); }); }); - subscriptionClient.requestTradeEvent(symbol, tradeEvent -> { + subscriptionClient.subscribeTradeEvent(symbol2, tradeEvent -> { - System.out.println("------------Request Trade Event-------------"); + System.out.println("------------Subscribe Trade Event-------------symbol:"+tradeEvent.getSymbol()); tradeEvent.getTradeList().forEach(trade -> { System.out.println(JSON.toJSONString(trade)); System.out.println("id:" + trade.getTradeId() + " price:" + trade.getPrice() + " amount:" + trade.getAmount() + " direction:" + trade.getDirection()); }); - }); +// subscriptionClient.requestTradeEvent(symbol, tradeEvent -> { +// +// System.out.println("------------Request Trade Event-------------"); +// tradeEvent.getTradeList().forEach(trade -> { +// System.out.println(JSON.toJSONString(trade)); +// System.out.println("id:" + trade.getTradeId() + " price:" + trade.getPrice() + " amount:" + trade.getAmount() + " direction:" + trade.getDirection()); +// }); +// +// }); + } diff --git a/src/test/java/com/huobi/client/impl/MockWebsocketConnection.java b/src/test/java/com/huobi/client/impl/MockWebsocketConnection.java index 7d15d4c2..1a2e18f4 100644 --- a/src/test/java/com/huobi/client/impl/MockWebsocketConnection.java +++ b/src/test/java/com/huobi/client/impl/MockWebsocketConnection.java @@ -25,6 +25,7 @@ public class MockWebsocketConnection extends WebSocketConnection { this.request = request; } + @Override void connect() { try { mockWebsocket = new MockOkHttpWebsocket(); From 74c5e91b7eaa00846781cce323f704b1e09b9a4d Mon Sep 17 00:00:00 2001 From: guoyingcheng Date: Sat, 5 Dec 2020 17:16:04 +0800 Subject: [PATCH 2/3] commit by test --- src/main/java/com/huobi/client/impl/AccountsInfoMap.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/huobi/client/impl/AccountsInfoMap.java b/src/main/java/com/huobi/client/impl/AccountsInfoMap.java index 00685dc3..1ea0ca08 100644 --- a/src/main/java/com/huobi/client/impl/AccountsInfoMap.java +++ b/src/main/java/com/huobi/client/impl/AccountsInfoMap.java @@ -17,7 +17,6 @@ static void updateUserInfo(String key, RestApiRequestImpl requestImpl) { user.setAccounts(accounts); AccountsInfoMap.userMap.put(key, user); } - static User getUser(String key) { if ("".equals(key) || key == null) { throw new HuobiApiException( From 2b748eb3cd0360f058c3a697c05b3e75df546c7c Mon Sep 17 00:00:00 2001 From: guoyingcheng Date: Sat, 5 Dec 2020 19:13:01 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BB=A3=E7=90=86?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E5=99=A8=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/huobi/constant/HuobiOptions.java | 8 +- src/main/java/com/huobi/constant/Options.java | 4 + .../huobi/connection/HuobiRestConnection.java | 1 + .../com/huobi/utils/ConnectionFactory.java | 171 ++++++++++-------- .../huobi/examples/AccountClientExample.java | 169 ++++++++--------- 5 files changed, 193 insertions(+), 160 deletions(-) diff --git a/src/main/java/com/huobi/constant/HuobiOptions.java b/src/main/java/com/huobi/constant/HuobiOptions.java index 2c90b904..8f5c25a1 100644 --- a/src/main/java/com/huobi/constant/HuobiOptions.java +++ b/src/main/java/com/huobi/constant/HuobiOptions.java @@ -7,6 +7,8 @@ import com.huobi.constant.enums.ExchangeEnum; +import java.net.Proxy; + @Builder @AllArgsConstructor @NoArgsConstructor @@ -22,7 +24,7 @@ public class HuobiOptions implements Options { private String apiKey; private String secretKey; - + private Proxy proxy; @Builder.Default private boolean websocketAutoConnect = true; @@ -56,4 +58,8 @@ public boolean isWebSocketAutoConnect() { return this.websocketAutoConnect; } + @Override + public Proxy getProxy(){ + return this.proxy; + }; } diff --git a/src/main/java/com/huobi/constant/Options.java b/src/main/java/com/huobi/constant/Options.java index 9a4b1683..3fc8d789 100644 --- a/src/main/java/com/huobi/constant/Options.java +++ b/src/main/java/com/huobi/constant/Options.java @@ -2,6 +2,8 @@ import com.huobi.constant.enums.ExchangeEnum; +import java.net.Proxy; + public interface Options { String getApiKey(); @@ -16,4 +18,6 @@ public interface Options { boolean isWebSocketAutoConnect(); + Proxy getProxy(); + } diff --git a/src/main/java/com/huobi/service/huobi/connection/HuobiRestConnection.java b/src/main/java/com/huobi/service/huobi/connection/HuobiRestConnection.java index 7abd8956..ac779ef7 100644 --- a/src/main/java/com/huobi/service/huobi/connection/HuobiRestConnection.java +++ b/src/main/java/com/huobi/service/huobi/connection/HuobiRestConnection.java @@ -26,6 +26,7 @@ public Options getOptions() { public HuobiRestConnection(Options options) { this.options = options; + ConnectionFactory.initFactory(options.getProxy()); try { this.host = new URL(this.options.getRestHost()).getHost(); } catch (MalformedURLException e) { diff --git a/src/main/java/com/huobi/utils/ConnectionFactory.java b/src/main/java/com/huobi/utils/ConnectionFactory.java index 8751c14d..769e520d 100644 --- a/src/main/java/com/huobi/utils/ConnectionFactory.java +++ b/src/main/java/com/huobi/utils/ConnectionFactory.java @@ -1,13 +1,12 @@ package com.huobi.utils; import java.io.IOException; +import java.net.Proxy; +import java.util.Objects; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; +import lombok.*; import okhttp3.ConnectionPool; import okhttp3.Interceptor; import okhttp3.OkHttpClient; @@ -24,94 +23,112 @@ public class ConnectionFactory { - private static Boolean LATENCY_DEBUG_SWATCH = Boolean.FALSE; + private static Boolean LATENCY_DEBUG_SWATCH = Boolean.FALSE; - private static LinkedBlockingQueue LATENCY_DEBUG_QUEUE = new LinkedBlockingQueue<>(); + private static LinkedBlockingQueue LATENCY_DEBUG_QUEUE = new LinkedBlockingQueue<>(); - private static ConnectionPool connectionPool = - new ConnectionPool(20, 300, TimeUnit.SECONDS); + private static ConnectionPool connectionPool = + new ConnectionPool(20, 300, TimeUnit.SECONDS); - private static final OkHttpClient client = new OkHttpClient.Builder() - .followSslRedirects(false) - .followRedirects(false) - .connectTimeout(5000, TimeUnit.MILLISECONDS) - .readTimeout(5000, TimeUnit.MILLISECONDS) - .writeTimeout(5000, TimeUnit.MILLISECONDS) - .connectionPool(connectionPool) - .addNetworkInterceptor(new Interceptor() { - @NotNull - @Override - public Response intercept(@NotNull Chain chain) throws IOException { - Request request = chain.request(); - - Long startNano = System.nanoTime(); - - Response response = chain.proceed(request); + private ConnectionFactory(){} + public static void initFactory(Proxy proxy) { + init(proxy); + } - Long endNano = System.nanoTime(); - if (LATENCY_DEBUG_SWATCH) { - LATENCY_DEBUG_QUEUE.add(new NetworkLatency(request.url().url().getPath(), startNano, endNano)); - } + private static OkHttpClient client; + @Getter + public static OkHttpClient.Builder builder; +// static { +// } - return response; + private static void init(Proxy proxy) { + builder = new OkHttpClient.Builder(); + if (!Objects.isNull(proxy)) { + builder.proxy(proxy); } - }) - .build(); - - private static final Logger log = LoggerFactory.getLogger(ConnectionFactory.class); - - public static String execute(Request request) { - - Response response = null; - String str = null; - try { - log.debug("[Request URL]{}", request.url()); - response = client.newCall(request).execute(); - if (response.code() != 200) { - throw new SDKException(SDKException.EXEC_ERROR, "[Execute] Response Status Error : " + response.code() + " message:" + response.message()); - } - if (response != null && response.body() != null) { - str = response.body().string(); - response.close(); - } else { - throw new SDKException(SDKException.ENV_ERROR, "[Execute] Cannot get the response from server"); - } - log.debug("[Response]{}", str); - return str; - } catch (IOException e) { - e.printStackTrace(); - throw new SDKException(SDKException.RUNTIME_ERROR, "[Execute] Cannot get the response from server"); + client = builder + .followSslRedirects(false) + .followRedirects(false) + .connectTimeout(5000, TimeUnit.MILLISECONDS) + .readTimeout(5000, TimeUnit.MILLISECONDS) + .writeTimeout(5000, TimeUnit.MILLISECONDS) + .connectionPool(connectionPool) + .addNetworkInterceptor(new Interceptor() { + @NotNull + @Override + public Response intercept(@NotNull Chain chain) throws IOException { + Request request = chain.request(); + + Long startNano = System.nanoTime(); + + Response response = chain.proceed(request); + + Long endNano = System.nanoTime(); + + if (LATENCY_DEBUG_SWATCH) { + LATENCY_DEBUG_QUEUE.add(new NetworkLatency(request.url().url().getPath(), startNano, endNano)); + } + + return response; + } + }) + .build(); } - } + private static final Logger log = LoggerFactory.getLogger(ConnectionFactory.class); + + public static String execute(Request request) { + + Response response = null; + String str = null; + try { + log.debug("[Request URL]{}", request.url()); + response = client.newCall(request).execute(); + if (response.code() != 200) { + throw new SDKException(SDKException.EXEC_ERROR, "[Execute] Response Status Error : " + response.code() + " message:" + response.message()); + } + if (response != null && response.body() != null) { + str = response.body().string(); + response.close(); + } else { + throw new SDKException(SDKException.ENV_ERROR, "[Execute] Cannot get the response from server"); + } + log.debug("[Response]{}", str); + return str; + } catch (IOException e) { + e.printStackTrace(); + throw new SDKException(SDKException.RUNTIME_ERROR, "[Execute] Cannot get the response from server"); + } - public static WebSocket createWebSocket(Request request, WebSocketListener listener) { - return client.newWebSocket(request, listener); - } + } - public static void setLatencyDebug() { - LATENCY_DEBUG_SWATCH = Boolean.TRUE; - } + public static WebSocket createWebSocket(Request request, WebSocketListener listener) { + return client.newWebSocket(request, listener); + } - public static LinkedBlockingQueue getLatencyDebugQueue() { - return LATENCY_DEBUG_QUEUE; - } + public static void setLatencyDebug() { + LATENCY_DEBUG_SWATCH = Boolean.TRUE; + } - public static void clearLatencyDebugQueue() { - LATENCY_DEBUG_QUEUE.clear(); - } + public static LinkedBlockingQueue getLatencyDebugQueue() { + return LATENCY_DEBUG_QUEUE; + } - @Data - @Builder - @AllArgsConstructor - @NoArgsConstructor - public static class NetworkLatency { + public static void clearLatencyDebugQueue() { + LATENCY_DEBUG_QUEUE.clear(); + } - private String path; + @Data + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class NetworkLatency { - private Long startNanoTime; + private String path; - private Long endNanoTime; - } + private Long startNanoTime; + + private Long endNanoTime; + } } diff --git a/src/test/java/com/huobi/examples/AccountClientExample.java b/src/test/java/com/huobi/examples/AccountClientExample.java index e93a8822..756cefab 100644 --- a/src/test/java/com/huobi/examples/AccountClientExample.java +++ b/src/test/java/com/huobi/examples/AccountClientExample.java @@ -1,6 +1,8 @@ package com.huobi.examples; import java.math.BigDecimal; +import java.net.InetSocketAddress; +import java.net.Proxy; import java.util.List; import com.huobi.Constants; @@ -34,87 +36,90 @@ public class AccountClientExample { - public static void main(String[] args) { - - Long accountId = 123L; - AccountClient accountService = AccountClient.create(HuobiOptions.builder() - .apiKey(Constants.API_KEY) - .secretKey(Constants.SECRET_KEY) - .build()); - - List accountList = accountService.getAccounts(); - accountList.forEach(account -> { - System.out.println(account.toString()); - }); - - - AccountBalance accountBalance = accountService.getAccountBalance(AccountBalanceRequest.builder() - .accountId(accountId) - .build()); - - System.out.println(accountBalance.getId()); - System.out.println(accountBalance.getType()); - System.out.println(accountBalance.getState()); - accountBalance.getList().forEach(balance -> { - System.out.println(balance.toString()); - }); - - List historyList = accountService.getAccountHistory(AccountHistoryRequest.builder().accountId(accountId).build()); - historyList.forEach(history->{ - System.out.println(history); - }); - - AccountLedgerResult accountLedgerResult = accountService.getAccountLedger(AccountLedgerRequest.builder() - .accountId(accountId) - .limit(2) - .build()); - System.out.println("leger nextId: " + accountLedgerResult.getNextId()); - accountLedgerResult.getLedgerList().forEach(ledger -> { - System.out.println(ledger); - }); - - - accountService.subAccountsUpdate(SubAccountUpdateRequest.builder() - .accountUpdateMode(AccountUpdateModeEnum.ACCOUNT_CHANGE).build(), event -> { - System.out.println(event.toString()); - }); - - - AccountTransferResult accountTransferResult = accountService.accountTransfer(AccountTransferRequest.builder() - .fromUser(123L) - .fromAccount(456L) - .fromAccountType(AccountTransferAccountTypeEnum.SPOT) - .toUser(678L) - .toAccount(789L) - .toAccountType(AccountTransferAccountTypeEnum.MARGIN) - .currency("usdt") - .amount(new BigDecimal("10")) - .build()); - - System.out.println("account transfer result:"+accountTransferResult.toString()); - - AccountFuturesTransferResult accountFuturesTransferResult = accountService.accountFuturesTransfer(AccountFuturesTransferRequest.builder() - .currency("xrp") - .amount(new BigDecimal("5")) - .type(AccountFuturesTransferTypeEnum.PRO_TO_FUTURES) - .build()); - - System.out.println("account futures result:"+accountFuturesTransferResult.toString()); - - Point point = accountService.getPoint(PointRequest.builder().build()); - System.out.println("get point: " + point); - - - PointTransferResult pointTransferResult = accountService.pointTransfer(PointTransferRequest.builder() - .fromUid(123L) - .toUid(123L) - .groupId(123L) - .amount(BigDecimal.ONE) - .build()); - System.out.println(pointTransferResult); - - AccountAssetValuationResult accountAssetValuationResult = accountService.accountAssetValuation(AccountAssetValuationRequest.builder().accountType(AccountTypeEnum.SPOT).build()); - System.out.println(accountAssetValuationResult); - } + public static void main(String[] args) { + + Long accountId = 123L; + Proxy proxyTest = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 3189)); + + AccountClient accountService = AccountClient.create(HuobiOptions.builder() + .apiKey(Constants.API_KEY) + .secretKey(Constants.SECRET_KEY) + .proxy(proxyTest) + .build()); + + List accountList = accountService.getAccounts(); + accountList.forEach(account -> { + System.out.println(account.toString()); + }); + + + AccountBalance accountBalance = accountService.getAccountBalance(AccountBalanceRequest.builder() + .accountId(accountId) + .build()); + + System.out.println(accountBalance.getId()); + System.out.println(accountBalance.getType()); + System.out.println(accountBalance.getState()); + accountBalance.getList().forEach(balance -> { + System.out.println(balance.toString()); + }); + + List historyList = accountService.getAccountHistory(AccountHistoryRequest.builder().accountId(accountId).build()); + historyList.forEach(history -> { + System.out.println(history); + }); + + AccountLedgerResult accountLedgerResult = accountService.getAccountLedger(AccountLedgerRequest.builder() + .accountId(accountId) + .limit(2) + .build()); + System.out.println("leger nextId: " + accountLedgerResult.getNextId()); + accountLedgerResult.getLedgerList().forEach(ledger -> { + System.out.println(ledger); + }); + + + accountService.subAccountsUpdate(SubAccountUpdateRequest.builder() + .accountUpdateMode(AccountUpdateModeEnum.ACCOUNT_CHANGE).build(), event -> { + System.out.println(event.toString()); + }); + + + AccountTransferResult accountTransferResult = accountService.accountTransfer(AccountTransferRequest.builder() + .fromUser(123L) + .fromAccount(456L) + .fromAccountType(AccountTransferAccountTypeEnum.SPOT) + .toUser(678L) + .toAccount(789L) + .toAccountType(AccountTransferAccountTypeEnum.MARGIN) + .currency("usdt") + .amount(new BigDecimal("10")) + .build()); + + System.out.println("account transfer result:" + accountTransferResult.toString()); + + AccountFuturesTransferResult accountFuturesTransferResult = accountService.accountFuturesTransfer(AccountFuturesTransferRequest.builder() + .currency("xrp") + .amount(new BigDecimal("5")) + .type(AccountFuturesTransferTypeEnum.PRO_TO_FUTURES) + .build()); + + System.out.println("account futures result:" + accountFuturesTransferResult.toString()); + + Point point = accountService.getPoint(PointRequest.builder().build()); + System.out.println("get point: " + point); + + + PointTransferResult pointTransferResult = accountService.pointTransfer(PointTransferRequest.builder() + .fromUid(123L) + .toUid(123L) + .groupId(123L) + .amount(BigDecimal.ONE) + .build()); + System.out.println(pointTransferResult); + + AccountAssetValuationResult accountAssetValuationResult = accountService.accountAssetValuation(AccountAssetValuationRequest.builder().accountType(AccountTypeEnum.SPOT).build()); + System.out.println(accountAssetValuationResult); + } }