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


服务端主动通知


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

\

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

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

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

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

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    {
         "resp_event" : 20 ,
         "action" : "" ,
         "seq_id" : 11111111 ,
         "resp" : {
     
           }
         }
    }<span style= "font-family: Arial, Verdana, sans-serif;" >我们根据resp_event为 20 判断这次响应是服务端主动通知,然后通过action找到对应处理类,然后把resp中数据解析成对应的bean传入对应处理类执行对应业务逻辑.</span>

    show code

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    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()方法.

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    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);
         }
     
     
    }</string,>

    NotifyListenerManager是一个单例的类,在第一次创建的时候在构造方法中执行了regist方法,这是一个变种的观察者模式对于添加观察者这个过程我们直接在regist方法中写好了,如果增加了新的业务逻辑我们只需要在regist方法中put新添加的action与对应处理类.对外暴露的fire方法根据传入的responsse中action找到对应的处理类,拿到处理类对应的注解标记的class,将服务端返回的resp解析成对应的bean丢到对应处理类执行对应逻辑.

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    //抽象接口
    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 {
     
         @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;
         }
     
    }</announcemsgnotify></t>

    如果新增业务逻辑我们只需要实现新的业务逻辑类,然后在NotifyListenerManager的regist方法中put新增的action与listener映射关系,对外只需要调用NotifyListenerManager.getInstance().fire(response)即可,实现了解耦.

    到此websocket介绍完啦….鼓掌鼓掌鼓掌.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值