AndroidPN消息推送

发表于 5年以前  | 总阅读数:920 次

Androidpn是韩国Sehwan No写的开源消息推送项目,很多大公司都用这个消息推送方式构建自己的消息推送服务,缺点是导致客户端比较耗电。通信机制分别由客户端和服务器完成。

客户端采用基于java的XMPP协议包asmack(该包依赖于openfire下的开源项目smack)。通过该协议包提供的XMPPConnetcion类与服务器建立持久连接,并通过该连接进行用户注册和登录认证,以及接受服务器消息。

服务器是基于开源的openfire工程,采用java语言实现和Spring框架提供Web服务。主要有两个部分,一个是侦听在5222端口上的XMPP服务,负责与客户端的XMPPConnection类进行通信,作用是用户注册和身份认证,并推送消息。另外是Web服务器,采用一个轻量级的HTTP服务器,负责接收用户的Web请求。

整个基于XMPP的通信中,服务器端和客户端的通信是基于一个session(会话)过程,会话开始,首先客户端会指定端口号,然后把准备的连接信息发送到服务器端,客户端通过XMPP协议做的只有接收消息,其他的管理连接和保存消息等都由服务器负责。消息的传递是以根节点为起始,以为结束。

服务器和客户端建立Tcp连接过程如下。首先,建立会话协商,Client 准备connecting to server (127.0.0.1:5222)。其次,服务器询问Client所支持的安全认证。再者,Client发送给服务器要注册的用户。然后,Client根据服务器的要求提交用户信息。最后,Client关闭注册的STREAM元素。


客户端

Client这边包含有消息的收发,解析以及持久连接的发起,重连等功能呢,十分强大,我们开发时完全不用管底层的连接,也不用担心断线,可以专注于业务部分的开发。

控制器

XmppManager是Client的主控制器,主要用来管理连接信息,包括XMPP端口、IP地址、登录的用户名和密码,以及对连接的维护。

消息解析处理

NotificationIQ、NotificationPackerListener以及NotificationIQProvider三个类负责对收到的Notification格式的消息进行解析和处理。

手机状态监听

PersistentConnetcionListener、PhoneStateChangeListener以及ReconnectionThread三个类负责监听手机状态和断线重连。

同时,代码结构也很简单。去除android的Service和BroadCast类以及一些工具类和常量类不谈:

1.NotificationIQ,NotificationIQProvider,NotificationPacketListener三个类负责对收到的Notification格式的消息进行解析和处理,

2.XmppManager是主控制器,NotificationService通过这个类,在后台维护androidpn连接。

3.PersistentConnectionListener,PhoneStateChangeListener,ReconnectionThread.java三个类则负责监听手机的状态并进行断线重连。

我们自定义消息时需要定义3个类:在NotificationIQ中定义消息的实体,在NotificationIQProvider中将消息转化为NotificationIQ实体,在NotificationPacketListener中对实体进行处理,具体的实现可参考NotificationIQ,NotificationIQProvider,NotificationPacketListener三个类。在定义这些类之后,还需要在XmppManager中将这3个类中注册到connection中,代码如下:

connection.connect();
    Log.i(LOGTAG, "XMPP connected successfully");
    // packet provider
    ProviderManager.getInstance().addIQProvider("message",
    Constants.NOTIFICATION_NAMESPACE,
    new NotificationIQProvider());
    //packet filter
    PacketFilter packetFilter = new PacketTypeFilter(
    NotificationIQ.class);
    // packet listener
    PacketListener packetListener = xmppManager.getNotificationPacketListener();
    connection.addPacketListener(packetListener, packetFilter);

需要注意的是,注册NotificationIQProvider时,传入的namespace需要和服务端组装消息时使用的namespace一致,才能正确的收到。

注册

Client在与服务器建立connection后,首先会提交注册任务,在Androidpn项目中,用户注册是采用UUID(通用唯一标识码)来实现的,其每次登录都会利用这个UUID.randomUUID()来产生一个用户名和密码,而且不会重复。

注册方法根据Server的格式要求组装注册消息,发送到服务器,同时使用在connection中添加监听,来获取服务器返回的消息packet。Client会根据消息的类型来判断是否注册成功。

服务端收到Client的注册请求,会通过路由类router来转发到相应的Handler处理,router首先会读取Client发来包Packet的Namespace部分,根据XMPP RFC协议注册packet的namespace为jabber:iq:register,授权packet的namespace为jabber:iq:auth,由此转发到IQRegisterHandler处理注册请求。

如果注册成功,Client会把相应的用户名、密码通过SharePerence保存在Client的共享文件AndroidpnClient中。此外,AndroidpnClient还保存了当前应用的包名、类名、服务器地址、端口、客户端版本、设备ID等。

登录

Client的登录是在注册之后进行的,在Client的XmppManager类中,建立连接的时候首先会提交登录任务,然而在提交登录任务的时候都有一个submitRegisterTask()方法,可知,每次登录都会首先提交一个注册任务。

