`
longgangbai
  • 浏览: 7330464 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

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的源代码如下:

 

package org.androidpn.server.xmpp.router;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.androidpn.server.xmpp.handler.IQAuthHandler;
import org.androidpn.server.xmpp.handler.IQHandler;
import org.androidpn.server.xmpp.handler.IQRegisterHandler;
import org.androidpn.server.xmpp.handler.IQRosterHandler;
import org.androidpn.server.xmpp.session.ClientSession;
import org.androidpn.server.xmpp.session.Session;
import org.androidpn.server.xmpp.session.SessionManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Element;
import org.xmpp.packet.IQ;
import org.xmpp.packet.JID;
import org.xmpp.packet.PacketError;

/** 
 * This class is to route IQ packets to their corresponding handler.
 *
 * @author Sehwan Noh (devnoh@gmail.com)
 */
public class IQRouter {

    private final Log log = LogFactory.getLog(getClass());

    private SessionManager sessionManager;

    private List<IQHandler> iqHandlers = new ArrayList<IQHandler>();

    private Map<String, IQHandler> namespace2Handlers = new ConcurrentHashMap<String, IQHandler>();

    /**
     * Constucts a packet router registering new IQ handlers.
     */
    public IQRouter() {
        sessionManager = SessionManager.getInstance();
        iqHandlers.add(new IQAuthHandler());
        iqHandlers.add(new IQRegisterHandler());
        iqHandlers.add(new IQRosterHandler());
    }

    /**
     * Routes the IQ packet based on its namespace.
     * 
     * @param packet the packet to route
     */
    public void route(IQ packet) {
        if (packet == null) {
            throw new NullPointerException();
        }
        JID sender = packet.getFrom();
        ClientSession session = 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 {
            IQ reply = IQ.createResultIQ(packet);
            reply.setChildElement(packet.getChildElement().createCopy());
            reply.setError(PacketError.Condition.not_authorized);
            session.process(reply);
        }
    }

    private void handle(IQ packet) {
        try {
            Element childElement = packet.getChildElement();
            String namespace = null;
            if (childElement != null) {
                namespace = childElement.getNamespaceURI();
            }
            if (namespace == null) {
                if (packet.getType() != IQ.Type.result
                        && packet.getType() != IQ.Type.error) {
                    log.warn("Unknown packet " + packet);
                }
            } else {
                IQHandler handler = getHandler(namespace);
                if (handler == null) {
                    sendErrorPacket(packet,
                            PacketError.Condition.service_unavailable);
                } else {
                    handler.process(packet);
                }
            }

        } catch (Exception e) {
            log.error("Could not route packet", e);
            Session session = sessionManager.getSession(packet.getFrom());
            if (session != null) {
                IQ reply = IQ.createResultIQ(packet);
                reply.setError(PacketError.Condition.internal_server_error);
                session.process(reply);
            }
        }
    }

    /**
     * Senda the error packet to the original sender
     */
    private void sendErrorPacket(IQ originalPacket,
            PacketError.Condition condition) {
        if (IQ.Type.error == originalPacket.getType()) {
            log.error("Cannot reply an IQ error to another IQ error: "
                    + originalPacket);
            return;
        }
        IQ reply = IQ.createResultIQ(originalPacket);
        reply.setChildElement(originalPacket.getChildElement().createCopy());
        reply.setError(condition);
        try {
            PacketDeliverer.deliver(reply);
        } catch (Exception e) {
            // Ignore
        }
    }

    /**
     * Adds a new IQHandler to the list of registered handler.
     * 
     * @param handler the IQHandler
     */
    public void addHandler(IQHandler handler) {
        if (iqHandlers.contains(handler)) {
            throw new IllegalArgumentException(
                    "IQHandler already provided by the server");
        }
        namespace2Handlers.put(handler.getNamespace(), handler);
    }

    /**
     * Removes an IQHandler from the list of registered handler.
     * 
     * @param handler the IQHandler
     */
    public void removeHandler(IQHandler handler) {
        if (iqHandlers.contains(handler)) {
            throw new IllegalArgumentException(
                    "Cannot remove an IQHandler provided by the server");
        }
        namespace2Handlers.remove(handler.getNamespace());
    }

    /**
     * Returns an IQHandler with the given namespace.
     */
    private IQHandler getHandler(String namespace) {
        IQHandler handler = namespace2Handlers.get(namespace);
        if (handler == null) {
            for (IQHandler handlerCandidate : iqHandlers) {
                if (namespace.equalsIgnoreCase(handlerCandidate.getNamespace())) {
                    handler = handlerCandidate;
                    namespace2Handlers.put(namespace, handler);
                    break;
                }
            }
        }
        return handler;
    }

}

 

        由以上的源代码可以看出,IQRouter在加载时候将各种处理器添加到回话管理器中,当消息分发到IQRouter中时候,根据命名空间的不同使用不同的处理处置即可。
 

分享到:
评论
2 楼 longgangbai 2012-09-22  
109492927 写道
这个明白,请解释一下,客户端需要使用上面的命名空间给服务器传消息吗?

androidpn客户端也使用命名空间的发送给服务,开源的androidpn-client中之封装部分,如果想增加相关的功能可能就需要自己扩展咯
1 楼 109492927 2012-09-17  
这个明白,请解释一下,客户端需要使用上面的命名空间给服务器传消息吗?

相关推荐

    androidpn-client-0.5.0.zip和androidpn-server-0.5.0-bin.zip

    首先, 我们需要下载androidpn-client-0.5.0.zip和androidpn-server-0.5.0-bin.zip。 下载地址:http://sourceforge.net/projects/Androidpn/ 解压两个包,Eclipse导入client,配置好目标平台,打开raw/...

    androidpn-client-0.5.0 AND androidpn-server-0.5.0

    使用Apndroid Push Notification 实现android信息推送,AndroidPn项目是使用XMPP协议实现信息推送的一个开源项目。内涵服务端和客户端源码

    xmpp-androidPn server and client

    1. androidpn-server-0.5.0-bin.zip:这个文件包含了一个预编译的AndroidPN服务器。AndroidPN服务器是基于XMPP协议构建的,用于向Android设备发送推送通知。服务器接收来自应用的请求,然后将消息推送到注册的...

    androidpn-client-Demo.zip_DEMO_androidpn-server_asmack _xmpp _推送

    基于XMPP协议、使用Androidpn服务器,Asmack编程的即时通讯IM客户端源代码;主要功能实现向客户端推送消息!

    androidpn-tomcat-0.5.0

    另一方面,"androidpn-server-tomcat.zip"则包含了AndroidPN服务端的部署包,这部分是基于Tomcat服务器运行的。Tomcat是Apache软件基金会的Jakarta项目下的一个开源产品,它实现了Java Servlet和JavaServer Pages...

    androidpn基于Xmpp的消息推送源码.zip

    androidpn客户端需要用到一个基于java的开源XMPP协议包asmack,这个包同样也是基于openfire下的另外一个开源项目smack,不过我们不需要自己编译,可以直接把androidpn客户端里面的asmack.jar拿过来用。客户端利用...

    androidpn-client-0.5.0

    这通常通过XMPP(Extensible Messaging and Presence Protocol)协议实现,因为XMPP支持双向通信,适合推送服务。 2. **注册过程**:应用首次安装时,客户端会向AndroidPN服务器注册,获取一个唯一的设备标识符,如...

    androidpn 相关文件

    androidpn xmpp 消息推送 供研究学习使用 项目相关的jar包 androidpn-client-0.5.0,androidpn-server-0.5.0-binmandroidpn-server-0.5.0-src

    androidpn_tomcat整合(发布直接使用)

    4. **配置XML文件**:AndroidPN-server可能需要一些特定的XML配置文件,例如`server.xml`、`context.xml`等,以定义连接池、数据源和其他服务器设置。根据需求,编辑这些文件以适应你的环境。 5. **数据库连接**:...

    androidpn(客户端和服务器端)

    androidpn-client.zip和androidpn-server-0.5.0-bin.zip, 解压两个包,Eclipse导入client,配置好目标平台,打开raw/androidpn.properties文件, apiKey=1234567890 xmppHost=10.0.2.2 xmppPort=5222 如果是...

    安卓XMPP聊天通讯Socket相关-XMPP(Android客户端的实现Tomcat版的Androidpn).rar

    【标题】中的“安卓XMPP聊天通讯Socket相关-XMPP(Android客户端的实现Tomcat版的Androidpn).rar”提到了XMPP(Extensible Messaging and Presence Protocol)在Android平台上的实现,以及它与Tomcat服务器的结合。...

    XMPP(Android客户端的实现__Tomcat版的Androidpn_)

    XMPP(Extensible Messaging and Presence Protocol)是一种开放的即时通讯协议,主要用于实现用户之间的实时通信。在Android平台上实现XMPP客户端,可以构建出强大的聊天应用,例如即时消息、群聊、状态更新等功能...

    androidpn消息推送-tomcat版

    3. **XMPP协议解析(org.androidpn.server.xmpp.codec)**:负责消息的编码和解码工作。 4. **消息处理(org.androidpn.server.xmpp.handler)**:根据消息类型进行相应的处理操作。 5. **连接维护(org.androidpn.server...

    基于XMPP协议的消息推送(内含有服务器和客户端)一看就懂 简单实用

    例如,`androidpn-server-0.5.0`可能是一个专为Android平台设计的XMPP服务器实现,负责接收客户端发送的消息,并将它们分发到正确的目标客户端。 客户端则是用户与XMPP系统的接口,它们负责建立与服务器的连接,...

    androidpn-消息推送文档宣贯.pdf

    AndroidPN(Android Push Notification)是一种基于XMPP(Extensible Messaging and Presence Protocol)协议的消息推送服务,主要用于Android设备。本文档详细介绍了AndroidPN的通信机制、客户端功能和服务器结构。...

    androidPn-client

    在这个项目中,`asmack`库被用于处理XMPP协议,这是一种广泛用于即时通讯(IM)和推送通知的开放标准。 `asmack`是一个针对Android平台优化的Smack库的分支,Smack是Java中用于处理XMPP的开源库。由于Android系统对...

    XMPP协议学习资料

    1. 数据传输基于广泛使用的XMPP协议,与其他如QQ、MSN、GTalk等即时通讯服务兼容。 2. 提供了良好的框架支持,简化了开发者实现推送通知的复杂度。 3. 利用MINA框架有效处理高并发连接,提高了系统效率。 4. 采用TLS...

    【整理】解刨AndroidPN消息推送.pdf

    - org.androidpn.server.xmpp.codec:负责XMPP协议的XML文件解析,服务器通过此包进行消息的编码和解码。 - org.androidpn.server.xmpp.handler:负责处理不同类型的消息。 ***:负责维护与客户端之间的持久连接,并...

Global site tag (gtag.js) - Google Analytics