androidpn的学习研究(七)Androidpn-server的添加其他xmpp相关的协议(如查看好友列表等)...
曾经有一个同学,在网上问我,如果想androidpn添加额外的xmpp协议的方法在怎么加呢?我当时很迷惑,后来经过一翻仔细研究androidpn发现,其实每一种处理xmpp协议方法,必须有一个Handler实现。具体可以参考org.androidpn.server.xmpp.handler中。
针对每一个Handler对应的xml拥有不同的命名空间,每一个命名空间在xmpp中都有定义,因为传输的xml的格式是一定的。
例如:
IQAuthHandler:命名空间 String NAMESPACE = "jabber:iq:auth";
IQRegisterHandler:命名空间 String NAMESPACE = "jabber:iq:register";
IQRosterHandler:命名空间 String NAMESPACE = "jabber:iq:roster";
同时我们从Handler的实现可以看到每一个handler最好实现对应IQHandler类,但是为辅助类型的Handler那么可以不用,例如androidpn的状态更新处理器类PresenceUpdateHandler,不必要发送相关的消息到客户端。
所以如果要实现xmpp中如查看好友,用户分组等通信协议,那么你可能要实现相关的Handler并使用xmpp协议规定的相关的命名空间。
在androidpn中主要的业务处理类XmppIoHandler可以看出最终消息解析之后分发到IQRouter中。IQRouter用于处理消息的响应的消息。
IQRouter的源代码如下:
- packageorg.androidpn.server.xmpp.router;
- importjava.util.ArrayList;
- importjava.util.List;
- importjava.util.Map;
- importjava.util.concurrent.ConcurrentHashMap;
- importorg.androidpn.server.xmpp.handler.IQAuthHandler;
- importorg.androidpn.server.xmpp.handler.IQHandler;
- importorg.androidpn.server.xmpp.handler.IQRegisterHandler;
- importorg.androidpn.server.xmpp.handler.IQRosterHandler;
- importorg.androidpn.server.xmpp.session.ClientSession;
- importorg.androidpn.server.xmpp.session.Session;
- importorg.androidpn.server.xmpp.session.SessionManager;
- importorg.apache.commons.logging.Log;
- importorg.apache.commons.logging.LogFactory;
- importorg.dom4j.Element;
- importorg.xmpp.packet.IQ;
- importorg.xmpp.packet.JID;
- importorg.xmpp.packet.PacketError;
- /**
- *ThisclassistorouteIQpacketstotheircorrespondinghandler.
- *
- *@authorSehwanNoh(devnoh@gmail.com)
- */
- publicclassIQRouter{
- privatefinalLoglog=LogFactory.getLog(getClass());
- privateSessionManagersessionManager;
- privateList<IQHandler>iqHandlers=newArrayList<IQHandler>();
- privateMap<String,IQHandler>namespace2Handlers=newConcurrentHashMap<String,IQHandler>();
- /**
- *ConstuctsapacketrouterregisteringnewIQhandlers.
- */
- publicIQRouter(){
- sessionManager=SessionManager.getInstance();
- iqHandlers.add(newIQAuthHandler());
- iqHandlers.add(newIQRegisterHandler());
- iqHandlers.add(newIQRosterHandler());
- }
- /**
- *RoutestheIQpacketbasedonitsnamespace.
- *
- *@parampacketthepackettoroute
- */
- publicvoidroute(IQpacket){
- if(packet==null){
- thrownewNullPointerException();
- }
- JIDsender=packet.getFrom();
- ClientSessionsession=sessionManager.getSession(sender);
- if(session==null
- ||session.getStatus()==Session.STATUS_AUTHENTICATED
- ||("jabber:iq:auth".equals(packet.getChildElement()
- .getNamespaceURI())
- ||"jabber:iq:register".equals(packet.getChildElement()
- .getNamespaceURI())||"urn:ietf:params:xml:ns:xmpp-bind"
- .equals(packet.getChildElement().getNamespaceURI()))){
- handle(packet);
- }else{
- IQreply=IQ.createResultIQ(packet);
- reply.setChildElement(packet.getChildElement().createCopy());
- reply.setError(PacketError.Condition.not_authorized);
- session.process(reply);
- }
- }
- privatevoidhandle(IQpacket){
- try{
- ElementchildElement=packet.getChildElement();
- Stringnamespace=null;
- if(childElement!=null){
- namespace=childElement.getNamespaceURI();
- }
- if(namespace==null){
- if(packet.getType()!=IQ.Type.result
- &&packet.getType()!=IQ.Type.error){
- log.warn("Unknownpacket"+packet);
- }
- }else{
- IQHandlerhandler=getHandler(namespace);
- if(handler==null){
- sendErrorPacket(packet,
- PacketError.Condition.service_unavailable);
- }else{
- handler.process(packet);
- }
- }
- }catch(Exceptione){
- log.error("Couldnotroutepacket",e);
- Sessionsession=sessionManager.getSession(packet.getFrom());
- if(session!=null){
- IQreply=IQ.createResultIQ(packet);
- reply.setError(PacketError.Condition.internal_server_error);
- session.process(reply);
- }
- }
- }
- /**
- *Sendatheerrorpackettotheoriginalsender
- */
- privatevoidsendErrorPacket(IQoriginalPacket,
- PacketError.Conditioncondition){
- if(IQ.Type.error==originalPacket.getType()){
- log.error("CannotreplyanIQerrortoanotherIQerror:"
- +originalPacket);
- return;
- }
- IQreply=IQ.createResultIQ(originalPacket);
- reply.setChildElement(originalPacket.getChildElement().createCopy());
- reply.setError(condition);
- try{
- PacketDeliverer.deliver(reply);
- }catch(Exceptione){
- //Ignore
- }
- }
- /**
- *AddsanewIQHandlertothelistofregisteredhandler.
- *
- *@paramhandlertheIQHandler
- */
- publicvoidaddHandler(IQHandlerhandler){
- if(iqHandlers.contains(handler)){
- thrownewIllegalArgumentException(
- "IQHandleralreadyprovidedbytheserver");
- }
- namespace2Handlers.put(handler.getNamespace(),handler);
- }
- /**
- *RemovesanIQHandlerfromthelistofregisteredhandler.
- *
- *@paramhandlertheIQHandler
- */
- publicvoidremoveHandler(IQHandlerhandler){
- if(iqHandlers.contains(handler)){
- thrownewIllegalArgumentException(
- "CannotremoveanIQHandlerprovidedbytheserver");
- }
- namespace2Handlers.remove(handler.getNamespace());
- }
- /**
- *ReturnsanIQHandlerwiththegivennamespace.
- */
- privateIQHandlergetHandler(Stringnamespace){
- IQHandlerhandler=namespace2Handlers.get(namespace);
- if(handler==null){
- for(IQHandlerhandlerCandidate:iqHandlers){
- if(namespace.equalsIgnoreCase(handlerCandidate.getNamespace())){
- handler=handlerCandidate;
- namespace2Handlers.put(namespace,handler);
- break;
- }
- }
- }
- returnhandler;
- }
- }
由以上的源代码可以看出,IQRouter在加载时候将各种处理器添加到回话管理器中,当消息分发到IQRouter中时候,根据命名空间的不同使用不同的处理处置即可。
androidpn的学习研究(七)Androidpn-server的添加其他xmpp相关的协议(如查看好友列表等)...相关推荐
- BT源代码学习心得(七):跟踪服务器(Tracker)的代码分析(HTTP协议处理对象) -- 转贴自 wolfenstein (NeverSayNever)
BT源代码学习心得(七):跟踪服务器(Tracker)的代码分析(HTTP协议处理对象) author: wolfenstein (NeverSayNever) 上次我们分析了Tracker类初始化的 ...
- androidpn的学习研究(六)Androidpn-server的Mina编码和解码解析过程
在许多网络应用中可能针对传输的数据进行加密操作,接收到数据之后进行解码操作. 在mina中提供许多加密和解密的解析方式: 1.带一定前缀的字符串的解析方式. 2.序列化对象的字符串解析方式. 3.分隔 ...
- androidpn的学习研究(二)androidpn-server服务端启动过程的理解分析
在Androidpn的底层主要采用的mina和openfire两大框架,其中mina主要为底层数据传输的Socket框架.下面简单说明mina的框架. Apache Mina Server 是一个网络 ...
- androidpn的学习研究(八)androidpn 中业务类XmppIoHandler实现分析
在androidpn中主要采用Mina进行网络通讯,其中Mina中IoHandler用来处理主要的业务逻辑. Mina 中源代码如下: Java代码 package org.apache.mina ...
- androidpn的学习研究(五)androidpn-client 常见BUG解决方法
原文地址:http://phonepush.sinaapp.com/forum.php?mod=viewthread&tid=6&extra=page%3D1 最近有需要做手机推送方面 ...
- androidpn的学习研究(一)androidpn-server服务端相关配置的常识
androidpn的一些基本常识: ANDROIDPN_HOME=C:\android-push\androidpn-server-0.5.0 启动androidpn服务端: %ANDROID_HOM ...
- androidpn的学习研究(四)androidpn-client客户端几个类说明
在androidpn的客户端几个重要的类: ServiceManager:管理消息服务和加载相关的配置. ConnectivityReceiver:处理网络状态的广播. NotificationRec ...
- androidpn的学习研究(三)androidpn-server服务端几个类说明
AndroidPN(Android Push Notification) 是一个基于XMPP协议的Java开源推送通知实现,它包含了完整的客户端和服务端. AndroidPN基于Openfire下的一 ...
- 强化学习实践七:给Agent添加记忆功能
在<强化学习>第一部分的实践中,我们主要剖析了gym环境的建模思想,随后设计了一个针对一维离散状态空间的格子世界环境类,在此基础上实现了SARSA和SARSA(λ)算法.<强化学习& ...
最新文章
- tinyxml 读取文本节点_TinyXml 读写XML文件
- JavaScript之数据类型
- Php7安装pdo_pgsql,pgsql扩展
- 书籍推荐:《More Effective C#》
- html5响应式网站优势,响应式网站优势有哪些 真的利于排名优化么
- MATLAB二维数组的创建与元素提取
- java synoch 加锁_线程间通信 - HappyCowboy - 博客园
- python快速入门及进阶
- 项目管理:文档可测试化
- (转载)用C#实现MySQL建库及建表
- 解决清除浮动的最佳办法
- char 数组和 int 之间转化
- [转]Java 的强引用、弱引用、软引用、虚引用
- SAP License:ERP系统和OA系统的区别?
- 手把手带你将手机打造一台私人便捷服务器及私人云盘
- jQuery实现简单分页
- 凹入法写入指定目录至文档,并计算目录大小
- bootstrap table th内容太多表格撑破(自动换行)
- 参数方程求二阶导时候不能直接把y,x分别对t求二阶导然后再相除作为d²y/dx²的原因
- 黑白棋(Othello)
热门文章
- [转]nodejs npm常用命令
- 关于WEB集群中文件服务器的讨论
- 编译安装postfix+sasl+mysql+dovecot+extmail构建完成的邮件系统(一)
- 使用Java的代理机制进行日志输出
- 题解 P2610 【[ZJOI2012]旅游】
- 《区块链原理、设计与应用》一3.8 本章小结
- 【译】技能测试解决方案:Python中的数据科学(一)
- 野心勃勃的NoSQL新贵 MongoDB应用实战(5)
- svn in xcode5
- Sql Function defference returns and returns