openfire開發文檔
版本:Openfire3.5.

摘自:IM即時通訊研究

    目  

一、初始工作···············

1 、安裝 jdk1.5

2 、安裝 eclipse,myeclipse

3 、安裝 oracle10gXE

4 、安裝 openfire3.5.1 源代碼

二、環境配置···············

1 、配置 java 環境

2 、配置 openfire 運行環境

三、代碼研究···············


第一章:初始工作

1.1 安裝 jdk1.5

方法1:放在F盤的安裝程序的java開發工具文件夾里

    方法2:可從www.sun.com.cn下載jdk1.5.

1.2 安裝 eclipse3.3,myeclipse6.0

     放在F盤的安裝程序的java開發工具文件夾里

1.3 安裝 oracle10gXE

     放在F盤的安裝程序的java開發工具文件夾里

1.4 安裝 openfire3.5.1 源代碼

        源代碼的下載

方法1:放在F盤的openfire文件夾里

方法2:可從openfire的官方網站下載,網址在IE的收藏夾里

②源代碼的安裝

將下載好的 openfire 源代碼解壓出來,復制到 eclipse workspace 里, 打開eclipse,點新建java工程,在Contents里選擇第二個,即Create project from existing source, Directory選項里點右邊的Browse按鈕,選擇eclipseworkspace里的openfire文件夾(這個文件夾的名字應該叫:openfire_src),點確定。再填入Project name,工程名字一定要和eclipseworkspace里的openfire源代碼的文件夾名字相同,如下圖所示:

點擊完成,即成功導入openfire源代碼到eclipse中。如下圖所示:

右擊工程,點屬性->Java Build Path ->Libraries加入所對應的測試jar包,叫test什么什么的,放在E盤里。點擊完成,即可將錯誤消除。

第二章:環境配置

2.1 、配置 java 環境

    我的電腦點右鍵,選擇“屬性”。

選擇“高級”標簽。

進入環境變量設置:

分別設置如下三個環境變量:
PATH=C:"jdk1.6.0"bin
CLASSPATH=.;%JAVA_HOME%"lib"tools.jar;%JAVA_HOME%"lib"dt.jar(注意,CLASSPATH最前面是有個“.”的,表示當前目錄)
JAVA_HOME=C:"jdk1.6.0

設置完成之后,我們來測試一下。開始-》運行,輸入“CMD”,回車。

在打開的DOS命令窗口中輸入“java -version”,回車。

如果能像上圖那樣顯示JDK的版本,說明“PATH”變量設置沒有問題,如果有問題,檢查PATH變量設置,輸入“echo %PATH%”。

看其中是否存在“C:"jdk1.6.0"bin”。如果不存在則返回到環境變量設置中檢查。

接下來我們編寫一個簡單的Java程序測試CLASSPATH是否設置正確。

打開記事本,輸入下面的內容,保存至C:"java目錄下,文件名為HelloWorld.java。(注意大小寫)

class HelloWorld{
public static void main(String[] arg){
System.out.println("HelloWorld");
}
}

在打開的DOS命令窗口,進入C:"java,輸入“java HelloWorld.java”,回車。

這時在C:"java目錄下多了一個“HelloWorld.class”的文件。

在打開DOS命令窗口,輸入“java HelloWorld”,回車。

如果程序沒錯,那么將輸出“HelloWorld”。

恭喜,你的Java環境配置成功了。

2.2 、配置 openfire 運行環境

     點擊運行按鈕旁邊的小的黑色三角,點擊Open Run Dialog…

出現如下窗口,雙擊Java Application,Name框里的名字改成:openfire_src3.5.1,點擊Main class右邊的Search按鈕,

 

 

出現如下窗口:

在第一個文本框里輸入server,在第二個框里選擇ServerStarter-org.jivesoftware.openfire.starter,點OK

 

點擊eclipse菜單Window->Show View->Ant,如圖:

 

ant窗口里右擊選擇Add Buildfiles…,如下圖所示:

 

出現如下窗口:選擇:openfire_src->build->build.xml,點擊OK按鈕。

 

雙擊在ant窗口里生成的菜單,即開始部署項目。

 

察看console里顯示的信息:如果顯示BUILD SUCCESSFUL就表示項目部署成功。如圖:

  第三章:代碼研究


Openfire socket 網絡連接包括:

1. 服務器和服務器之間的連接(監聽在端口 5269

2. 外部組件和服務器之間的連接(監聽在端口 5275

3. 多元 (complex) 連接(監聽在端口 5269

4.客戶端和服務器的連接(監聽在端口5222)

5.和客戶端通過TLS/SSL3.0和服務器的連接。(監聽在端口5223)

這些連接都是通過ConnectionManager接口實現管理的,程序中對ConnectionManager接口的實現類是 ConnectionManagerImpl,它是作為一個模塊(Module)類加載到服務器中的。


下面分析的是客戶端和服務器的連接。 

ConnectionManagerImpl 中是通過調用 startClientListeners 方法來初始化和開始端口監聽的。

Mina框架 

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 模塊進行處理。

----------------------------------------------------------------------------------------------------------------------------------------------------

 結點類包

       起點    org.jivesoftware.openfire.starter.ServerStarter

       服務器  org.jivesoftware.openfire.XMPPServer

       用戶驗證包 里面有AuthProvier接口、幾個實現類。。。

               org.jivesoftware.openfire.auth

       用戶   org.jivesoftware.openfire.user

       組     org.jivesoftware.openfire.group

       好友列表org.jivesoftware.openfire.roster

      開發插件會用到的接口和包

          org.jivesoftware.openfire.container.Plugins

          org.xmpp.component.Component

          org.jivesoftware.openfire.event
          org.jivesoftware.openfire.handler

      攔截器

          org.jivesoftware.openfire.interceptor