Openfire源码研究
Openfire源码目录结构
1.build目录:build目录下收录的是生成安装文件(例如:rpm)所要的一些文件,例如JRE等。
2.resources目录:resources目录下收录的是一些为实现国际化(i18n)和本地化的一些编码文件(例如:英文,中文,法文,德文等)。
3.documentation目录:documentation目录下收录的是一些关于Openfire安装和配置的信息,但最终要的是这里有Openfire开发的Javadoc。
4.src目录:顾名思义这个src文件夹就是我们想要的Openfire源代码了,这下面又有许多文件夹,我们只要Java文件夹就好,这里面实现的Openfire的核心功能,通过它就可以调试Openfire了。
命名规则
Openfire中常见的类名后缀命名包括Starter、Plugin、Listener、Dispatcher、Handler、Manager、Provider,通常情况下,这些命名类包括如下意义:
XXStarter
系统启动类,如org.jivesoftware.openfire.starter.ServerStarter,调用其start()方法可启动系统应用。
XXListener
业务的最终处理类。
XXDispatcher
调度类,其中有很多关键方法,如addListener(),以组合的方式,为类内定义的静态Set<XXListener>实例添加XXListener对象。以便调用dispatchEvent(String property, EventType eventType, Map<String, Object> params)方法遍历处理Set集中的XXListener对象(通过调用XXListener对象的各实际方法完成实际业务)。
XXPlugin
实现Plugin接口的插件类,需实现initializePlugin(PluginManager manager, File pluginDirectory)方法和destroyPlugin()方法。在其初始化方法中调用Dispatcher实现类的addListener()方法如PropertyEventDispatcher.addListener(this)。
XXProvider
实现面向接口编程方式的接口类,通过反射机制创建具体实现类的对象,反射类名配置在ofproperty表对应的记录propvalue属性中。若没有相关配置,则调用默认实现类,默认实现类类名命名规则为DefaultXXProvider。
XXHandler
实际处理类,以ConnectionHandler为例,在org.jivesoftware.openfire.spi. ConnectionManagerImpl类的startClientSSLListeners(String localIPAddress)方法中,有这样一段代码:sslSocketAcceptor.bind(new InetSocketAddress(bindInterface, port), new ClientConnectionHandler(serverName));其中bind方法的第二个参数是新创建的一个ClientConnectionHandler的实例,而它就是ConnectionHandler的一个子类。
系统配置项
Openfire的系统配置项采用文件结合数据库表的方式配置,也有部分默认配置项通过Java硬编码方式配置(如org.jivesoftware.openfire. ConnectionManager接口类中定义的DEFAULT_PORT、DEFAULT_SSL_PORT、DEFAULT_COMPONENT_PORT等),Openfire中比较重要的配置位置包括:
一、 src/conf目录下的openfire.xml配置文件。该配置文件为系统核心配置文件。在第一次启动Openfire并通过管理控制台完成安装配置后会往该配置文件中填入相应的配置信息。
二、 plugin.xml配置文件。该配置文件为各插件包下的核心配置文件,由它确定插件核心处理类和相应页面插件的展现等。配置项及含义详见官方插件开发说明部分。
三、 web.xml和web-custom.xml配置文件。用于配置servlet和用户自定义servlet(插件页面用,放在插件对应目录下)。
四、 ofproperty中的各条记录,该表中包括两个字段name和propvalue,分别代表配置项名和配置项值。
系统启动流程
系统启动时调用ServerStarter类中的start()方法,通过反射加载org.jivesoftware.openfire.XMPPServer类文件,创建实例时调用其构造函数,在其构造函数中调用其start()方法实际启动服务应用程序。Start()方法中首先调用verifyDataSource()方法验证并确保数据库可以访问,然后会调用 loadModules();initModules();startModules();方法来对Module接口的实现类的各子类进行操作,依次完成模块的加载、初始化和启动操作。loadModules()方法中会调用loadModule(String module)方法通过反射加载各模块类,参数字符串module为对应的模块核心处理类的类名。
客户端
Openfire的socket网络连接包括:
1. 服务器和服务器之间的连接(监听在端口5269)
2. 外部组件和服务器之间的连接(监听在端口5275)
3. 多元(complex)连接(监听在端口5269)
4. 客户端和服务器的连接(监听在端口5222)
5. 和客户端通过TLS/SSL3.0和服务器的连接。(监听在端口5223)
这些连接都是通过ConnectionManager接口实现管理的,程序中对ConnectionManager接口的实现类是ConnectionManagerImpl,它是作为一个模块(Module)类加载到服务器中的。
客户端和服务器的连接
在ConnectionManagerImpl中是通过调用startClientListeners方法来初始化和开始端口监听的。
在startClientListeners方法使用的是Apache的Mina框架来实现网络连接的,Mina框架的模式如下:
IoFilter:
IoFilter为MINA的功能扩展提供了接口。它拦截所有的IO事件进行事件的预处理和后处理。它与Servlet中的filter机制十分相似。多个IoFilter存放在IoFilterChain中
IoFilter能够实现以下功能:
数据转换
事件日志
性能检测
在Openfire中主要用filter(过虐器)这种机制来进行数据转换。
Protocol Codec Factory:
Protocol Codec Factory提供了方便的Protocol支持,通过它的Encoder和Decoder,可以方便的扩展并支持各种基于Socket的网络协议,比如HTTP服务器、FTP服务器、Telnet服务器等等。
要实现自己的编码/解码器(codec)只需要实现interface: ProtocolCodecFactory即可,在Openfire中实现ProtocolCodecFactory的类为XMPPCodecFactory。
IoHandler:
MINA中,所有的业务逻辑都有实现了IoHandler的class完成 ,当事件发生时,将触发IoHandler中的方法:
sessionCreated
sessionOpened
sessionClosed
sessionIdle
exceptionCaught
messageReceived
messageSent
在Openfire中客户端和服务器连接的IoHandler实现类是ClientConnectionHandler,它是从ConnectionHandler中继承来的。
startClientListeners方法首先为Mian框架设置线程池,再将一个由XMPPCodecFactory作为Protocol Codec Factory的Filter放入到FilterChain中,然后绑定到端口5222,并将ClientConnectionHandler作为IoHandler对数据进行处理。完成这些步骤后Openfire就在5222等待客户端的连接。
IOSession
Session可以理解为服务器与客户端的特定连接,该连接由服务器地址、端口以及客户端地址、端口来决定。客户端发起请求时,指定服务器地址和端口,客户端也会指定或者根据网络路由信息自动指定一个地址、自动分配一个端口。这个地址、端口对构成一个Session。
客户端连接的处理过程:
1、当有客户端进行连接时根据Mina框架的模式首先调用的是sessionOpened方法。
sessionOpened首先为此新连接构造了一个parser(XMLLightWeightParser),这个parser是专门给XMPPDecoder(是XMPPCodecFactory的解码器类)使用的,再创建一个Openfire的Connection类实例connection和一个StanzaHandler的实例。最后将以上的parser, connection和StanzaHandler的实例存放在Mina的session中,以便以后使用。
2、当有数据发送过来时,Mina框架会调用messageReceived方法
messageReceived首先从Mina的session中得到在sessionOpened方法中创建的StanzaHandler实例handler,然后从parsers中得到一个parser(如果parsers中没有可以创建一个新的实例)(注意这个parser和在sessionOpened方法中创建的parser不同,这个parser是用来处理Stanza的,而在sessionOpened方法中创建的parser是在filter中用来解码的,一句话说就是在sessionOpened方法中创建的parser是更低一层的parser)。最后将xml数据包交给StanzaHander的实例hander进行处理。
3、StanzaHander的实例hander处理xml数据包的过程
StanzaHander首先判断xml数据包的类型,.如果数据包以“<stream:stream”打头那么说明客户端刚刚连接,需要初始化通信(符合XMPP协议)Openfire首先为此客户端建立一个与客户端JID相关的ClientSession,而后与客户端交互协商例如是否使用SSL,是否使用压缩等问题。当协商完成之后进入正常通信阶段,则可以将xml数据包交给PacketRouteImpl模块进行处理。
4、PacketRouteImpl中包将进一步被细化处理
PacketRouteImp1将packet分成Message、Iq和Presence,分别交由MessageRouter、IqRouter和PresenceRouter进行下一步路由。
MessageRoute处理
调用routetableImp1进行处理,然后交由通过getRoute方法获取session,最后调用NIOConnection的deliver方法。
IQRoute 处理
根据IQ的不同的命名空间通过getHandler方法找到相应的iq处理方法进行处理。
注意:在IQRouter的initialize方法中,iqHandlers.addAll方法会将iq的命名空间与其对应的处理方法存储到一个map中。
PresenceRoute处理
调用PresenceUpdateHandler的process方法(处理数据库的更新和缓存的更新),然后调用Roster的boradcastPresence方法(检查privacy list(隐身及黑名单用户)然后路由给所有在线好友),再调用routeTable的getRoutes()获取session,最后调用NIOConnection的deliver方法。
数据库处理
Openfire的数据库处理采用直接调用JDBC 的方式。核心类为org.jivesoftware.database.DbConnectionManager。数据库的处理与业务处理耦合,没有划分出专门的业务逻辑层。
ConnectionProvider
此类为数据库提供者接口,如需连接mysql、hsqldb等数据库,需首先实现些接口。
处理方式
通常直接调用XXManager中的实例方法,XXManager中又调用的是对应的接口XXProvider的方法,实际操作在该接口的实现类中实现。实现类是动态绑定的(默认的实现类通常命名规则为DefaultXXProvider),在运行时根据ofproperty表中对应配置项值选择。下面以添加用户组为例进行说明。
首先获得GroupManager的一个实例,在调用其构造函数时调用initProvider()方法,在该方法中获取数据库中配置项的值,若不为空则根据该值通过反射机制获取GroupProvider接口的实现类实例对象。
常用类
org.jivesoftware.database.DbConnectionManager
连接管理类
org.jivesoftware.util.JiveGlobals
通常用于操作ofproperty表中记录
用户登录
服务器告诉客户端,服务器支持的认证方法列表。
客户端就可以选其中一个发起真正的认证。
相关推荐
通过深入研究Openfire源码,不仅可以学习到即时通讯服务器的设计和实现,还可以掌握Java网络编程、数据库操作、安全实践、分布式系统等多个方面的知识。这对于任何希望在IM领域或Java后端开发中提升技能的开发者来说...
### Openfire源码部署开发详解 #### 一、Openfire简介 Openfire是一款开源的即时通讯服务器,基于XMPP协议栈。它支持多种客户端,并且能够处理大量的并发连接。Openfire以其灵活性、可扩展性和易用性而受到广泛欢迎...
通过阅读Openfire源码,开发者可以了解即时通讯系统的底层实现,学习如何处理并发连接、优化性能和保证安全性。此外,源码中的注释和文档也能帮助理解设计决策和最佳实践。对于想要二次开发或自定义功能的开发者来说...
通过研究Openfire Spark 2.7.0的源码,开发者不仅可以学习到即时通讯应用的实现,还可以深入理解XMPP协议、Java GUI编程、网络编程以及软件的可扩展性和安全性设计。这对于任何想要从事即时通讯领域或者对Java Swing...
### Openfire源代码研究 #### 一、Openfire源代码目录结构分析 ##### 1. build目录 - **概述**:此目录包含了构建Openfire安装文件所需的资源与配置,例如生成RPM包或其他类型的安装程序时所必需的脚本与文件。 -...
《Openfire 3.5.1源码解析与即时通讯技术探析》 Openfire是一款开源的、基于XMPP协议的即时通讯服务器软件,它的3.5.1版本的源码为我们提供了深入理解其工作原理的宝贵资料。本文将围绕Openfire 3.5.1的源代码进行...
3. 不使用默认位置,指定到Openfire源码文件夹。 第四步,解决导入工程后的错误: 1. 解决clustering插件的错误,需在src/plugins/clustering目录下新建lib文件夹,放入coherence.jar, coherence-work.jar, ...
标题提到的"openfire聊天服务端源码",意味着我们将深入探讨Openfire的源代码,这对于开发者来说是一个宝贵的学习资源。通过源码,我们可以理解Openfire内部的工作机制,学习如何扩展其功能,或者根据特定需求进行...
下面将详细讨论Openfire源码中的关键知识点。 1. **XMPP协议**:Openfire是基于XMPP(Extensible Messaging and Presence Protocol)协议的,这是一种用于即时通讯的开放标准,允许用户进行一对一或群组聊天、文件...
学习Openfire源码有助于理解IM服务器的工作原理,可以参考以下步骤: 1. **阅读源码**:从`src/core`和`src/plugins`开始,了解Openfire的核心组件和插件。 2. **理解协议**:通过阅读`src/proxy`和`src/xmpp`等...
开发者可以研究这些源码来理解插件的工作原理,如何与Openfire的核心系统集成,如何处理XMPP协议,以及如何存储和检索聊天记录。源码中的注释也是学习的好资料,可能包含实现细节、设计决策以及潜在的优化点。 在...
总之,深入研究"openfire的webchat源码"不仅可以帮助开发者掌握即时通讯系统的设计和实现,还可以提升他们在Java Web开发、前端技术以及版本控制等多个方面的技能。这对于个人职业发展或是参与类似项目都是非常有益...
对于计算机科学的学习者,尤其是那些进行毕业设计或论文研究的人,Openfire源码提供了一个了解即时通讯系统实现的实践平台。通过分析和学习源码,可以深入了解XMPP协议的实现细节,提高对网络通信、服务器开发和...
在实际应用中,开发者可以深入研究源码,了解Openfire与Red5的集成方式,以及SparkWeb如何处理音视频交互。这有助于定制自己的即时通讯解决方案,例如添加新的功能,优化性能,或者改进用户体验。同时,对于学习Flex...
本资源包含JAVA源码、openfire服务器和spark客户端,为开发者提供了一整套构建即时通讯系统的解决方案。 首先,我们要了解JAVA源码在即时通讯中的作用。Java作为跨平台的编程语言,广泛应用于服务器端开发,尤其...
通过深入研究Openfire 3.9.3的源码,开发者不仅可以了解IM服务器的实现细节,还能掌握到Java编程、网络通信、数据库操作和系统安全等多个领域的知识,对于提升个人技能和解决实际问题有着极大的帮助。
《Openfire防丢包插件及其源码解析》 Openfire是一款开源的即时通讯服务器,以其高效、稳定和可扩展性赢得了广泛的应用。在实时通信中,丢包问题常常是影响用户体验的重要因素,为此,开发者们设计了一款专门针对...
Openfire是一款开源、基于XMPP协议的实时协作服务器,它提供了强大的聊天、会议以及...通过深入研究这个源代码,开发者不仅可以学习到Openfire插件开发的技巧,还能了解到如何将实时通信技术应用于物联网设备的控制。