package com.example.msi.websocketdemo.websocket;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.text.TextUtils;
import com.example.msi.websocketdemo.BuildConfig;
import com.example.msi.websocketdemo.WsApplication;
import com.example.msi.websocketdemo.websocket.common.CallbackDataWrapper;
import com.example.msi.websocketdemo.websocket.common.CallbackWrapper;
import com.example.msi.websocketdemo.websocket.common.Codec;
import com.example.msi.websocketdemo.websocket.common.ErrorCode;
import com.example.msi.websocketdemo.websocket.common.ICallback;
import com.example.msi.websocketdemo.websocket.common.IWsCallback;
import com.example.msi.websocketdemo.websocket.common.WsStatus;
import com.example.msi.websocketdemo.websocket.notify.NotifyListenerManager;
import com.example.msi.websocketdemo.websocket.request.Action;
import com.example.msi.websocketdemo.websocket.request.Request;
import com.example.msi.websocketdemo.websocket.response.ChildResponse;
import com.example.msi.websocketdemo.websocket.response.Response;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.neovisionaries.ws.client.WebSocket;
import com.neovisionaries.ws.client.WebSocketAdapter;
import com.neovisionaries.ws.client.WebSocketException;
import com.neovisionaries.ws.client.WebSocketFactory;
import com.neovisionaries.ws.client.WebSocketFrame;
import com.orhanobut.logger.Logger;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
/**
* Created by zly on 2017/6/8.
*/
public class WsManager {
private final String TAG = this.getClass().getSimpleName();
/**
* WebSocket config
*/
private static final long HEARTBEAT_INTERVAL = 30000;//心跳间隔
private static final int FRAME_QUEUE_SIZE = 5;
private static final int CONNECT_TIMEOUT = 5000;
private static final int REQUEST_TIMEOUT = 10000;//请求超时时间
private static final String DEF_TEST_URL = "测试服地址";//测试服默认地址
private static final String DEF_RELEASE_URL = "正式服地址";//正式服默认地址
private static final String DEF_URL = BuildConfig.DEBUG ? DEF_TEST_URL : DEF_RELEASE_URL;
private String url;
private WsStatus mStatus;
private WebSocket ws;
private WsListener mListener;
private AtomicLong seqId = new AtomicLong(SystemClock.uptimeMillis());//每个请求的唯一标识
private ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
private Map<Long, CallbackWrapper> callbacks = new HashMap<>();
private final int SUCCESS_HANDLE = 0x01;
private final int ERROR_HANDLE = 0x02;
private Handler mHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case SUCCESS_HANDLE:
CallbackDataWrapper successWrapper = (CallbackDataWrapper) msg.obj;
successWrapper.getCallback().onSuccess(successWrapper.getData());
break;
case ERROR_HANDLE:
CallbackDataWrapper errorWrapper = (CallbackDataWrapper) msg.obj;
errorWrapper.getCallback().onFail((String) errorWrapper.getData());
break;
}
}
};
private WsManager() {
}
private static class WsManagerHolder {
private static WsManager mInstance = new WsManager();
}
public static WsManager getInstance() {
return WsManagerHolder.mInstance;
}
public void init() {
try {
/**
* configUrl其实是缓存在本地的连接地址
* 这个缓存本地连接地址是app启动的时候通过http请求去服务端获取的,
* 每次app启动的时候会拿当前时间与缓存时间比较,超过6小时就再次去服务端获取新的连接地址更新本地缓存
*/
String configUrl = "";
url = TextUtils.isEmpty(configUrl) ? DEF_URL : configUrl;
ws = new WebSocketFactory().createSocket(url, CONNECT_TIMEOUT)
.setFrameQueueSize(FRAME_QUEUE_SIZE)//设置帧队列最大值为5
.setMissingCloseFrameAllowed(false)//设置不允许服务端关闭连接却未发送关闭帧
.addListener(mListener = new WsListener())//添加回调监听
.connectAsynchronously();//异步连接
setStatus(WsStatus.CONNECTING);
Logger.t(TAG).d("第一次连接");
} catch (IOException e) {
e.printStackTrace();
}
}
private void doAuth() {
sendReq(Action.LOGIN, null, new ICallback() {
@Override
public void onSuccess(Object o) {
Logger.t(TAG).d("授权成功");
setStatus(WsStatus.AUTH_SUCCESS);
startHeartbeat();
delaySyncData();
}
@Override
public void onFail(String msg) {
}
});
}
//同步数据
private void delaySyncData() {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
sendReq(Action.SYNC, null, new ICallback() {
@Override
public void onSuccess(Object o) {
}
@Override
public void onFail(String msg) {
}
});
}
}, 300);
}
private void startHeartbeat() {
mHandler.postDelayed(heartbeatTask, HEARTBEAT_INTERVAL);
}
private void cancelHeartbeat() {
heartbeatFailCount = 0;
mHandler.removeCallbacks(heartbeatTask);
}
private int heartbeatFailCount = 0;
private Runnable heartbeatTask = new Runnable() {
@Override
public void run() {
sendReq(Action.HEARTBEAT, null, new ICallback() {
@Override
public void onSuccess(Object o) {
heartbeatFailCount = 0;
}
@Override
public void onFail(String msg) {
heartbeatFailCount++;
if (heartbeatFailCount >= 3) {
reconnect();
}
}
});
mHandler.postDelayed(this, HEARTBEAT_INTERVAL);
}
};
public void sendReq(Action action, Object req, ICallback callback) {
sendReq(action, req, callback, REQUEST_TIMEOUT);
}
public void sendReq(Action action, Object req, ICallback callback, long timeout) {
sendReq(action, req, callback, timeout, 1);
}
/**
* @param action Action
* @param req 请求参数
* @param callback 回调
* @param timeout 超时时间
* @param reqCount 请求次数
*/
@SuppressWarnings("unchecked")
private <T> void sendReq(Action action, T req, final ICallback callback, final long timeout, int reqCount) {
if (!isNetConnect()) {
callback.onFail("网络不可用");
return;
}
if (WsStatus.AUTH_SUCCESS.equals(getStatus()) || Action.LOGIN.equals(action)) {
Request request = new Request.Builder<T>()
.action(action.getAction())
.reqEvent(action.getReqEvent())
.seqId(seqId.getAndIncrement())
.reqCount(reqCount)
没有合适的资源?快使用搜索试试~ 我知道了~
WebSocket安卓客户端实现详解(三)–服务端主动通知
共48个文件
java:23个
xml:7个
png:5个
5星 · 超过95%的资源 需积分: 50 358 下载量 42 浏览量
2017-08-06
14:20:58
上传
评论 13
收藏 103KB RAR 举报
温馨提示
WebSocket安卓客户端实现详解(三)–服务端主动通知
资源推荐
资源详情
资源评论
收起资源包目录
WebSocketDemo.rar (48个子文件)
WebSocketDemo
.gitignore 127B
app
.gitignore 8B
build.gradle 1KB
src
androidTest
java
com
example
msi
websocketdemo
ExampleInstrumentedTest.java 788B
main
AndroidManifest.xml 1KB
res
mipmap-xhdpi
ic_launcher.png 5KB
mipmap-mdpi
ic_launcher.png 2KB
layout
activity_main.xml 558B
values-w820dp
dimens.xml 364B
mipmap-xxhdpi
ic_launcher.png 8KB
drawable
mipmap-hdpi
ic_launcher.png 3KB
mipmap-xxxhdpi
ic_launcher.png 10KB
values
strings.xml 79B
colors.xml 214B
dimens.xml 216B
styles.xml 403B
java
com
example
msi
websocketdemo
MainActivity.java 1KB
websocket
notify
AnnounceMsgListener.java 315B
NotifyClass.java 450B
NotifyListenerManager.java 2KB
INotifyListener.java 167B
AnnounceMsgNotify.java 439B
response
ChildResponse.java 683B
Response.java 966B
WsManager.java 16KB
common
CallbackWrapper.java 1KB
ICallback.java 202B
CallbackDataWrapper.java 737B
WsStatus.java 263B
ErrorCode.java 482B
Codec.java 2KB
IWsCallback.java 415B
request
Action.java 699B
Request.java 2KB
NetStatusReceiver.java 1KB
ForegroundCallbacks.java 4KB
WsApplication.java 1KB
test
java
com
example
msi
websocketdemo
ExampleUnitTest.java 423B
libs
proguard-rules.pro 658B
app.iml 10KB
settings.gradle 16B
build.gradle 521B
gradlew 5KB
gradlew.bat 2KB
gradle.properties 747B
gradle
wrapper
gradle-wrapper.properties 230B
gradle-wrapper.jar 52KB
WebSocketDemo.iml 867B
共 48 条
- 1
zhuliyuan丶
- 粉丝: 350
- 资源: 14
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 最入门的爬虫代码 python.docx
- 爬虫零基础入门-爬取天气预报.pdf
- 最通俗易懂的 MongoDB 非结构化文档存储数据库教程.zip
- 以mongodb为数据库的订单物流小项目.zip
- 腾讯云-mongodb数据库, 项目部署.zip
- 腾讯 APIJSON 的 MongoDB 数据库插件.zip
- 理解非关系型数据库和关系型数据库的区别.zip
- 操作简单的Mongodb网页web管理工具,基于Spring Boot2.0支持mongodb集群.zip
- tms-mongodb-web,提供访问mongodb数据的REST API和可灵活扩展的mongodb web 客户端.zip
- SpringBoot整合mongodb学习MongoTemplate和MongoRepository两种方式CRUD使用.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
前往页