`
ssxxjjii
  • 浏览: 944913 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

开发openfire的内部组件

    博客分类:
  • IM
 
阅读更多

http://blog.csdn.net/otangba/article/details/8212593

openfire的组件分为内部组件和外部组件两种,可能大家不一定完全明白什么意思,我解释一下:

内部组件是工作在openfire运行环境的插件,是以独立的jar包存在,具有访问和控制openfire主域的权限,其最主要的能力就是,可以参与和控制主域的通信。

外部组件是实现XEP-0114规范的实例,确切的说就是独立的应用程序,通过tcp通信的方式连接到openfire上,只能参与和控制独立的子域通信。

因此,内外部组件的应用场景非常容易区分,就是看,你是否需要使用服务器主域资源。

例如,你需要在某些特定场景下枚举服务器上所有的用户,那么你无法用外部组件实现,只能通过内部组件实现。

那么为什么要有外部组件呢,子域又是什么,请看我的例子:

 

有2家公司,各有员工500人,需要实现xmpp互通,但是是受到逻辑约束的,某些人只能和另外公司的某些人沟通,你也许想说,把两个公司的员工都放在主域上,用内部组件进行控制,的确,没问题,但是如果两家公司各自通信有特殊的业务需求怎么办?是不是要在内部组件写很多的分支呢。

于是我们假设A公司的子域为coma,B公司子域为comb,服务器主域为example.com,那么我们就可以创建2个外部组件(类)来分别控制2个公司的通信,第一个外部组件componenta负责域coma.example.com,componentb负责comb.example.com

我们通过实现2个类来完成2个外部组件的操作,一旦实例化并和服务器建立了安全连接之后,所有的业务逻辑就很简单了。

 

对于外部组件今天我先暂且搁置,先说说内部组件。

下面涉及的代码是一个例子项目,任务是把openfire的用户在线状态同步到redis里,类似的解决方案在openfire源码自带的presence service插件里也有实现,不过那个是提供了一个web的rest接口,用起来当然没有redis爽快。

实现逻辑,注册一个组件,注入到包通信中,截获presence包

当presence的type为unavaiable时,认为用户离线,对比redis内原来用户状态,如果变更,则将离线状态写入redis。

当截获到type为空的presence包,则认为用户在线。

另外为组件实现一个web控制台,可以删除所有的用户以及初始化同步一次openfire已有的用户状态。

内部组件的编写比较简单,基本上下载了openfire源码就可以开始写,不用准备额外的jar包。

一个合法的内部组件,首先,位置必须在src/plugins下,建立组件的目录,再创建src/java存放java代码src/web存放web console的jsp页面

上图就是一个合法的内部组件的位置

在组件目录,例子中的synUserStateToRedis里,需要plugin.xml。这个文件是组件的描述文件,必须。

文件的内容大家可以打开源码内任何一个看看,不需要过多介绍,如果没有web console,可以把<adminconsole>节点忽略。

在src/java目录下,建立组件的package和类代码:

至于编译则非常简单,在eclipse里打开ant的panel,添加位于openfire源码的build下的build.xml

展开之后双击plugins就可以编译所有的组件,如果需要单独编译你的组件,在ant的配置中添加-Dplugin=你的组件名,该组件名是在xml里面配置的名称,也是组件类getName()方法返回的那个字符串,不是组件的类名。

 

组件的实现有多种方式,这个可以参考jivesoftware的官方文档,不过我看用的比较多的还是PacketInterceptor模式。

新建一个类,实现Plugin,PacketInterceptor,必须完成三个方法的重写,interceptPacket,initializePlugin,destroyPlugin。

顾名思义,分别是实现包的注入,初始化组件和销毁组件。外部组件的某些开发方式中,jivesoftware提供了继承component类来更简单的重写对不同类型数据包的操作,而在这里,你只能利用interceptPacket来完成对所有类型的包进行操作。

例如我要处理presence包,我会这么写:

 

[html] view plaincopy
  1. public void interceptPacket(Packet packet, Session session,  
  2.             boolean incoming, boolean processed) throws PacketRejectedException {  
  3.         if (!processed && incoming) {  
  4.             if (packet instanceof Presence) {  
  5.                 // Respond to presence subscription request or presence probe  
  6.                 Presence presence = (Presence) packet;  
  7.                 processPresence(presence);  
  8.             }  
  9.         }  
  10.   
  11.     }  

 

 

如果要让你的组件在openfire后台有嵌入的界面,那么就在src/web下编写你的jsp页面

主要部分:

 

[html] view plaincopy
  1. <%@ page import="java.util.*,  
  2.                  org.jivesoftware.openfire.XMPPServer,  
  3.                  org.jivesoftware.util.*,  
  4.                  org.jivesoftware.openfire.plugin.SynUserStateToRedis"  
  5.     errorPage="error.jsp"  
  6. %>  
  7. <%@ page contentType="text/html; charset=UTF-8"%>  
  8. <%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>  
  9. <%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>  
  10.   
  11. <%-- Define Administration Bean --%>  
  12. <jsp:useBean id="admin" class="org.jivesoftware.util.WebManager"  />  
  13. <c:set var="admin" value="${admin.manager}" />  
  14. <% admin.init(request, response, session, application, out ); %>  
  15.   
  16. <%  // Get parameters  
  17.     boolean init = request.getParameter("init") != null;  
  18.       
  19.     SynUserStateToRedis plugin = (SynUserStateToRedis) XMPPServer.getInstance().getPluginManager().getPlugin("synuserstatetoredis");  
  20.       
  21. %>  

为了让jsp页面实现初始化同步用户的逻辑,我们在组件的类里添加一个方法:

 

[java] view plaincopy
  1. public int initUserStates() {  
  2.         int cnt=0;  
  3.         Jedis jedis = RedisManager.getInstance().getRedis();  
  4.         Pipeline pl = jedis.pipelined();  
  5.         Collection<User> users = userManager.getUsers();  
  6.         try {  
  7.   
  8.             for (User u : users) {  
  9.                 int state = STATUS_ONLINE;  
  10.                 Presence p = presenceManager.getPresence(u);  
  11.                 if (p == null) {  
  12.                     state = STATUS_OFFLINE;  
  13.                 } else if (p.getType() == Type.unavailable) {  
  14.                     state = STATUS_OFFLINE;  
  15.                 }  
  16.                 pl.hset(REDIS_KEY, u.getUsername(), String.valueOf(state));  
  17.                 cnt ++;  
  18.                   
  19.             }  
  20.             pl.sync();  
  21.         } catch (Exception e) {  
  22.             // TODO: handle exception  
  23.         }  
  24.         RedisManager.getInstance().returnJedis(jedis);  
  25.         return cnt;  
  26.     }  

这个方法是将openfire的用户枚举并且判断其状态,批量写入到redis

 

在jsp中这样调用即可

 

[html] view plaincopy
  1. <%  if (init) {   
  2. String initedUserNum=String.valueOf(plugin.initUserStates());  
  3. %>  
  4.     <div class="jive-success">  
  5.     <table cellpadding="0" cellspacing="0" border="0">  
  6.     <tbody>  
  7.         <tr><td class="jive-icon"><img src="images/success-16x16.gif" width="16" height="16" border="0"></td>  
  8.         <td class="jive-icon-label">  
  9.             操作执行成功,同步了<%=initedUserNum%>个用户。  
  10.         </td></tr>  
  11.     </tbody>  
  12.     </table>  
  13.     </div><br>  
  14. <% }%>  


完成之后,编译,在openfire后台直接上传

 

 

相关的web console:


应该说开发内部组件还是比较简单的,理解了原理之后对于java程序员来说应该是小意思,

总体来说openfire还是性能不错的xmpp服务器,大家不妨可以换个思路考虑一下是否可以利用即时通信服务来实现原来基于web实现的业务。

分享到:
评论

相关推荐

    XMPP开发Openfire详细介绍

    ### XMPP开发Openfire详细介绍 #### 一、XMPP与Openfire概述 XMPP(Extensible Messaging and Presence Protocol,可扩展消息与呈现协议)是一种基于XML的即时通讯协议,广泛应用于构建即时通讯系统。Openfire是一...

    Openfire开发资料

    "Openfire 及插件开发.doc"中详细讲述了如何开发Openfire服务和插件,包括设计架构、编写代码、测试和部署的步骤。同时,了解Openfire的内部工作原理,如组件模型、数据库交互和XMPP协议的实现,对于高效开发至关...

    openfire深入浅出

    OpenFire是一款基于Java开发的XMPP服务器,支持多用户聊天、群聊、文件传输等功能,广泛应用于企业内部沟通、在线客服以及游戏社交等领域。 首先,书中会介绍OpenFire的基本概念和架构。XMPP(Extensible Messaging...

    openfire_src_3_8_2.zip

    《Openfire服务器源码解析与XMPP协议探秘》 Openfire是一款开源的即时通讯(IM)...通过深入研究源码,开发者不仅能掌握Openfire的内部运作机制,还能提升对分布式通信系统的理解,为构建自己的IM系统打下坚实基础。

    openfire开发资料

    开发Openfire插件时,开发者可以利用这些类名后缀的约定,快速理解和构建系统组件。通过插件化开发,Openfire能够灵活应对各种业务需求,保持核心代码的稳定性和可维护性。对于希望深入了解或定制Openfire功能的...

    openfire二次开发资料整理

    ### Openfire二次开发资料知识点梳理 #### 一、XMPP协议概述 - **XMPP**(Extensible Messaging and Presence Protocol)是一种基于XML的即时通信协议。该协议的主要特点是使用XML作为消息格式,使得消息能够携带...

    openfire3.8.1API

    API提供了对这些核心组件的编程访问,让开发者能够自定义功能,如集成企业内部系统或创建特定的应用程序。 3. **API接口**:API文档通常包含各种方法、类和接口的详细描述,例如用户管理接口(创建、删除、查询用户...

    目前最详尽的openfire介绍

    总之,Openfire结合XMPP协议、Apache MINA框架以及Spark和Smack等组件,构建了一套完整的即时通信解决方案,不仅支持基本的文本聊天,更具备高度的可扩展性和定制化能力,适用于多种应用场景,包括企业级通信、网络...

    JAVA源码+openfire+spark 即时通讯

    源码的学习可以帮助理解即时通讯系统的架构和工作原理,openfire和spark则提供了现成的基础设施,大大减少了从零开始的开发成本。对于初学者,这是一个很好的实践平台;对于有经验的开发者,这是一个快速原型验证和...

    openfire_3_8_2

    在使用Openfire 3.8.2版本时,您会发现它已经包含了所有必要的组件和服务,只需解压提供的"openfire"文件,按照官方文档进行安装和配置即可开始使用。在开发聊天工具时,您可以利用Openfire提供的功能来快速搭建基础...

    openfire服务器插件

    Openfire是一款基于Java开发的开源XMPP(Extensible Messaging and Presence Protocol)服务器,广泛应用于企业内部通信、在线协作以及实时消息传递。通过安装各种插件,用户可以定制化Openfire以满足特定需求。 ...

    openfire tar包

    8. **API与集成**: 开发者可以利用Openfire提供的API和SDK来开发自定义的客户端或者集成到现有应用中,增强企业的工作流程。 9. **多语言支持**: Openfire支持多种语言,满足全球化企业的需要。 10. **监控与日志*...

    openfire + spark 视频通话 war包和jar包

    Openfire是用Java开发的,它通过XMPP(可扩展消息传递和Presence协议)提供实时通信服务。XMPP是一种开放的标准,用于构建分散式、可扩展的即时消息和在线状态系统。Openfire的核心功能包括用户管理和认证、群聊、...

    openfire_3_9_3.tar.zip

    Openfire是一款基于Java开发的开源即时通讯(Instant Messaging, IM)服务器,其强大的功能和易用性使其在全球范围内被广泛应用于企业内部沟通、在线客服以及多用户协作等多种场景。"openfire_3_9_3.tar.zip"是...

    spark-openfire一些资料

    - 开发Openfire插件:Openfire的插件系统允许开发者创建新的功能模块,比如权限管理、审计日志、自定义认证机制等。 - 集成其他系统:Spark和Openfire可以与其他系统集成,例如CRM、ERP等,实现业务流程中的即时...

    openfire服务器的搜索插件和fastjson的Jar包

    Openfire服务器是一款基于Java开发的即时通讯(IM)服务器,它使用XMPP协议提供服务,广泛应用于企业级的内部通信和协作系统。Openfire的可扩展性非常强,支持通过插件来添加额外的功能,例如搜索插件就是其中之一,...

    openfire和spark及时通讯,解压即运行

    Openfire是一款基于Java开发的服务器端即时通讯软件,它采用了XMPP协议,提供实时通信和协作功能。Openfire的主要特点包括: 1. **安全性**:支持SSL/TLS加密,确保通信过程中的数据安全。 2. **可扩展性**:基于...

Global site tag (gtag.js) - Google Analytics