登录的时候,要先通过isAuthenticated()方法判断是否授权,授权处理同样会通过connection发送到服务端,服务端会根据packet的namespace部分进行解析,然后路由类router会根据namespace转发到IQAuthHandler处理。

Client收到服务端返回的消息packet,会使用connection的监听器异步接收消息,并通过XmppManager的context的sendBroadcast(Intentintent)以广播发送出去。

基于tomcat的项目源码http://pan.baidu.com/s/1kTDUQWJ


服务器

服务端架构依赖spring、mina框架,spring完成java Ben管理,mina完成网络通信。另外,服务端还通过jetty潜入了Admin Console Web界面功能。对于spring的依赖导致要把androidpn-server整合潜入项目中时,要考虑和自己项目本身spring环境的整合问题,可能要改造androidpn-server源代码,具体要看项目中spring的环境。对于mina的依赖不存在这个问题,因为mina是类库型框架,而spring是容器型框架。androidpn-server对jetty的使用不是可选的,而是和jetty绑定的,所以要不使用jetty就必须对androidpn-server的源代码进行改造。

另外,对数据的存储使用hibernate框架,androidpn-server在使用hibernate时配置通过ehcache实现二级缓存。官方默认使用的数据库是HSQLDB数据库,你可以改用其他数据库。HSQLDB是用java语言实现的数据库,对其使用请自己学习。Androidpn-server通过In-Process模式(作为应用程序的一部分潜入应用程序)使用HSQLDB的。

服务器主要由以下几个包组成:

  • org.androidpn.server.xmpp异常类型定义,包含程序入口类XmppServer。

  • org.androidpn.server.util加载配置文件,获取主机和端口等信息。

  • org.androidpn.server.xmpp.codec是XMPP协议的XML文件解析包,server

收到和发送的消息都要通过这个包来进行xmpp协议编码和解码。

  • org.androidpn.server.xmpp.handler负责对不同类型的消息进行处理

  • org.androidpn.server.xmpp.net负责维护与client之间的持久连接,并实现了一些传输方式供发送xmpp消息时使用。

  • org.androidpn.server.xmpp.ssl是对连接进行ssl认证的工具包。

  • org.androidpn.server.xmpp.router包负责将收到的信息包发送到相应的handler进行处理,是一个路由包。

  • org.androidpn.server.xmpp.presence里面只包含PresenceManager类,用来维护client的在线状态。

  • org.androidpn.server.xmpp.push包里面的NotificationManager类包含有向client发送消息的接口。

服务器中使用ServerStarter类启动服务,服务启动后使用XmppServer来管理连接、加载配置等。

服务器接收处理消息流程

① connection接收到来着Client的packet,使用包codec解码。

② 路由包router根据packet的namespace等信息,将packet路由到相应的Handler。

③ Handler开始处理。

开发中只要根据client发送消息的格式,定义自己的router和handler类,然后在PacketRouter中注册router,在IQRouter中注册handler即可。

服务器发送消息的流程

① 使用NotificationManager接口的push方法。

② 使用SessionManager在Session集合查找相应的client连接。

③ 定义和组装XMPP消息,通过session向client发送。

在这个流程中我们需要修改的是步骤3,也就是需要定义和组装自己的xmpp消息,以便于将适当的信息传到客户端并便于客户端解析。一个简单的消息组装例子如下:

private IQ  createMessageIQ(String title, String message, String userId,String json) {
    Element notification =  DocumentHelper.createElement(QName.get(
    "message",  INQURIE_NAMESPACE));
    notification.addElement("title").setText(title);
    notification.addElement("text").setText(message);
    notification.addElement("userId").setText(userId);
    notification.addElement("json").setText(json);
    IQ iq = new IQ();
    iq.setType(IQ.Type.set);
    iq.setChildElement(notification);
    return iq;
    }

要注意的是在创建element的时候,传入的namespace要和client解析使用的namespace相匹配。

独立部署使用

独立部署使用不需要对androidpn-server源代码进行任何改造,目录结构见上图,只需要修改好配置文件即可,配置文件在conf文件夹下,下面对需要注意的配置项进行说明,其他配置项目使用默认配置就可。

对于config.properties的配置说明如下:

apiKey=1234567890 #暂时发现没什么用处

admin.console.host=127.0.0.1 #web管理控制界面jetty服务监听的地址

admin.console.port=7070 #web管理控制界面jetty服务监听的端口

对于spring-config.xml的配置说明:

<bean id="ioAcceptor" class="org.apache.mina.transport.socket.nio.NioSocketAcceptor"init-method="bind" destroy-method="unbind">

    <property name="defaultLocalAddress" value=":5222" /> <!--mina Socekt服务端监听端口,客户端配置和此配置一致-->

    <property name="handler" ref="xmppHandler" />

    <property name="filterChainBuilder" ref="filterChainBuilder" />

    <property name="reuseAddress" value="true" />

    </bean>

