一、OkSocket简介
- OkSocket是一款基于阻塞式传统Socket的一款Socket客户端整体解决方案.你可以使用它进行基于Tcp协议的Socket通讯.就是我们所说的长连接.
- 对通讯协议几乎无限制,可以使用PB,可以使用JSON,可以使用XML.只要可以序列化成Byte数组的对象都可以传输.
- 兼容所有语言写的Socket服务端,解决了Tcp通讯中头疼的粘包拆包问题,断线重连问题,心跳保持问题,分片发送,重定向连接等问题.
- 针对 手机 < - > 服务器 , 手机< - > 手机 间都可以进行tcp通讯,手机间通讯俗称点对点通讯,可以很好的支持.
- OkSocket还支持单工和全双工通讯.适配各种复杂业务场景.分为 客户端(OkSocketClient) 服务端(OkSocketServer)具体的继承和依赖方法在下面.
二、配置
配置仓库
allprojects {
repositories {
jcenter()
}
}
加入build.gradle文件
compile 'com.tonystark.android:socket:latest.release'
compile 'com.tonystark.android:socket-server:latest.release'
添加AndroidManifest.xml文件权限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
加入proguard-rules.pro内容,避免混淆
-dontwarn com.xuhao.didi.socket.client.**
-dontwarn com.xuhao.didi.socket.common.**
-dontwarn com.xuhao.didi.socket.server.**
-dontwarn com.xuhao.didi.core.**
-keep class com.xuhao.didi.socket.client.** { *; }
-keep class com.xuhao.didi.socket.common.** { *; }
-keep class com.xuhao.didi.socket.server.** { *; }
-keep class com.xuhao.didi.core.** { *; }
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class com.xuhao.didi.socket.client.sdk.client.OkSocketOptions$* {
*;
}
-keep class com.xuhao.didi.socket.server.impl.OkServerOptions$* {
*;
}
三、服务端
服务端初始化代码
server = OkSocket.server(30012); // 创建服务器
IServerManager serverManager = server.registerReceiver(serverActionListener);// 注册回调
serverManager.listen();// 开启监听
服务端反初始化代码
server.unRegisterReceiver(serverActionListener); // 解除注册
服务端回调监听代码
IRegister<IServerActionListener, IServerManager> server;
IServerActionListener serverActionListener = new IServerActionListener() {
@Override
public void onServerListening(int serverPort) {
Log.d(TAG,"服务器启动完成.正在监听端口:" + serverPort);
}
@Override
public void onClientConnected(IClient client, int serverPort, IClientPool clientPool) {
Log.d(TAG, client.getUniqueTag() + " 客户端已连接");
client.addIOCallback(new IClientIOCallback() {
@Override
public void onClientRead(OriginalData originalData, IClient client, IClientPool<IClient, String> clientPool) {
String str = new String(originalData.getBodyBytes(), Charset.forName("utf-8"));
if(str.equals("pause")){ //是否是心跳返回包,若是心跳包则发送应答包
Log.d(TAG,"收到客户端"+client.getUniqueTag()+"的心跳数据:"+str);
client.send(new ISendable() {
@Override
public byte[] parse() {
byte[] body = "ack".getBytes(Charset.defaultCharset()); // 心跳响应数据
ByteBuffer bb = ByteBuffer.allocate(4 + body.length);
bb.order(ByteOrder.BIG_ENDIAN);
bb.putInt(body.length);
bb.put(body);
return bb.array();
}
});
}else {
Log.d(TAG,"收到客户端"+client.getUniqueTag()+"的指令");
}
}
@Override
public void onClientWrite(ISendable sendable, IClient client, IClientPool<IClient, String> clientPool) {
Log.d(TAG,"发送数据到客户端:"+new String(sendable.parse(),Charset.forName("utf-8")));
}
});
}
@Override
public void onClientDisconnected(IClient client, int serverPort, IClientPool clientPool) {
Log.d(TAG, client.getUniqueTag() + " 客户端已断开连接");
client.removeAllIOCallback();
}
@Override
public void onServerWillBeShutdown(int serverPort, IServerShutdown shutdown, IClientPool clientPool, Throwable throwable) {
Log.d(TAG, "服务器即将关闭");
}
@Override
public void onServerAlreadyShutdown(int serverPort) {
Log.d(TAG, "服务器已经关闭,serverPort="+serverPort);
}
};
四、客户端
客户端初始化代码
ConnectionInfo info = new ConnectionInfo("192.168.43.1", 30012);//连接参数设置(IP,端口号)
mManager = OkSocket.open(info);//调用OkSocket,开启这次连接的通道,拿到通道Manager
mManager.registerReceiver(socketActionAdapter);//注册Socket行为监听器
mManager.connect();//调用通道进行连接
客户端发送数据
客户端反初始化代码
mManager.disconnect();//断开连接
mManager.unRegisterReceiver(socketActionAdapter); // 取消注册监听
客户端回调代码
IConnectionManager mManager;
SocketActionAdapter socketActionAdapter = new SocketActionAdapter() {
@Override
public void onSocketIOThreadStart(String action) {
super.onSocketIOThreadStart(action);
}
@Override
public void onSocketIOThreadShutdown(String action, Exception e) {
super.onSocketIOThreadShutdown(action, e);
}
@Override
public void onSocketDisconnection(ConnectionInfo info, String action, Exception e) {
super.onSocketDisconnection(info, action, e);
//断开连接
Log.d(TAG, "断开服务器连接");
}
@Override
public void onSocketConnectionSuccess(ConnectionInfo info, String action) {
super.onSocketConnectionSuccess(info, action);
Log.d(TAG, "客户端连接服务器成功,开启心跳");
//连接成功,开启心跳
OkSocket.open(info)
.getPulseManager()
.setPulseSendable(new IPulseSendable() {
@Override
public byte[] parse() {
byte[] body = "pause".getBytes(Charset.defaultCharset()); // 心跳数据
ByteBuffer bb = ByteBuffer.allocate(4 + body.length);
bb.order(ByteOrder.BIG_ENDIAN);
bb.putInt(body.length);
bb.put(body);
return bb.array();
}
})
.pulse();//开始心跳,开始心跳后,心跳管理器会自动进行心跳触发
}
@Override
public void onSocketConnectionFailed(ConnectionInfo info, String action, Exception e) {
super.onSocketConnectionFailed(info, action, e);
Log.d(TAG, "客户端连接服务器失败");
}
@Override
public void onSocketReadResponse(ConnectionInfo info, String action, OriginalData data) {
String str = new String(data.getBodyBytes(), Charset.forName("utf-8"));
Log.d(TAG, "客户端读取数据回调" + str);
if (mManager != null && str.equals("ack")) {//是否是心跳返回包,需要解析服务器返回的数据才可知道
Log.d(TAG, "客户端喂狗");//喂狗操作
mManager.getPulseManager().feed();
}
super.onSocketReadResponse(info, action, data);
}
@Override
public void onSocketWriteResponse(ConnectionInfo info, String action, ISendable data) {
Log.d(TAG, "客户端发送数据回调");
super.onSocketWriteResponse(info, action, data);
}
@Override
public void onPulseSend(ConnectionInfo info, IPulseSendable data) {
Log.d(TAG, "客户端发送心跳包");
super.onPulseSend(info, data);
}
};