详解OkSocket与Android的简单使用

一个Android轻量级Socket通讯框架,既OkHttp后又一力作.

框架开源地址: https://github.com/xuuhaoo/OkSocket,欢迎star,fork,Issue交流

OkSocket简介

Android OkSocket是一款基于阻塞式传统Socket的一款Socket客户端整体解决方案.您可以使用它进行简单的基于Tcp协议的Socket通讯,当然,也可以进行大数据量复杂的Socket通讯,
支持单工,双工通讯.

Maven配置

OkSocket 目前仅支持 JCenter 仓库

allprojects {
  repositories {
    jcenter()
  }
}

在Module的build.gradle文件中添加依赖配置

dependencies {
  compile 'com.tonystark.android:socket:1.0.0'
}

参数配置

在AndroidManifest.xml中添加权限:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

混淆配置

请避免混淆OkSocket,在Proguard混淆文件中增加以下配置:

-dontwarn com.xuhao.android.libsocket.**
-keep class com.xuhao.android.socket.impl.abilities.** { *; }
-keep class com.xuhao.android.socket.impl.exceptions.** { *; }
-keep class com.xuhao.android.socket.impl.EnvironmentalManager { *; }
-keep class com.xuhao.android.socket.impl.BlockConnectionManager { *; }
-keep class com.xuhao.android.socket.impl.UnBlockConnectionManager { *; }
-keep class com.xuhao.android.socket.impl.SocketActionHandler { *; }
-keep class com.xuhao.android.socket.impl.PulseManager { *; }
-keep class com.xuhao.android.socket.impl.ManagerHolder { *; }
-keep class com.xuhao.android.socket.interfaces.** { *; }
-keep class com.xuhao.android.socket.sdk.** { *; }
# 枚举类不能被混淆
-keepclassmembers enum * {
  public static **[] values();
  public static ** valueOf(java.lang.String);
}
-keep class com.xuhao.android.socket.sdk.OkSocketOptions$* {
  *;
}

OkSocket初始化

将以下代码复制到项目Application类onCreate()中,OkSocket会为自动检测环境并完成配置:

public class MyApplication extends Application {
  @Override
  public void onCreate() {
    super.onCreate();
    //在主进程初始化一次,多进程时需要区分主进程.
    OkSocket.initialize(this);
    //如果需要开启Socket调试日志,请配置
    //OkSocket.initialize(this,true);
  }
}

调用演示

测试服务器

该服务器是专门为初学者调试 OkSocket 库部属的一台测试服务器,初学者可以将项目中的 app 安装到手机上,点击 Connect 按钮即可,该服务器仅为熟悉通讯方式和解析方式使用.该服务器不支持心跳返回,不能作为商用服务器.服务器代码在 SocketServerDemo 文件夹中,请注意参考阅读.

IP: 104.238.184.237

Port: 8080

您也可以选择下载 JAR 文件到本地,运行在您的本地进行调试 Download JAR

下载后使用下面的代码将其运行起来java -jar SocketServerDemo.jar

简单的长连接

OkSocket 会默认对每一个 Open 的新通道做缓存管理,仅在第一次调用 Open 方法时创建 ConnectionManager 管理器,之后调用者可以通过获取到该ConnectionManager的引用,继续调用相关方法

ConnectionManager 主要负责该地址的套接字连接断开发送消息等操作.
//连接参数设置(IP,端口号),这也是一个连接的唯一标识,不同连接,该参数中的两个值至少有其一不一样
ConnectionInfo info = new ConnectionInfo("104.238.184.237",8080);
//调用OkSocket,开启这次连接的通道,调用通道的连接方法进行连接.
OkSocket.open(info).connect();

有回调的长连接

注册该通道的监听器,每个 Connection 通道中的监听器互相隔离,因此如果一个项目连接了多个 Socket 连接需要在每个 Connection 注册自己的连接监听器,连接监听器是该 OkSocket 与用户交互的唯一途径

//连接参数设置(IP,拿到通道Manager
IConnectionManager manager = OkSocket.open(info);
//注册Socket行为监听器,SocketActionAdapter是回调的Simple类,其他回调方法请参阅类文档
manager.registerReceiver(new SocketActionAdapter(){
  @Override
  public void onSocketConnectionSuccess(Context context,ConnectionInfo info,String action) {
   Toast.makeText(context,"连接成功",LENGTH_SHORT).show();
  }
});
//调用通道进行连接
manager.connect();

可配置的长连接

获得 OkSocketOptions 的行为属于比较高级的 OkSocket 调用方法,每个 Connection 将会对应一个 OkSocketOptions,如果第一次调用 Open 时未指定 OkSocketOptions,OkSocket将会使用默认的配置对象,默认配置请见文档下方的高级调用说明

//连接参数设置(IP,拿到通道Manager
IConnectionManager manager = OkSocket.open(info);
//获得当前连接通道的参配对象
OkSocketOptions options= manager.getOption();
//基于当前参配对象构建一个参配建造者类
OkSocketOptions.Builder builder = new OkSocketOptions.Builder(options);
//修改参配设置(其他参配请参阅类文档)
builder.setSinglePackageBytes(size);
//建造一个新的参配对象并且付给通道
manager.option(builder.build());
//调用通道进行连接
manager.connect();

如何进行数据发送

//类A:
//...定义将要发送的数据结构体...
public class TestSendData implements ISendable {
  private String str = "";

  public TestSendData() {
    JSONObject jsonObject = new JSONObject();
    try {
      jsonObject.put("cmd",14);
      jsonObject.put("data","{x:2,y:1}");
      str = jsonObject.toString();
    } catch (JSONException e) {
      e.printStackTrace();
    }
  }

  @Override
  public byte[] parse() {
    //根据服务器的解析规则,构建byte数组
    byte[] body = str.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();
  }
}

//类B:
private IConnectionManager mManager;
//...省略连接及设置回调的代码...
@Override
public void onSocketConnectionSuccess(Context context,String action) {
   //连接成功其他操作...
   //链式编程调用
   OkSocket.open(info)
    .send(new TestSendData());
   
   //此处也可将ConnectManager保存成成员变量使用.
   mManager = OkSocket.open(info);
   if(mManager != null){
    mManager.send(new TestSendData());
   }
   //以上两种方法选择其一,成员变量的方式请注意判空
}

如何接收数据

OkSocket客户端接收服务器数据是要求一定格式的,客户端的OkSocketOptions提供了接口来修改默认的服务器返回的包头解析规则.请看下图为默认的包头包体解析规则

 

微信公众号搜索 “ 程序精选 ” ,选择关注!
精选程序员所需精品干货内容!