启动脚本在bin下,windowns和linux的脚本都有,需要配置系统环境变量JAVA_HOME,或者修改启动脚本将JAVA_HOME指定为你本机的具体地址,运行run脚本androidpn启动成功,通过浏览器访问http://127.0.0.1:7070/就可看到console界面。

其他项目通过http方式将需要发送的消息提交给androidpn-server服务,由androidpn-server完成客户端消息推送。

具体应用可以通过程序代码编写方式访问http://192.168.1.24:7070/notification.do地址,将需要的参数以post方式提交。

嵌入项目使用
若要将androidpn作为应用程序的一部分潜入项目中使用,需要对androidpn-server源代码进行改造。

情况一:若你的项目中没有用到spring

这种情况不用考虑androidpn的spring和你项目中spring配置的融合问题,直接因为spring就可以了,配置文件使用androidpn默认配置文件名称spring-config.xml。配置文件都放在classpath下。

需要在config.properties配置文件中增加配置server.home.dir选项,值指向一个目录,如:server.home.dir=F:\android\download\androidpn-server-0.5.0,该目录下要有子目录conf\security,目录下要放两个文件keystore和truststore,用来进行SSL安全传输用的密钥和证书,利用androdpn-server自带的就可以。

接下来就是修改org.androidpn.server.xmpp. XmppServer类,将启动admin console的代码注释掉,如下截图红框框住的部分。如果你需要启动admin console的话,需要将原始androidpn中console文件夹放到合适的路径下,这个还没有试。

Androidpn-server主启动类

org.androidpn.server.xmpp.XmppServer修改完后,你就可以在你的应用程序这样调用:

XmppServerserver = XmppServer.getInstance();

这样XmppServer通过加载spring启动了mina监听服务,这时手机客户端应用已经可以连接服务端了。

你的应用程序需要推送消息时,实例化

org.androidpn.server.xmpp.push.NotificationManager,调用其提供的sendBroadcast和sendNotifcationToUser方法,如下代码调用:

NotificationManager notificationManager = new NotificationManager();
    notificationManager.sendBroadcast("1234567890", "Hello","Hello BalanceJia!", "uri");
    或
    notificationManager.sendNotifcationToUser(apiKey,username, title, message, uri);

情况二:若你的项目中用到spring

和你的项目中spring配置融合,需要注意spring容器不能重复启动的问题。所以要将androidpn-server的spring配置增加到你的spring配置中,需要修改XmppServer启动spring的地方,另外androidpn-server spring中配置的ben名字和你项目中的本名字不能重复,因为androidpn-server中用到的ben id有:dataSource、dataSource、transactionManager、userDao、userService。还有数据源冲突的问题。

情况三:基于tomcat部署

1.依据ServerStart类写一个servlet,在servlet中启动时创建XmppServer实例。然后在web.xml中配置为自启动。

2.将androidpn自带的配置目录conf拷贝到WEB-INF下面,并且把spring-config.xml文件从conf目录移动到WEB-INF目录。

3.修改默认的spring-config.xml文件,在文件schema的头部下面加入如下内容,其中,加载顺序会默认先加载applicationContext文件,然后会加载spring-config文件后面的内容。

原因是spring-config文件中有个组件会在web服务启动的时候加载,该组件也会初始化XmppServer,导致与servlet的加载发生冲突。

由于未使用使用hibernate-cfg.xml文件,需要在spring-config文件加入如下内容:

<bean id="sessionFactory"
       class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
       <property name="dataSource" ref="dataSource" />
       <property name="mappingResources" >
      <list>
    <value>org/androidpn/server/model/User.hbm.xml</value>
      </list>
    </property>
    <property name="hibernateProperties">
       <props>
     <prop key="hibernate.dialect">
      org.hibernate.dialect.SQLServerDialect
     </prop>
     <prop key="hibernate.show_sql">true</prop>
     <prop key="hibernate.hbm2ddl.auto">update</prop>
      </props>
     </property>
     </bean>

在spring-config.xml文件中,配置组件的listenrPort属性

<bean id="listenrPort" class="java.net.InetSocketAddress">
     <constructor-arg value="localhost"/>
     <constructor-arg value="5222"/>
    </bean>

此外,Androidpn默认采用spring-mvc方式配置,所以需要修改action指向。修改org.androidpn.server.console.controller包下面的三个类,改为继承自struct2的ActionSupport方式,并修改默认的调用方法,然后配置struct.xml文件。

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:8月以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:8月以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:8月以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:8月以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:8月以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:8月以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:8月以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:8月以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:8月以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:8月以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:8月以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:8月以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:8月以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:8月以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:8月以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:8月以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:8月以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:8月以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:8月以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:8月以前  |  398次阅读  |  详细内容 »
 相关文章
Android插件化方案 5年以前  |  236913次阅读
vscode超好用的代码书签插件Bookmarks 1年以前  |  7118次阅读
 目录