WebSocket安卓用戶端實現詳解(三)–服務端主動通知

來源:互聯網
上載者:User

標籤:serialize   回顧   策略   過程   type   UI   _id   ring   關係   

  WebSocket安卓用戶端實現詳解(三)–服務端主動通知
  
  本篇依舊是接著上一篇繼續擴充,還沒看過之前部落格的小夥伴,這裡附上前幾篇地址
  
  WebSocket安卓用戶端實現詳解(一)–串連建立與重連
  
  WebSocket安卓用戶端實現詳解(二)–用戶端發送請求
  
  終於是最後一篇啦,有點激動\ ( ≧▽≦ ) /啦啦啦,
  
  服務端主動通知
  
  熱身完畢,我們先回顧下第一篇中講到的服務端主動通知的流程
  
  根據notify中事件類型找到對應的處理類,處理對應邏輯.
  
  然後用eventbus通知對應的ui介面更新.
  
  如果需要ack,發送ack請求.
  
  在回顧下第二篇中服務端主動通知協議的格式
  
  {
  
  "resp_event": 20,
  
  "action": "",
  
  "seq_id": 11111111,
  
  我們根據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 = www.wmyl166.cn callbacks.remove(
  
  Long.parseLong(response.getSeqId()));//找到對應callback
  
  if (wrapper == null) {
  
  Logger.t(TAG).d("(action:%s) not found www.xingchexiu.com 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( www.chuangyed.com 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 www.wmyl110.com 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的www.wmyl119.cn regist方法中put新增的action與listener映射關係,對外只需要調用NotifyListenerManager.getInstance().fire(response)即可,實現瞭解耦.
  
  到此websocket介紹完啦….鼓掌鼓掌鼓掌.
  
  總結
  
  對於websocket使用我已經盡我所能最詳細的講解了一遍,但是也避免不了有所疏漏和錯誤還望各位小夥伴指出.
  
  然後雖然寫了三篇但是還有幾個點說的不夠詳細,這裡我一一列舉感興趣的小夥伴可以自己看看.
  
  擷取串連地址與選擇串連地址的策略
  
  重連的策略
  
  心跳的策略
  
  進程保活
  
  最後感謝各位小夥伴捧場能把三篇都看完的絕對是真愛啊…

WebSocket安卓用戶端實現詳解(三)–服務端主動通知

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.