openfire開源IM服務器知識分享+社交app實戰

1、      概述

  1. Openfire最主要的功能是實現XMPP服務器,簡單來講,openfire爲咱們提供一個固定的地址,咱們只須要向openfire服務器發送標準的XMPP信息(即XML文件流),那麼openfire服務器應當給予咱們迴應,這裏的openfire服務器也能夠看作一個容器,咱們在聊天時,須要在這個服務器上註冊一個會話,在會話存在的時間,咱們能夠實現即時聊天的一些經常使用功能,好比創建本身的組,添加好友,聊天,以及傳送文件等等,同時,openfire服務器也須要實現本身的管理界面,這樣openfire服務器也扮演一個web容器的角色
  2. Openfire是開源的實時協做服務器(RTC),它是基於公開協議XMPP(也成爲Jabber)消息的。
  3. 使用它輕易的構建高效率的即時通訊服務器。
  4. Openfire的核心功能能夠歸納爲:鏈接管理、消息解析、消息路由、消息發送。
  5. Openfire具備跨平臺的能力,Openfire與客戶端採用的是C/S架構,一個服務器要負責爲鏈接在其上的客戶端提供服務。
  6. Openfire客戶端有spark, pidgin, Miranda IM, iChat等,用戶若是本身開發客戶端,能夠採用遵循GPL的開源Client端API--Smack。
  7. Openfire服務器端支持插件開發,若是開發者須要添加新的服務,能夠開發出本身的插件後,安裝至服務器,就能夠提供服務,如查找聯繫人服務就是以插件的形式提供的。

2、      體系架構



 

3、      功能模塊



 

  1. Pubsub:Publish/Subscribe,這使得xmpp實體可以在pubsub服務上建立nodes(topics),而且發佈信息。一個事件通知將廣播到全部訂閱了這個節點的實體上。
  2. Pep:(Personal Eventing Protocol)使用XMPP publish-subscribe協議廣播狀態改變事件、及時消息和出席賬戶到其餘用戶。
  3. Stun:爲p2p會話提供地址發現服務,如:媒體傳輸和UDP包的收發。
  4. Router:內部的路由,把相應的包路由給相應的處理器。
  5. Muc:(Multi-User Chat)用戶能夠交換文本信息在room或者channel上下文中,版主或者管理員有權踢除用戶和禁止用戶。
  6. 全部Module都須要實現Module接口,該接口中定義了模塊生命週期中須要調用的方法



 

 

 

4、      數據模型

  1. 數據庫表設計:詳見:

http://www.igniterealtime.org/builds/openfire/docs/latest/documentation/database-guide.html#ofGroup#ofGrouphtml

  1. Openfire的數據庫處理採用直接調用JDBC 的方式。核心類爲org.jivesoftware.database.DbConnectionManager。數據庫的處理與業務處理耦合,沒有劃分出專門的業務邏輯層。
  2. 3.      ConnectionProvider此類爲數據庫提供者接口,如需鏈接mysql、hsqldb等數據庫,需首先實現些接口,一般直接調用XXManager中的實例方法,XXManager中又調用的是對應的接口XXProvider的方法,實際操做在該接口的實現類中實現。實現類是動態綁定的(默認的實現類一般命名規則爲DefaultXXProvider),在運行時根據ofproperty表中對應配置項值選
  3. org.jivesoftware.database.DbConnectionManager,鏈接管理類
  4. org.jivesoftware.util.JiveGlobals,一般用於操做ofproperty表中記錄
  5. 1.         XMPP協議

5、      通訊機制

1)      XMPP(Extensible Messageing and Presence Protocol:可擴展消息處理現場協議)是目前主流的四種IM(IM:instant messaging,即時消息)協議之一,其餘三種分別爲:即時信息和空間協議(IMPP)、空間和即時信息協議(PRIM)、針對即時通信和空間平衡擴充的進程開始協議SIP(SIMPLE)。node

2)      XMPP的前身是Jabber,一個開源形式組織產生的網絡即時通訊協議。mysql

3)      核心的XML流傳輸協議 ,基於XML FreeEIM流傳輸的即時通信擴展應用,XMPP的擴展協議Jingle使得其支持語音和視頻web

