Openfire源代码研究

Openfire socket 网络连接包括:

1.       服务器和服务器之间的连接(监听在端口 5269

2.       外部组件和服务器之间的连接(监听在端口 5275

3.       多元 (complex) 连接(监听在端口 5269

4.       客户端和服务器的连接(监听在端口 5222

5.       和客户端通过 TLS/SSL3.0 和服务器的连接。(监听在端口 5223

 

这些连接都是通过 ConnectionManager 接口实现管理的,程序中对 ConnectionManager 接口的实现类是 ConnectionManagerImpl ,它是作为一个模块( Module )类加载到服务器中的。

下面分析的是客户端和服务器的连接。

 

ConnectionManagerImpl 中是通过调用 startClientListeners 方法来初始化和开始端口监听的。

Openfire源代码研究_第1张图片 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 等待客户端的连接。

 

客户端连接的处理过程:

 

当有客户端进行连接时根据 Mina 框架的模式首先调用的是 sessionOpened 方法。

       sessionOpened 首先为此新连接构造了一个 parser XMLLightWeightParser ),这个 parser 是专门给 XMPPDecoder (是 XMPPCodecFactory 的解码器类) 使用的,再创建一个 Openfire Connection 类实例 connection 和一个 StanzaHandler 的实例。最后将以上的 parser, connection StanzaHandler 的实例存放在 Mina session 中,以便以后使用。

 

       当有数据发送过来时, 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 进行处理。

 

       StanzaHander 的实例 hander 处理 xml 数据包的过程

       StanzaHander 首先判断 xml 数据包的类型, . 如果数据包以“ <stream:stream ”打头那么说明客户端刚刚连接,需要初始化通信(符合 XMPP 协议) Openfire 首先为此客户端建立一个与客户端 JID 相关的 ClientSession ,而后与客户端交互协商例如是否使用 SSL ,是否使用压缩等问题。当协商完成之后进入正常通信阶段,则可以将 xml 数据包交给这个用户的 ClientSession 进行派送( deliever ),经过派送数据包可以发送给 PacketRouteImpl 模块进行处理。

    PacketRouteImpl 中包将进一步被细化处理,以后将继续分析。

你可能感兴趣的:(Openfire源代码研究)