-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #148 from crossoverJie/feature/client-sdk
Client SDK
- Loading branch information
Showing
91 changed files
with
1,931 additions
and
1,657 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<parent> | ||
<groupId>com.crossoverjie.netty</groupId> | ||
<artifactId>cim</artifactId> | ||
<version>1.0.0-SNAPSHOT</version> | ||
</parent> | ||
|
||
<artifactId>cim-client-sdk</artifactId> | ||
|
||
<properties> | ||
<maven.compiler.source>17</maven.compiler.source> | ||
<maven.compiler.target>17</maven.compiler.target> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
</properties> | ||
|
||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>com.crossoverjie.netty</groupId> | ||
<artifactId>cim-common</artifactId> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>com.crossoverjie.netty</groupId> | ||
<artifactId>cim-rout-api</artifactId> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.junit.jupiter</groupId> | ||
<artifactId>junit-jupiter</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.junit.vintage</groupId> | ||
<artifactId>junit-vintage-engine</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.crossoverjie.netty</groupId> | ||
<artifactId>cim-integration-test</artifactId> | ||
<version>${project.version}</version> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
|
||
</project> |
39 changes: 39 additions & 0 deletions
39
cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/Client.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package com.crossoverjie.cim.client.sdk; | ||
|
||
import com.crossoverjie.cim.client.sdk.impl.ClientBuilderImpl; | ||
import com.crossoverjie.cim.client.sdk.impl.ClientConfigurationData; | ||
import com.crossoverjie.cim.common.pojo.CIMUserInfo; | ||
import com.crossoverjie.cim.route.api.vo.req.P2PReqVO; | ||
import com.crossoverjie.cim.route.api.vo.res.CIMServerResVO; | ||
import java.io.Closeable; | ||
import java.util.Optional; | ||
import java.util.Set; | ||
import java.util.concurrent.CompletableFuture; | ||
|
||
public interface Client extends Closeable { | ||
|
||
static ClientBuilder builder() { | ||
return new ClientBuilderImpl(); | ||
} | ||
|
||
default void sendP2P(P2PReqVO p2PReqVO) throws Exception{ | ||
sendP2PAsync(p2PReqVO).get(); | ||
}; | ||
|
||
CompletableFuture<Void> sendP2PAsync(P2PReqVO p2PReqVO); | ||
|
||
default void sendGroup(String msg) throws Exception{ | ||
sendGroupAsync(msg).get(); | ||
}; | ||
|
||
CompletableFuture<Void> sendGroupAsync(String msg); | ||
|
||
ClientState.State getState(); | ||
|
||
ClientConfigurationData.Auth getAuth(); | ||
|
||
Set<CIMUserInfo> getOnlineUser() throws Exception; | ||
|
||
Optional<CIMServerResVO> getServerInfo(); | ||
|
||
} |
23 changes: 23 additions & 0 deletions
23
cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/ClientBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package com.crossoverjie.cim.client.sdk; | ||
|
||
import com.crossoverjie.cim.client.sdk.impl.ClientConfigurationData; | ||
import com.crossoverjie.cim.client.sdk.io.MessageListener; | ||
import com.crossoverjie.cim.client.sdk.io.ReconnectCheck; | ||
import java.util.concurrent.ThreadPoolExecutor; | ||
import okhttp3.OkHttpClient; | ||
|
||
/** | ||
* @author crossoverJie | ||
*/ | ||
public interface ClientBuilder { | ||
|
||
Client build(); | ||
ClientBuilder auth(ClientConfigurationData.Auth auth); | ||
ClientBuilder routeUrl(String routeUrl); | ||
ClientBuilder loginRetryCount(int loginRetryCount); | ||
ClientBuilder event(Event event); | ||
ClientBuilder reconnectCheck(ReconnectCheck reconnectCheck); | ||
ClientBuilder okHttpClient(OkHttpClient okHttpClient); | ||
ClientBuilder messageListener(MessageListener messageListener); | ||
ClientBuilder callbackThreadPool(ThreadPoolExecutor callbackThreadPool); | ||
} |
23 changes: 23 additions & 0 deletions
23
cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/ClientState.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package com.crossoverjie.cim.client.sdk; | ||
|
||
import java.util.concurrent.atomic.AtomicReference; | ||
|
||
public abstract class ClientState { | ||
|
||
private static final AtomicReference<State> STATE = new AtomicReference<>(State.Initialized); | ||
|
||
public enum State { | ||
/** | ||
* Client state | ||
*/ | ||
Initialized, Reconnecting, Ready, Closed, Failed | ||
} | ||
|
||
public void setState(State s) { | ||
STATE.set(s); | ||
} | ||
|
||
public State getState() { | ||
return STATE.get(); | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/Event.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package com.crossoverjie.cim.client.sdk; | ||
|
||
public interface Event { | ||
void debug(String msg, Object... replace); | ||
void info(String msg, Object... replace); | ||
void warn(String msg, Object... replace); | ||
void error(String msg, Object... replace); | ||
void fatal(Client client); | ||
|
||
class DefaultEvent implements Event { | ||
@Override | ||
public void debug(String msg, Object... replace) { | ||
System.out.println(msg); | ||
} | ||
|
||
@Override | ||
public void info(String msg, Object... replace) { | ||
System.out.println(msg); | ||
} | ||
|
||
@Override | ||
public void warn(String msg, Object... replace) { | ||
System.out.println(msg); | ||
} | ||
|
||
@Override | ||
public void error(String msg, Object... replace) { | ||
System.err.println(msg); | ||
} | ||
|
||
@Override | ||
public void fatal(Client client) { | ||
|
||
} | ||
} | ||
} |
69 changes: 69 additions & 0 deletions
69
cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/ReConnectManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package com.crossoverjie.cim.client.sdk; | ||
|
||
import com.crossoverjie.cim.client.sdk.impl.ClientImpl; | ||
import com.crossoverjie.cim.common.kit.HeartBeatHandler; | ||
import com.google.common.util.concurrent.ThreadFactoryBuilder; | ||
import io.netty.channel.ChannelHandlerContext; | ||
import java.util.concurrent.ScheduledExecutorService; | ||
import java.util.concurrent.ScheduledThreadPoolExecutor; | ||
import java.util.concurrent.ThreadFactory; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
public final class ReConnectManager { | ||
|
||
private ScheduledExecutorService scheduledExecutorService; | ||
|
||
/** | ||
* Trigger reconnect job | ||
* | ||
* @param ctx | ||
*/ | ||
public void reConnect(ChannelHandlerContext ctx) { | ||
buildExecutor(); | ||
scheduledExecutorService.scheduleAtFixedRate(() -> { | ||
try { | ||
ClientImpl.getClient().getHeartBeatHandler().process(ctx); | ||
} catch (Exception e) { | ||
ClientImpl.getClient().getConf().getEvent().error("ReConnectManager reConnect error", e); | ||
} | ||
}, | ||
0, 10, TimeUnit.SECONDS); | ||
} | ||
|
||
/** | ||
* Close reconnect job if reconnect success. | ||
*/ | ||
public void reConnectSuccess() { | ||
scheduledExecutorService.shutdown(); | ||
} | ||
|
||
|
||
/*** | ||
* build a thread executor | ||
*/ | ||
private void buildExecutor() { | ||
if (scheduledExecutorService == null || scheduledExecutorService.isShutdown()) { | ||
ThreadFactory factory = new ThreadFactoryBuilder() | ||
.setNameFormat("reConnect-job-%d") | ||
.setDaemon(true) | ||
.build(); | ||
scheduledExecutorService = new ScheduledThreadPoolExecutor(1, factory); | ||
} | ||
} | ||
|
||
private static class ClientHeartBeatHandle implements HeartBeatHandler { | ||
|
||
@Override | ||
public void process(ChannelHandlerContext ctx) throws Exception { | ||
ClientImpl.getClient().reconnect(); | ||
} | ||
} | ||
|
||
public static ReConnectManager createReConnectManager() { | ||
return new ReConnectManager(); | ||
} | ||
|
||
public static HeartBeatHandler createHeartBeatHandler() { | ||
return new ClientHeartBeatHandle(); | ||
} | ||
} |
81 changes: 81 additions & 0 deletions
81
cim-client-sdk/src/main/java/com/crossoverjie/cim/client/sdk/RouteManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package com.crossoverjie.cim.client.sdk; | ||
|
||
import com.crossoverjie.cim.client.sdk.impl.ClientImpl; | ||
import com.crossoverjie.cim.common.core.proxy.RpcProxyManager; | ||
import com.crossoverjie.cim.common.enums.StatusEnum; | ||
import com.crossoverjie.cim.common.exception.CIMException; | ||
import com.crossoverjie.cim.common.pojo.CIMUserInfo; | ||
import com.crossoverjie.cim.common.res.BaseResponse; | ||
import com.crossoverjie.cim.common.res.NULLBody; | ||
import com.crossoverjie.cim.route.api.RouteApi; | ||
import com.crossoverjie.cim.route.api.vo.req.ChatReqVO; | ||
import com.crossoverjie.cim.route.api.vo.req.LoginReqVO; | ||
import com.crossoverjie.cim.route.api.vo.req.P2PReqVO; | ||
import com.crossoverjie.cim.route.api.vo.res.CIMServerResVO; | ||
import java.util.Optional; | ||
import java.util.Set; | ||
import java.util.concurrent.CompletableFuture; | ||
import okhttp3.OkHttpClient; | ||
|
||
public class RouteManager { | ||
|
||
|
||
private final RouteApi routeApi; | ||
private final Event event; | ||
|
||
public RouteManager(String routeUrl, OkHttpClient okHttpClient, Event event) { | ||
routeApi = RpcProxyManager.create(RouteApi.class, routeUrl, okHttpClient); | ||
this.event = event; | ||
} | ||
|
||
public CIMServerResVO getServer(LoginReqVO loginReqVO) throws Exception { | ||
BaseResponse<CIMServerResVO> cimServerResVO = routeApi.login(loginReqVO); | ||
|
||
// repeat fail | ||
if (!cimServerResVO.getCode().equals(StatusEnum.SUCCESS.getCode())) { | ||
event.info(cimServerResVO.getMessage()); | ||
|
||
// when client in Reconnecting state, could exit. | ||
if (ClientImpl.getClient().getState() == ClientState.State.Reconnecting) { | ||
event.warn("###{}###", StatusEnum.RECONNECT_FAIL.getMessage()); | ||
throw new CIMException(StatusEnum.RECONNECT_FAIL); | ||
} | ||
} | ||
return cimServerResVO.getDataBody(); | ||
} | ||
|
||
public CompletableFuture<Void> sendP2P(CompletableFuture<Void> future, P2PReqVO p2PReqVO) { | ||
return CompletableFuture.runAsync(() -> { | ||
try { | ||
BaseResponse<NULLBody> response = routeApi.p2pRoute(p2PReqVO); | ||
if (response.getCode().equals(StatusEnum.OFF_LINE.getCode())) { | ||
future.completeExceptionally(new CIMException(StatusEnum.OFF_LINE)); | ||
} | ||
future.complete(null); | ||
} catch (Exception e) { | ||
future.completeExceptionally(e); | ||
event.error("send p2p msg error", e); | ||
} | ||
}); | ||
} | ||
|
||
public CompletableFuture<Void> sendGroupMsg(ChatReqVO chatReqVO) { | ||
return CompletableFuture.runAsync(() -> { | ||
try { | ||
routeApi.groupRoute(chatReqVO); | ||
} catch (Exception e) { | ||
event.error("send group msg error", e); | ||
} | ||
}); | ||
} | ||
|
||
public void offLine(Long userId) { | ||
ChatReqVO vo = new ChatReqVO(userId, "offLine"); | ||
routeApi.offLine(vo); | ||
} | ||
|
||
public Set<CIMUserInfo> onlineUser() throws Exception { | ||
BaseResponse<Set<CIMUserInfo>> onlineUsersResVO = routeApi.onlineUser(); | ||
return onlineUsersResVO.getDataBody(); | ||
} | ||
} |
Oops, something went wrong.