4)      XMPP協議在PC和Android分別有對應的協議實現smack和asmack,不用咱們寫XML協議解析sql

5)      XMPP的基本網絡結構:Client、Server、Gateway,通訊可以在這三者的任意兩個之間雙向發生。服務器同時承擔了客戶端信息記錄,鏈接管理和信息的路由功能。網關承擔着與異構即時通訊系統的互聯互通,異構系統能夠包括SMS(短信),MSN,ICQ等。數據庫

6)      客戶端利用xmpp(基於TCP/IP)訪問server,傳輸的是XML,工做原理是:apache

a)    節點鏈接到服務器;編程

b)    服務器利用本地目錄系統中的證書對其認證;緩存

c)    節點指定目標地址,讓服務器告知目標狀態;安全

d)    服務器查找、鏈接並進行相互認證;

e)    節點之間進行交互

7)      XMPP協議的傳輸是經過XML文件來傳輸的,而且不是相似於QQ的點對點通信,而是客戶端到服務器再到客戶端的方式來實現,以上過程的一個簡單的XMPP通信流程能夠以下:

a)    首先,由客戶端鏈接到服務器,客戶端經過IO流發送一段XML文件,在文件中包含了自身的用戶名和密碼

b)    服務器端接收到客戶端的XML文件,從中獲取用戶名和密碼進行驗證,若是驗證成功,服務器會發送一個XML文件給客戶端代表已經登陸成功

c)    登錄成功後,客戶端能夠經過發送一個獲取好友名單的XML文件,服務器會將當前用戶的好友以XML文件傳到客戶端

d)    客戶端選擇一個好友,向其發送信息(實際上是向服務器發送,服務器收到後會轉發給對應的好友),好友收到

8)      XMPP地址模式:JID=[ node」@」 ] domain [ 「/」 resource ](如:cyber@cyberobject.com/res),domain:服務器域名,node: 用戶名,resource:屬於用戶的位置或設備。一個用戶能夠同時以多種資源與同一個XMPP服務器鏈接

9)      XMPP xml消息格式定義:

<stram>

   <presence>  //此元素肯定用戶的狀態

      <status/>

   </prensence>

   <message>  //用於兩個用戶之間發送信息

        <body/>

    </message>

    <iq> //信息/請求,是一個請求-響應機制,管理xmpp服務器上兩個用戶的轉換,容許他們經過相應的xml格式的查詢和響應

                     <bind/>

    </iq>

</stream>

10)    XMPP的安全機制:XMPP採用SASL做爲身份認證協議,XMPP採用TLS的「START-TLS」擴展來爲通訊雙方提供加密性和數據完整性服務

11)    XMPP體系架構:XMPP server:其內核是一個XMPP路由器,完成基本組件間的數據包交換和路由。功能:1.會話管理器:負責客戶端會話認證,在線狀態,用戶聯繫表等;2.數據存儲器(XDB):鏈接數據庫系統,保持用戶信息、通訊日誌等;3.鏈接器管理器:管理與客戶端之間的鏈接;4.服務器鏈接器:管理xmpp服務器之間的鏈接;5.傳輸器:創建xmpp服務器與非xmpp服務器通訊

12)     

  1. 2.      Apache MINA框架

1)      XMPP協議是基於TCP/IP協議進行傳輸的,在openfire中,應用了apache的mina框架做爲NIO框架,簡單的來講,openfire服務器用mina框架創建一個簡單的服務器,能夠接收和發送基本的IO流,而後在此基礎上把接收到的IO流解析爲XML文件,而後在根據XMPP協議對XML文件進行操做

2)      是一個網絡應用程序框架,用來幫助用戶簡單地開發高性能和高可靠性的網絡應用程序。它提供了一個經過Java NIO在不一樣的傳輸例如TCP/IP和UDP/IP上抽象的事件驅動的異步API,對通訊功能進行擴展

3)      爲不一樣的傳輸類型(TCP/UDP)提供了統一的API

4)      過濾器做爲一個擴展特性,相似Servlet過濾器

5)      低級(字節緩存)和高級(用戶定義的消息對象和編碼)的API

