diff --git a/cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/ClientBuilder.java b/cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/ClientBuilder.java index 4ef802b0..783b3b3c 100644 --- a/cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/ClientBuilder.java +++ b/cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/ClientBuilder.java @@ -4,6 +4,8 @@ import com.crossoverjie.cim.client.sdk.io.MessageListener; import com.crossoverjie.cim.client.sdk.io.ReconnectCheck; import java.util.concurrent.ThreadPoolExecutor; + +import com.crossoverjie.cim.client.sdk.io.backoff.BackoffStrategy; import okhttp3.OkHttpClient; /** @@ -20,4 +22,5 @@ public interface ClientBuilder { ClientBuilder okHttpClient(OkHttpClient okHttpClient); ClientBuilder messageListener(MessageListener messageListener); ClientBuilder callbackThreadPool(ThreadPoolExecutor callbackThreadPool); + ClientBuilder backoffStrategy(BackoffStrategy backoffStrategy); } diff --git a/cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/impl/ClientBuilderImpl.java b/cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/impl/ClientBuilderImpl.java index 8779f755..d5d7ea01 100644 --- a/cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/impl/ClientBuilderImpl.java +++ b/cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/impl/ClientBuilderImpl.java @@ -5,9 +5,16 @@ import com.crossoverjie.cim.client.sdk.Event; import com.crossoverjie.cim.client.sdk.io.MessageListener; import com.crossoverjie.cim.client.sdk.io.ReconnectCheck; +import com.crossoverjie.cim.client.sdk.io.backoff.BackoffStrategy; +import com.crossoverjie.cim.client.sdk.io.backoff.RandomBackoff; import com.crossoverjie.cim.common.util.StringUtil; + +import java.lang.reflect.Constructor; +import java.util.ServiceLoader; import java.util.concurrent.ThreadPoolExecutor; import okhttp3.OkHttpClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ClientBuilderImpl implements ClientBuilder { @@ -79,4 +86,10 @@ public ClientBuilder callbackThreadPool(ThreadPoolExecutor callbackThreadPool) { this.conf.setCallbackThreadPool(callbackThreadPool); return this; } + + @Override + public ClientBuilder backoffStrategy(BackoffStrategy backoffStrategy) { + this.conf.setBackoffStrategy(backoffStrategy); + return this; + } } diff --git a/cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/impl/ClientConfigurationData.java b/cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/impl/ClientConfigurationData.java index 0ed24417..a9b95562 100644 --- a/cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/impl/ClientConfigurationData.java +++ b/cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/impl/ClientConfigurationData.java @@ -1,7 +1,9 @@ package com.crossoverjie.cim.client.sdk.impl; import com.crossoverjie.cim.client.sdk.Event; +import com.crossoverjie.cim.client.sdk.io.backoff.BackoffStrategy; import com.crossoverjie.cim.client.sdk.io.MessageListener; +import com.crossoverjie.cim.client.sdk.io.backoff.RandomBackoff; import com.crossoverjie.cim.client.sdk.io.ReconnectCheck; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @@ -46,4 +48,7 @@ public static class Auth{ @JsonIgnore private ReconnectCheck reconnectCheck = (client) -> true; + + @JsonIgnore + private BackoffStrategy backoffStrategy = new RandomBackoff(); } diff --git a/cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/impl/ClientImpl.java b/cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/impl/ClientImpl.java index dbd3c0ca..931405bb 100644 --- a/cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/impl/ClientImpl.java +++ b/cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/impl/ClientImpl.java @@ -202,9 +202,7 @@ public void reconnect() throws Exception { this.conf.getEvent().info("cim trigger reconnecting...."); - // TODO: 2024/9/13 need a backoff interface - int random = (int) (Math.random() * 7 + 3); - TimeUnit.SECONDS.sleep(random); + this.conf.getBackoffStrategy().runBackoff(); // don't set State ready, because when connect success, the State will be set to ready automate. connectServer(v -> { diff --git a/cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/io/backoff/BackoffStrategy.java b/cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/io/backoff/BackoffStrategy.java new file mode 100644 index 00000000..eed72b3a --- /dev/null +++ b/cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/io/backoff/BackoffStrategy.java @@ -0,0 +1,24 @@ +package com.crossoverjie.cim.client.sdk.io.backoff; + +import java.util.concurrent.TimeUnit; + +/** + * @author:qjj + * @create: 2024-09-21 12:16 + * @Description: backoff strategy interface + */ + +public interface BackoffStrategy { + /** + * @return the backoff time in milliseconds + */ + long nextBackoff(); + + /** + * Run the backoff strategy + * @throws InterruptedException + */ + default void runBackoff() throws InterruptedException { + TimeUnit.SECONDS.sleep(nextBackoff()); + } +} diff --git a/cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/io/backoff/RandomBackoff.java b/cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/io/backoff/RandomBackoff.java new file mode 100644 index 00000000..89d663b1 --- /dev/null +++ b/cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/io/backoff/RandomBackoff.java @@ -0,0 +1,19 @@ +package com.crossoverjie.cim.client.sdk.io.backoff; + +import java.util.concurrent.TimeUnit; + +/** + * @author:qjj + * @create: 2024-09-21 12:22 + * @Description: random backoff strategy + */ + +public class RandomBackoff implements BackoffStrategy { + + @Override + public long nextBackoff() { + int random = (int) (Math.random() * 7 + 3); + return random; + } + +} diff --git a/cim-client-sdk/src/test/java/com/crossoverjie/cim/client/sdk/ClientTest.java b/cim-client-sdk/src/test/java/com/crossoverjie/cim/client/sdk/ClientTest.java index bc51afaf..54dca1ea 100644 --- a/cim-client-sdk/src/test/java/com/crossoverjie/cim/client/sdk/ClientTest.java +++ b/cim-client-sdk/src/test/java/com/crossoverjie/cim/client/sdk/ClientTest.java @@ -1,6 +1,7 @@ package com.crossoverjie.cim.client.sdk; import com.crossoverjie.cim.client.sdk.impl.ClientConfigurationData; +import com.crossoverjie.cim.client.sdk.io.backoff.RandomBackoff; import com.crossoverjie.cim.client.sdk.route.AbstractRouteBaseTest; import com.crossoverjie.cim.common.pojo.CIMUserInfo; import com.crossoverjie.cim.route.api.vo.req.P2PReqVO; @@ -224,11 +225,13 @@ public void testReconnect() throws Exception { .userName(zs) .userId(zsId) .build(); + var backoffStrategy = new RandomBackoff(); @Cleanup Client client1 = Client.builder() .auth(auth1) .routeUrl(routeUrl) + .backoffStrategy(backoffStrategy) .build(); TimeUnit.SECONDS.sleep(3); ClientState.State state = client1.getState(); @@ -242,6 +245,7 @@ public void testReconnect() throws Exception { .auth(auth2) .routeUrl(routeUrl) .messageListener((client, message) -> client2Receive.set(message)) + .backoffStrategy(backoffStrategy) .build(); TimeUnit.SECONDS.sleep(3); ClientState.State state2 = client2.getState(); diff --git a/cim-client/src/main/java/com/crossoverjie/cim/client/config/BeanConfig.java b/cim-client/src/main/java/com/crossoverjie/cim/client/config/BeanConfig.java index 2845dcba..170eca64 100644 --- a/cim-client/src/main/java/com/crossoverjie/cim/client/config/BeanConfig.java +++ b/cim-client/src/main/java/com/crossoverjie/cim/client/config/BeanConfig.java @@ -3,6 +3,7 @@ import com.crossoverjie.cim.client.sdk.Client; import com.crossoverjie.cim.client.sdk.Event; import com.crossoverjie.cim.client.sdk.impl.ClientConfigurationData; +import com.crossoverjie.cim.client.sdk.io.backoff.RandomBackoff; import com.crossoverjie.cim.client.service.MsgLogger; import com.crossoverjie.cim.client.service.ShutDownSign; import com.crossoverjie.cim.client.service.impl.MsgCallBackListener; @@ -61,6 +62,7 @@ public Client buildClient(@Qualifier("callBackThreadPool") ThreadPoolExecutor ca .okHttpClient(okHttpClient) .messageListener(new MsgCallBackListener(msgLogger)) .callbackThreadPool(callbackThreadPool) + .backoffStrategy(new RandomBackoff()) .build(); } diff --git a/cim-client/src/main/resources/application.yaml b/cim-client/src/main/resources/application.yaml index d1d3e495..862f1f59 100644 --- a/cim-client/src/main/resources/application.yaml +++ b/cim-client/src/main/resources/application.yaml @@ -1,37 +1,37 @@ -spring: - application: - name: cim-client - -# web port -server: - port: 8082 - -logging: - level: - root: error - -# enable swagger -springdoc: - swagger-ui: - enabled: true - -# log path -cim: - msg: - logger: - path: /opt/logs/cim/ - route: - url: http://localhost:8083 # route url suggested that this is Nginx address - user: # cim userId and userName - id: 1725714450795 - userName: cj4 - callback: - thread: - queue: - size: 2 - pool: - size: 2 - heartbeat: - time: 60 # cim heartbeat time (seconds) - reconnect: - count: 3 \ No newline at end of file +spring: + application: + name: cim-client + +# web port +server: + port: 8082 + +logging: + level: + root: error + +# enable swagger +springdoc: + swagger-ui: + enabled: true + +# log path +cim: + msg: + logger: + path: /opt/logs/cim/ + route: + url: http://localhost:8083 # route url suggested that this is Nginx address + user: # cim userId and userName + id: 1725714450795 + userName: cj4 + callback: + thread: + queue: + size: 2 + pool: + size: 2 + heartbeat: + time: 60 # cim heartbeat time (seconds) + reconnect: + count: 3