AndroidPN:基于Asmack实现和服务器端的持久连接,以实现服务器对客户端的推送,全称为android push notification。
所谓的推送其实就是建立客户端和服务器端之间的长连接,原生的Socket长连接,性能并不好,而且作为阻塞式的连接并不适合处理高并发的情景,为了解决这种问题,在JDK1.4版本中加入一个一种非阻塞式的I/O模型,这种基于通道和缓冲区的 I/O 方式被称为NIO,但是NIO使用比较繁琐,基本上是没有什么人会使用的,更多是使用封装好的网络连接框架如Mina、Netty等,其使用方法可参见Socket、Mina简单使用,关于AndroidPN源码可参见源码
通信架构图:
1、客户端和服务器的通信是基于XMPP协议,其通信的方式是XML流,但是因为Asmack的存在,使得客户端在发送信息时,只需要构建一个Packet对象,在Asmack内部会将Packet转化成XML流发送到服务器,在服务器端接收到XML流之后会解析成Packet对象,同理,从服务器端向客户端发送消息时也是如此,这样我们在构建消息时,就避免了和XMPP协议的直接对话,大大降低了难度
2、服务器端要管理客户端的连接,就避免不了要处理高并发的情景,因此服务器端会比较依赖Mina框架
客户端:
1、客户端实现推送需要具备图中的四个模块
2、身份验证其实是分成三步的,其大致的功能已在图中标明,在连接服务器过程中,会创建Socket,而不是使用Mina的原因是因为客户端并不需要处理高并发的情况,只是需要一个和服务器连接的通道而已,因此使用原生Socket即可
3、在连接服务器阶段,会初始化Reader,Writer读写流,这个会在后面包装成Asmack的读写流
4、注册阶段中,会构建一个Packet对象,随机指定ID,userName,passWord发送到服务器,此ID就是本次的连接ID,userName和passWord就是当前设备的账号密码,因此,在后台可以全量推送消息,也可以指定特定账号推送消息
5、注册阶段中,会添加一个监听,这个监听中添加了过滤条件,即是相同的连接ID时才可以被回调此监听中,而这个监听是会保存在一个集合中,当有消息到来时,是先被Asmack的读取流PacketReader接收到,之后遍历此集合,将消息分发出去
通讯:
1、通讯模块中有两个很重要的类PacketWriter、PacketReader负责发送消息和读取消息。它是Writre和Reader的进一步包装,当需要发送消息时,会将Packet数据包放到queue队列中,此时会notify队列,一个一个的读取Packet包,之后转换成XML,调用内部writer将之发送出去,若是queue队列中没有Packet包,则队列一直等待,直到新数据的到来
2、在收到服务器推送的消息时,PacketReader会将收到的XML流转换成对应的Packet类型数据,并根据各自的过滤条件分发出去
服务器:
1、在服务器端的功能其实就是两个,第一是和客户端建立联系,对客户端发来的消息可以做出响应,第二是可以主动的向客户端推送消息
2、服务器端很依赖于Mina框架,其接收处理消息完全是标准的Mina使用方法,可以参照上面所提到的Mina的简单使用方法
3、Mina框架是将网络连接和消息处理各自独立,在AndroidPN中是使用XmpploHandler处理消息,在这个里面可以应对:接收消息、发送消息、出现异常、会话创建、会话开启、会话闲置这6种情况,但是这里AndroidPN在接收消息时是利用的XmpploHandler,而在发送消息的时候用的是Connection类的方法
4、当客户端发送Packet消息时,服务器接收到之后,解析成不同类型的Packet,然后做出不同的响应,调用Connection的方法将之发送出去,这样在客户端接收到之后也会做同样的解析,转换成不同类型的消息
至此,AndroidPN的原理,从客户端到服务器端以及两者之间的通信简单的分析了一下,本意是依据源码进行分析,但是源码太多,一一贴出篇幅太长,而且并不清晰,所以只能勉强剥离出各个模块加以分析,仅用于学习记忆,其中不免有误,请多指教
原文:https://www.cnblogs.com/zsk-crs/p/14822105.html