6)      高度定製化線程模型(單線程/線程池)

7)      超載保護和傳輸流量控制

8)      Openfire的ConnectionHandler類繼承了MINA的IoHandlerAdaper,他主要負責鏈接的建立、銷燬,以及接收到XML數據包的投遞。ConnectionHandler有三個子類,其中ClientConnectionHandler負責客戶端與服務器端的鏈接,ComponentConnectionHandler負責組件與服務器端的鏈接,類圖以下:



 

  1. 3.      Openfiresocket網絡鏈接

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

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

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

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

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

6)      鏈接都是經過ConnectionManager接口實現管理的,程序中對ConnectionManager接口的實現類是ConnectionManagerImpl,它是做爲一個模塊(Module)類加載到服務器中的

6、      開發配置

  1. 環境配置:

1)      http://blog.csdn.net/kingsonl/article/details/7730225

2)      http://blog.csdn.net/nomousewch/article/details/6534555

  1. 2.         Openfire源碼目錄結構

1)      build目錄:build目錄下收錄的是生成安裝文件(例如:rpm)所要的一些文件,例如JRE等

2)      resources目錄:resources目錄下收錄的是一些爲實現國際化(i18n)和本地化的一些編碼文件(例如:英文,中文,法文,德文等)

3)      documentation目錄:documentation目錄下收錄的是一些關於Openfire安裝和配置的信息,但最終要的是這裏有Openfire開發的Javadoc

4)      src目錄:顧名思義這個src文件夾就是咱們想要的Openfire源代碼了,這下面又有許多文件夾,咱們只要Java文件夾就好,這裏面實現的Openfire的核心功能,經過它就能夠調試Openfire了

  1. 3.         命名規則

Openfire中常見的類名後綴命名包括Starter、Plugin、Listener、Dispatcher、Handler、Manager、Provider,一般狀況下,這些命名類包括以下意義:

1)      XXStarter系統啓動類

2)      XXListener業務的最終處理類

3)      XXDispatcher調度類,其中有不少關鍵方法,如addListener(),以組合的方式,爲類內定義的靜態Set<XXListener>實例添加XXListener對象。以便調用dispatchEvent(String property, EventType eventType, Map<String, Object> params)方法遍歷處理Set集中的XXListener對象(經過調用XXListener對象的各實際方法完成實際業務)

4)      XXPlugin實現Plugin接口的插件類,需實現initializePlugin(PluginManager manager, File pluginDirectory)方法和destroyPlugin()方法。在其初始化方法中調用Dispatcher實現類的addListener()方法如PropertyEventDispatcher.addListener(this)

5)      XXProvider實現面向接口編程方式的接口類,經過反射機制建立具體實現類的對象,反射類名配置在ofproperty表對應的記錄propvalue屬性中。若沒有相關配置,則調用默認實現類,默認實現類類名命名規則爲DefaultXXProvider

6)      XXHandler實際處理類,以ConnectionHandler爲例,在org.jivesoftware.openfire.spi. ConnectionManagerImpl類的startClientSSLListeners(String localIPAddress)方法中,有這樣一段代碼:sslSocketAcceptor.bind(new InetSocketAddress(bindInterface, port), new ClientConnectionHandler(serverName));其中bind方法的第二個參數是新建立的一個ClientConnectionHandler的實例,而它就是ConnectionHandler的一個子類

  1. 4.         系統配置

Openfire的系統配置項採用文件結合數據庫表的方式配置,也有部分默認配置項經過Java硬編碼方式配置(如org.jivesoftware.openfire. ConnectionManager接口類中定義的DEFAULT_PORT、DEFAULT_SSL_PORT、DEFAULT_COMPONENT_PORT等),Openfire中比較重要的配置位置包括:

1)      src/conf目錄下的openfire.xml配置文件。該配置文件爲系統核心配置文件。在第一次啓動Openfire並經過管理控制檯完成安裝配置後會往該配置文件中填入相應的配置信息

2)      plugin.xml配置文件。該配置文件爲各插件包下的核心配置文件,由它肯定插件核心處理類和相應頁面插件的展示等。配置項及含義詳見官方插件開發說明部分

