WebSocketDemo
WebSocket 安卓客户端的实现方式。
介绍
WebSocketDemo二 已经出来啦,更新了很多功能,使用起来比这个要方便很多,详见:
https://blog.csdn.net/u013872857/article/details/80947944
如果不想了解其中的原理可以直接拉到最后面的使用方式章节,按照教程使用即可,或者直接打开 demo 查看代码,代码地址:。
https://github.com/0xZhangKe/WebSocketDemo
本文使用一个后台 Service 来建立 WebSocket 连接,Activity 与 Fragment 需要使用 WebSocket 接口时只需要绑定该服务既可。
WebSocketService 接收到数据之后会通知每一个绑定了 WebSocketService 服务的 Activity 及 Fragment,其自身也可以对返回的数据进行判断等等,具体如何操作根据业务需求定。
下图是 WebSocketService 的工作流程图
WebSocketService 负责建立 WebSocket 连接,接收返回的数据,接收到的数据通过 EventBus 发送出去,连接失败之后可以自动重连。
下图是 Activity 的工作流程图
Activity/Fragment 绑定 WebSocket 服务,绑定成功后可以直接调用 WebSocketService 对象发送数据。
WebSocketService
添加必要的依赖
首先添加 WebSocket 框架依赖:
compile 'com.neovisionaries:nv-websocket-client:2.3'
这个框架也是我在 Github 上找了一圈之后选中的一个,使用的人很多,文档齐全,还在继续维护。
另外还要添加一个 EventBus 及阿里的 JSON 框架:
compile 'com.alibaba:fastjson:1.2.33'
compile 'org.greenrobot:eventbus:3.0.0'
好了完事大吉,现在开始吧。
定义 WebSocket 提供的接口
先创建一个 WebSocket 的接口,其中定义了 WebSocket 必须提供的几个公开方法:
public interface IWebSocket {
/**
* 发送数据
*
* @param text 需要发送的数据
*/
void sendText(String text);
/**
* 0-未连接
* 1-正在连接
* 2-已连接
*/
int getConnectStatus();
/**
* 重新连接
*/
void reconnect();
/**
* 关闭连接
*/
void stop();
}
WebSocketService 需要实现这个接口,后面绑定 WebSocketService 时直接通过 IWebSocket 创建对象既可。
AbsWebSocketService
我这里为了降低代码的耦合度,将与业务逻辑相关的代码(接口地址、数据处理及分发等)与 WebSocket 的连接、发送数据等操作剥离开来,所以这里创建的时一个抽象类 AbsWebSocketService 来实现与业务逻辑无关的代码。
在实际使用中只需要创建一个 WebSocketService 并继承该 AbsWebSocketService 既可,不需要改动其中的代码。
首先看一下 AbsWebSocketService 的代码:
public abstract class AbsBaseWebSocketService extends Service implements IWebSocket {
private static final String TAG = "AbsBaseWebSocketService";
private static final int TIME_OUT = 15000;
private static WebSocketFactory factory = new WebSocketFactory().setConnectionTimeout(TIME_OUT);
private AbsBaseWebSocketService.WebSocketThread webSocketThread;
private WebSocket webSocket;
private AbsBaseWebSocketService.ServiceBinder serviceBinder = new AbsBaseWebSocketService.ServiceBinder();
public class ServiceBinder extends Binder {
public AbsBaseWebSocketService getService() {
return AbsBaseWebSocketService.this;
}
}
private boolean stop = false;
/**
* 0-未连接
* 1-正在连接
* 2-已连接
*/
private int connectStatus = 0;//是否已连接
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate()");
ProxySettings settings = factory.getProxySettings();
settings.addHeader("Content-Type", "text/json");
connectStatus = 0;
webSocketThread = new AbsBaseWebSocketService.WebSocketThread();
webSocketThread.start();
Log.i(TAG, "onCreated");
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
if (serviceBinder == null) {
serviceBinder = new AbsBaseWebSocketService.ServiceBinder();
}
Log.i(TAG, "onBind");
return serviceBinder;
}
@Override
public void onDestroy() {
super.onDestroy();
stop = true;
webSocket.disconnect();
webSocket.flush();
webSocket = null;
connectStatus = 0;
Log.i(TAG, "onDestroy");
}
/**
* 获取服务器地址
*/
protected abstract String getConnectUrl();
/**
* 分发响应数据
*/
protected abstract void dispatchResponse(String textResponse);
/**
* 连接成功发送 WebSocketConnectedEvent 事件,
* 请求成功发送 CommonResponse 事件,
* 请求失败发送 WebSocketSendDataErrorEvent 事件。
*/
private class WebSocketThread extends Thread {
@Override
public void run() {
Log.i(TAG, "WebSocketThread->run()");
setupWebSocket();
}
}
private void setupWebSocket() {
if (connectStatus != 0) return;
connectStatus = 1;
try {
webSocket = factory.createSocket(getConnectUrl());
webSocket.addListener(new WebSocketAdapter() {
@Override
public void onTextMessage(WebSocket websocket, String text) throws Exception {
super.onTextMessage(websocket, text);
if (debug()) {
Log.i(TAG, String.format("onTextMessage->%s", text));
}
dispatchResponse(text);
}
@Override
public void onTextMessageError(WebSocket websocket, WebSocketException cause, byte[] data) throws Exception {
super.onTextMessageError(websocket, cause, data);
Log.e(TAG, "onTextMessageError()", cause);
EventBus.getDefault().post(new