本篇依旧是接着上一篇继续扩展, 还没看过之前博客的小伙伴, 这里附上前几篇地址
webSocket 安卓客户端实现详解 (一)–连接建立与重连
WebSocket 安卓客户端实现详解 (二)–客户端发送请求
终于是最后一篇啦, 有点激动 \ (≧▽≦) / 啦啦啦,
热身完毕, 我们先回顾下第一篇中讲到的服务端主动通知的流程
在回顾下第二篇中服务端主动通知协议的格式
- {
- "resp_event": 20,
- "action": "",
- "seq_id": 11111111,
- "resp": {
- }
- }
- }
我们根据 resp_event 为 20 判断这次响应是服务端主动通知, 然后通过 action 找到对应处理类, 然后把 resp 中数据解析成对应的 bean 传入对应处理类执行对应业务逻辑.
show code
- public class WsManager {
- ....跟之前相同代码省略.....
- class WsListener extends WebSocketAdapter {
- @Override
- public void onTextMessage(WebSocket websocket, String text) throws Exception {
- super.onTextMessage(websocket, text);
- Logger.t(TAG).d("receiverMsg:%s", text);
- Response response = Codec.decoder(text);//解析出第一层bean
- if (response.getRespEvent() == 10) {//响应
- CallbackWrapper wrapper = callbacks.remove(
- Long.parseLong(response.getSeqId()));//找到对应callback
- if (wrapper == null) {
- Logger.t(TAG).d("(action:%s) not found callback", response.getAction());
- return;
- }
- try {
- wrapper.getTimeoutTask().cancel(true);//取消超时任务
- ChildResponse childResponse = Codec.decoderChildResp(
- response.getResp());//解析第二层bean
- if (childResponse.isOK()) {
- Object o = new Gson().fromJson(childResponse.getData(),
- wrapper.getAction().getRespClazz());
- wrapper.getTempCallback().onSuccess(o);
- } else {
- wrapper.getTempCallback()
- .onError(ErrorCode.BUSINESS_EXCEPTION.getMsg(), wrapper.getRequest(),
- wrapper.getAction());
- }
- } catch (JsonSyntaxException e) {
- e.printStackTrace();
- wrapper.getTempCallback()
- .onError(ErrorCode.PARSE_EXCEPTION.getMsg(), wrapper.getRequest(),
- wrapper.getAction());
- }
- } else if (response.getRespEvent() == 20) {//通知
- NotifyListenerManager.getInstance().fire(response);
- }
- }
- }
- ....跟之前相同代码省略.....
- }
我们先解析出第一层 bean 然后根据 resp_event 为 20 执行 NotifyListenerManager 通知管理类对外暴露的 fire() 方法.
- public class NotifyListenerManager {
- private final String TAG = this.getClass().getSimpleName();
- private volatile static NotifyListenerManager manager;
- private Map < String,
- INotifyListener > map = new HashMap < >();
- private NotifyListenerManager() {
- regist();
- }
- public static NotifyListenerManager getInstance() {
- if (manager == null) {
- synchronized(NotifyListenerManager.class) {
- if (manager == null) {
- manager = new NotifyListenerManager();
- }
- }
- }
- return manager;
- }
- private void regist() {
- map.put("notifyAnnounceMsg", new AnnounceMsgListener());
- }
- public void fire(Response response) {
- String action = response.getAction();
- String resp = response.getResp();
- INotifyListener listener = map.get(action);
- if (listener == null) {
- Logger.t(TAG).d("no found notify listener");
- return;
- }
- NotifyClass notifyClass = listener.getClass().getAnnotation(NotifyClass.class);
- Class < ?>clazz = notifyClass.value();
- Object result = null;
- try {
- result = new Gson().fromJson(resp, clazz);
- } catch(JsonSyntaxException e) {
- e.printStackTrace();
- }
- Logger.t(TAG).d(result);
- listener.fire(result);
- }
- }
NotifyListenerManager 是一个单例的类, 在第一次创建的时候在构造方法中执行了 regist 方法, 这是一个变种的观察者模式对于添加观察者这个过程我们直接在 regist 方法中写好了, 如果增加了新的业务逻辑我们只需要在 regist 方法中 put 新添加的 action 与对应处理类. 对外暴露的 fire 方法根据传入的 responsse 中 action 找到对应的处理类, 拿到处理类对应的注解标记的 class, 将服务端返回的 resp 解析成对应的 bean 丢到对应处理类执行对应逻辑.
- //抽象接口
- public interface INotifyListener<T> {
- void fire(T t);
- }
- //标记注解
- @Target(ElementType.TYPE)
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- public @interface NotifyClass {
- Class<?> value();
- }
- //具体逻辑对应的处理子类
- @NotifyClass(AnnounceMsgNotify.class)
- public class AnnounceMsgListener implements INotifyListener<AnnounceMsgNotify> {
- @Override
- public void fire(AnnounceMsgNotify announceMsgNotify) {
- //这里处理具体的逻辑
- }
- }
- //对应数据bean
- public class AnnounceMsgNotify {
- @SerializedName("msg_version")
- private String msgVersion;
- public String getMsgVersion() {
- return msgVersion;
- }
- public void setMsgVersion(String msgVersion) {
- this.msgVersion = msgVersion;
- }
- }
如果新增业务逻辑我们只需要实现新的业务逻辑类, 然后在 NotifyListenerManager 的 regist 方法中 put 新增的 action 与 listener 映射关系, 对外只需要调用
即可, 实现了解耦.
- NotifyListenerManager.getInstance().fire(response)
到此 websocket 介绍完啦…. 鼓掌鼓掌鼓掌.
对于 websocket 使用我已经尽我所能最详细的讲解了一遍, 但是也避免不了有所疏漏和错误还望各位小伙伴指出.
然后虽然写了三篇但是还有几个点说的不够详细, 这里我一一列举感兴趣的小伙伴可以自己看看.
最后感谢各位小伙伴捧场能把三篇都看完的绝对是真爱啊…
源码下载 WebSocket 安卓客户端实现详解 (三)–服务端主动通知
来源: http://blog.csdn.net/zly921112/article/details/76767876