3)      web.xml和web-custom.xml配置文件。用於配置servlet和用戶自定義servlet(插件頁面用,放在插件對應目錄下)

4)      ofproperty中的各條記錄,該表中包括兩個字段name和propvalue,分別表明配置項名和配置項值

  1. 5.         Openfire啓動過程

系統啓動時調用org.jivesoftware.openfire.starter.ServerStarter類中的start()方法,加載org.jivesoftware.openfire.XMPPServer類,並調用這個類的start(),Start()方法中首先調用verifyDataSource()方法驗證並確保數據庫能夠訪問,而後會調用               loadModules();initModules();startModules();方法來對Module接口的實現類的各子類進行操做,依次完成模塊的加載、初始化和啓動操做。loadModules()方法中會調用loadModule(String module)方法經過反射加載各模塊類,參數字符串module爲對應的模塊核心處理類的類名

  1. 6.         消息處理流程

在Openfire服務器對XMPP的實現中,消息被封裝爲Packet對象,所以Openfire服務器的核心代碼是對客戶端Packet對象的監聽和處理流程

Packet處理流程:



 

1)      首先,Openfire服務器須要啓動一個基於TCP/IP的監聽服務,用以接收客戶端傳過來的XML流文件。這個過程在XMPPServer類的start()方法中進行,這個監聽服務是以loadModule(ConnectionManagerImpl.class.getName())來加載,調用ConnectionManagerImpl類的createClientListeners()方法

2)      其中的socketAcceptor是在buildSocektAcceptor()方法中定義的,它是做爲一個服務端的接收器,是mina框架爲咱們封裝好的一個socketserver,在上面這個方法中,咱們爲socketAcceptor添加了一個過濾器,XMPPCodeFactory,這個類將過濾xmpp相關請求,加以處理,咱們再看同一個類的另一個方法startClientListener()

3)      其中的socketAcceptor.bind()方法啓動了監聽服務器,來監聽全部發送到服務器5222端口的數據,並用ClientConnetionHandler類來處理,ClinetConnectionHandler繼承於ConnectionHandler類,後者實現了mina的IoHandlerAdaptor接口,其中的messageReceived()方法是關鍵

4)      能夠看到收到的信息交由StanzaHandler的process方法中進行XML解析並封裝爲packet對象,而後再進行下一步的處理,至此,從客戶端到服務器端的packet傳遞結束,以下圖所示:



 

 

 

  1. 7.         Spark 登陸過程-安全認證

1)      Spark登陸過程消息截圖:



 

2)      Spark登陸過程當中的XMPP消息含義:



 

 

  1. 8.         WEB服務器

1)      Openfire採用內置的jetty做web服務器,在啓動AdminConsolePlugin插件時調用startup()方法啓動jetty服務器,9090爲其明文端口,9091爲其加密端口

2)      Openfire沒有采用如今很流行的技術架構(SSH),只使用JSP+JavaBean,可是它有本身的系統設計,就連日誌都是本身作的,沒有使用咱們熟悉的log4j

3)      現有的Openfire管理控制檯可採用插件方式進行擴展,頁面採用Jsp方式實現,頁面直接調用業務處理邏輯類(一般命名爲XXManager)的實例方法,一般經過request對象封裝的方式傳遞頁面展示斷定變量,常出現本頁跳轉。每一個插件可定義本身的Servlet類和web.xml及web-custom.xml配置文件

4)      頁面展示採用裝飾框架方式,decorator頁面有兩個,即src/web/decorators目錄下的兩個頁面main.jsp和setup.jsp。採用自定義的admin標籤實現,標籤庫admin.tld放置在src/web/WEB-INF目錄下,標籤解析類放置在org.jivesoftware.admin包下,有SidebarTag、SubnavTag、SubSidebarTag、TabsTag四個解析類。在調用loadPlugin()方法進行插件加載時,解析插件的plugin.xml配置文件,將獲取的相關信息封裝在AdminConsole類的generatedModel對象中,後期經過插件解析類提取該對象中的數據並配合sitemesh裝飾器進行頁面展示。

社交app實戰以下圖:

 

溝通聯繫qq2729404527  微信:code588  

相關文章
相關標籤/搜索