WebSocket安卓客户端实现详解(三)--服务端主动通知

xiaoxiao2021-02-28  121

本篇依旧是接着上一篇继续扩展,还没看过之前博客的小伙伴,这里附上前几篇地址

WebSocket安卓客户端实现详解(一)–连接建立与重连

WebSocket安卓客户端实现详解(二)–客户端发送请求

终于是最后一篇啦,有点激动\ ( ≧▽≦ ) /啦啦啦,

服务端主动通知

热身完毕,我们先回顾下第一篇中讲到的服务端主动通知的流程

根据notify中事件类型找到对应的处理类,处理对应逻辑.

然后用eventbus通知对应的ui界面更新.

如果需要ack,发送ack请求.

在回顾下第二篇中服务端主动通知协议的格式

{ "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安卓客户端实现详解(三)–服务端主动通知

转载请注明原文地址: https://www.6miu.com/read-50372.html

最新回复(0)