XMPP
ExtensibleMessaging and Presence Protocol,簡單的來講,它就是一個發送接收處理消息的協議,但是這個協議發送的消息,既不是二進制的東東也不是字符串,而是XML。正是因為使用了XML作為消息傳遞的中介,Extensible 才談的上,不是么?
IM
InstantMessenger,及時通信軟件,就是大家使用的QQ、MSN Messenger和Gtalk等等。其中Gtalk 就是基於XMPP 協議的一個實現,其他的則不是。當前IM 幾乎作為每個上網者必然使用的工具,在國外的大型企業中有一些企業級的IM應用,但是其商業價值還沒完全發揮出來。設想既然XMPP 協議是一個公開的協議,那么每個企業都可以利用它來開發適合本身企業工作,提高自身生產效率的IM;甚至,你還可以在網絡游戲中集成這種通信軟件,不但讓你可以邊游戲邊聊天,也可以開發出適合游戲本身的IM 應用,比如說一些游戲關鍵場景提醒功能,團隊語音交流等等都可以基於IM來實現。
Spark Smack 和 Openfire
開源界總是有許多有趣的東東,這三個合起來就是一個完整的XMPP IM 實現。包括服務器端——Openfire,客戶端——Spark,XMPP 傳輸協議的實現——Smack(記住,XMPP是一個協議,協議是需要實現的,Smack起到的就是這樣的一個作用)。三者都是基於Java 語言的實現。
Spark 提供了客戶端一個基本的實現,並提出了一個很好的插件架構,這對於開發者來說不能不說是一個福音。我強烈建議基於插件方式來實現你新增加的功能,而不是去改它的源代碼,這樣有利於你項目架構,把原始項目的影響降到最低。
Openfire 是基於XMPP 協議的IM 的服務器端的一個實現,雖然當兩個用戶連接后,可以通過點對點的方式來發送消息,但是用戶還是需要連接到服務器來獲取一些連接信息和通信信息的,所以服務器端是必須要實現的。Openfire 也提供了一些基本功能,但真的很基本的!慶幸的是,它也提供插件的擴展,像Spark 一樣,同樣強烈建議使用插件擴展的方式來增加新的功能,而不是修改人家的源代碼。
Smack 是一個XMPP 協議的Java 實現,提供一套可擴展的API,不過有些時候,你還是不得不使用自己定制發送的XML 文件內容的方式來實現自己的功能
下圖展示了三者之間的關系:
從圖上可以了解到,client 端和server端都可以通過插件的方式來進行擴展,smack是二者傳遞數據的媒介。
Apache MINA
Openfire的通信處理基於Apache MINA框架實現。Apache MINA是一個網絡應用程序框架,用來幫助用戶簡單地開發高性能和高可靠性的網絡應用程序。它提供了一個通過Java NIO在不同的傳輸例如TCP/IP和UDP/IP上抽象的事件驅動的異步API。
Apache MINA 也稱為:
● NIO 框架庫
●客戶端服務器框架庫
●一個網絡套接字庫
MINA雖然簡單但是仍然提供了全功能的網絡應用程序框架:
●為不同的傳輸類型提供了統一的API:
○通過Java NIO提供TCP/IP 和 UDP/IP支持
○通過RXTX提供串口通訊(RS232)
○ In-VM管道通訊
○你能實現你自己的API!
●過濾器作為一個擴展特性; 類似Servlet過濾器
●低級和高級的API:
○低級: 使用字節緩存(ByteBuffers)
○高級: 使用用戶定義的消息對象(objects)和編碼(codecs)
●高度定制化線程模型:
○單線程
○一個線程池
○一個以上的線程池(也就是SEDA)
●使用Java 5 SSL引擎提供沙盒(Out-of-the-box) SSL • TLS • StartTLS支持
●超載保護和傳輸流量控制
●利用模擬對象進行單元測試
● JMX管理能力
●通過StreamIoHandler提供基於流的I/O支持
●和知名的容器(例如PicoContainer、Spring)集成
●從Netty平滑的遷移到MINA, Netty是MINA的前輩。
命名規則
Openfire中常見的類名后綴命名包括Starter、Plugin、Listener、Dispatcher、Handler、Manager、Provider,通常情況下,這些命名類包括如下意義:
XXStarter
系統啟動類,如org.jivesoftware.openfire.starter.ServerStarter,調用其start()方法可啟動系統應用。
XXListener
業務的最終處理類。
XXDispatcher
調度類,其中有很多關鍵方法,如addListener(),以組合的方式,為類內定義的靜態Set<XXListener>實例添加XXListener對象。以便調用dispatchEvent(Stringproperty, EventType eventType, Map<String, Object> params)方法遍歷處理Set集中的XXListener對象(通過調用XXListener對象的各實際方法完成實際業務)。
XXPlugin
實現Plugin接口的插件類,需實現initializePlugin(PluginManagermanager, File pluginDirectory)方法和destroyPlugin()方法。在其初始化方法中調用Dispatcher實現類的addListener()方法如PropertyEventDispatcher.addListener(this)。
XXProvider
實現面向接口編程方式的接口類,通過反射機制創建具體實現類的對象,反射類名配置在ofproperty表對應的記錄propvalue屬性中。若沒有相關配置,則調用默認實現類,默認實現類類名命名規則為DefaultXXProvider。
XXHandler
實際處理類,以ConnectionHandler為例,在org.jivesoftware.openfire.spi.ConnectionManagerImpl類的startClientSSLListeners(StringlocalIPAddress)方法中,有這樣一段代碼:
sslSocketAcceptor.bind(newInetSocketAddress(bindInterface, port), newClientConnectionHandler(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為對應的模塊核心處理類的類名,如AdHocCommandHandler。現以AdHocCommandHandler為例對接下來的處理流程進行說明。通過loadModule創建AdHocCommandHandler類實例時調用其構造函數,在構造函數中初始化了其私有AdHocCommandManager對象。在initModules()時調用AdHocCommandHandler實例的initialize(XMPPServer server)方法對其私有屬性對象進行初始化。然后調用start()方法,調用addDefaultCommands方法添加命令並啟動命令(通過調用startCommand(AdHocCommand command)方法實現)。
網絡處理
消息監聽服務
SSL等監聽服務的調度在ConnectionManagerImpl類中實現。ConnectionManagerImpl.createClientSSLListeners()方法啟動SSL監聽
消息封裝
信息處理采用XML節的方式傳遞信息,消息封裝通常采用IQ、Message、Presence。
Openfire消息包接受處理流程
數據庫處理
Openfire的數據庫處理采用直接調用JDBC 的方式。核心類為org.jivesoftware.database.DbConnectionManager。數據庫的處理與業務處理耦合,沒有划分出專門的業務邏輯層。
ConnectionProvider
此類為數據庫提供者接口,如需連接mysql、hsqldb等數據庫,需首先實現些接口,
處理方式
通常直接調用XXManager中的實例方法,XXManager中又調用的是對應的接口XXProvider的方法,實際操作在該接口的實現類中實現。實現類是動態綁定的(默認的實現類通常命名規則為DefaultXXProvider),在運行時根據ofproperty表中對應配置項值選擇。下面以添加用戶組為例進行說明。
首先獲得GroupManager的一個實例,在調用其構造函數時調用initProvider()方法,在該方法中獲取數據庫中配置項的值,若不為空則根據該值通過反射機制獲取GroupProvider接口的實現類實例對象;若為空則以DefaultGroupProvider作為GroupProvider接口的實現類並創建實例對象,然后調用GroupProvider.createGroup(String name)方法完成業務操作。
常用類
org.jivesoftware.database.DbConnectionManager
連接管理類
org.jivesoftware.util.JiveGlobals
通常用於操作ofproperty表中記錄
openfire數據結構
數據庫表
以下是一個說明每個表格的Openfire數據庫架構。黃色行表示主鍵。
· ofGroup
· ofID
· ofUser
· ofRoster
· ofVCard
ofGroup (用戶組的數據) |
|||
列名 |
類型 |
長度 |
描述 |
groupName |
VARCHAR |
50 |
組名稱(主鍵) |
description |
VARCHAR |
255 |
組描述 |
ofGroupProp (名稱值協會為一組) |
|||
列名 |
類型 |
長度 |
描述 |
groupName |
VARCHAR |
50 |
組名稱(主鍵) |
name |
VARCHAR |
100 |
組屬性名稱(主鍵) |
propValue |
VARCHAR |
4000 |
組屬性值 |
ofGroupUser (組成員) |
|||
列名 |
類型 |
長度 |
描述 |
groupName |
VARCHAR |
50 |
組名稱(主鍵) |
username |
VARCHAR |
100 |
用戶名(主鍵) |
administrator |
NUMBER |
n/a |
是否為管理員(布爾)(主鍵) |
ofID (用於唯一ID序列生成) |
|||
列名 |
類型 |
長度 |
描述 |
idType |
NUMBER |
n/a |
證件類型(例如,組,用戶名冊)(主鍵) |
id |
NUMBER |
n/a |
下一個可用塊編號的(用於數據庫獨立編號) |
ofOffline (離線郵件存儲) |
|||
列名 |
類型 |
長度 |
更改 |
username |
VARCHAR |
32 |
用戶名(主鍵) |
messageID |
NUMBER |
n/a |
存儲信息的編號(主鍵) |
creationDate |
VARCHAR |
15 |
日期信息存儲 |
messageSize |
NUMBER |
n/a |
郵件的大小以字節為單位 |
stanza |
TEXT |
n/a |
消息文本 |
ofPresence (離線的存在) |
|||
列名 |
類型 |
長度 |
更改 |
username |
VARCHAR |
64 |
用戶名(主鍵) |
offlinePresence |
TEXT |
n/a |
存在的信息設置為用戶注銷 |
offlineDate |
CHAR |
15 |
信息存儲日期 |
ofPrivate (私人數據存儲) |
|||
列名 |
類型 |
長度 |
描述 |
username |
VARCHAR |
32 |
用戶名(主鍵) |
name |
VARCHAR |
100 |
姓名私營項(主鍵) |
namespace |
VARCHAR |
200 |
名字空間私營項(主鍵) |
privateData |
TEXT |
n/a |
價值的私人數據 |
ofUser (用戶數據) |
|||
列名 |
類型 |
長度 |
描述 |
username |
VARCHAR |
32 |
用戶名(主鍵) |
plainPassword |
VARCHAR |
32 |
純文字密碼數據 |
encryptedPassword |
VARCHAR |
255 |
加密的密碼數據(默認) |
name |
VARCHAR |
100 |
名字 |
|
VARCHAR |
100 |
電郵地址 |
creationDate |
VARCHAR |
15 |
創建日期 |
modificationDate |
VARCHAR |
15 |
最后更新日期 |
ofUserProp (名稱值協會針對用戶) |
|||
列名 |
類型 |
長度 |
描述 |
username |
VARCHAR |
32 |
用戶名(主鍵) |
name |
VARCHAR |
100 |
用戶屬性名稱(主鍵) |
propValue |
VARCHAR |
4000 |
用戶屬性值 |
ofUserFlag (用戶類型標識(如殘疾人)) |
|||
列名 |
類型 |
長度 |
描述 |
username |
VARCHAR |
64 |
用戶名(主鍵) |
name |
VARCHAR |
100 |
用戶屬性名稱(主鍵) |
startTime |
CHAR |
15 |
國旗的時候,開始被有效(無效的'現在' ) |
endTime |
CHAR |
15 |
當時國旗是結束有效(無效的'永遠' ) |
ofRoster (好友列表) |
|||
列名 |
類型 |
長度 |
描述 |
rosterID |
NUMBER |
n/a |
編號名冊(主鍵) |
username |
VARCHAR |
32 |
用戶名 |
jid |
TEXT |
n/a |
地址名冊入境 |
sub |
NUMBER |
n/a |
認購地位入境 |
ask |
NUMBER |
n/a |
賣出地位入境 |
recv |
NUMBER |
n/a |
檢舉表明進入名冊收到請求 |
nick |
VARCHAR |
255 |
昵稱分配給這個名冊入境 |
ofRosterGroups (組的好友名單中的條目) |
|||
列名 |
類型 |
長度 |
描述 |
rosterID |
NUMBER |
n/a |
名冊編號(主鍵) |
rank |
NUMBER |
n/a |
立場項(主鍵) |
groupName |
VARCHAR |
255 |
用戶定義的名稱,這個名冊組 |
ofPrivacyList (用戶隱私清單) |
|||
列名 |
類型 |
長度 |
描述 |
username |
VARCHAR |
32 |
用戶名(主鍵) |
name |
VARCHAR |
100 |
姓名保密清單(主鍵) |
isDefault |
NUMBER |
n/a |
檢舉指出,如果這是默認隱私的用戶名單 |
list |
TEXT |
n/a |
XML表示的隱私清單 |
ofVCard (電子名片的聯系信息) |
|||
列名 |
類型 |
長度 |
描述 |
username |
VARCHAR |
32 |
用戶名(主鍵) |
vcard |
TEXT |
n/a |
價值的vCard入境 |
ofVersion (包含產品版本信息) |
|||
列名 |
類型 |
長度 |
描述 |
name |
VARCHAR |
50 |
名稱的項目,版本信息正在跟蹤的(主鍵) |
version |
INTEGER |
n/a |
版本號 |
ofProperty (服務器屬性) |
|||
列名 |
類型 |
長度 |
描述 |
name |
VARCHAR |
100 |
屬性名稱(主鍵) |
propValue |
TEXT |
n/a |
進入值 |
ofExtComponentConf (外部元件配置) |
|||
列名 |
類型 |
長度 |
描述 |
subdomain |
VARCHAR |
255 |
子的外部元件(主鍵) |
secret |
VARCHAR |
255 |
共享密鑰的外部元件 |
permission |
VARCHAR |
10 |
許可,表明如果組件是可以連接到服務器 |
ofRemoteServerConf (遠程服務器配置) |
|||
列名 |
類型 |
長度 |
描述 |
xmppDomain |
VARCHAR |
255 |
域的外部元件(主鍵) |
remotePort |
NUMBER |
n/a |
港口的遠程服務器連接到 |
permission |
VARCHAR |
10 |
許可,表明如果遠程服務器可以連接到服務器 |
ofSecurityAuditLog (伐木安全事件) |
|||
列名 |
類型 |
長度 |
描述 |
msgID |
NUMBER |
n/a |
編號審計信息(主鍵) |
username |
VARCHAR |
64 |
使用者誰執行的行動 |
entryStamp |
NUMBER |
n/a |
時間戳當事件發生 |
summary |
VARCHAR |
255 |
總結了發生在事件 |
node |
VARCHAR |
255 |
節點事件發生 |
details |
TEXT |
n/a |
詳細的細節,所發生的 |
ofMucService (甲Groupchat服務) |
|||
列名 |
類型 |
長度 |
描述 |
serviceID |
NUMBER |
n/a |
編號的服務(收錄) |
subdomain |
VARCHAR |
255 |
子服務(主鍵) |
description |
VARCHAR |
255 |
服務說明 |
isHidden |
NUMBER |
n/a |
1 ,如果隱藏的管理界面名單, 0正常 |
ofMucServiceProp (名稱值協會的Groupchat服務) |
|||
列名 |
類型 |
長度 |
描述 |
serviceID |
NUMBER |
n/a |
編號的服務(主鍵) |
name |
VARCHAR |
100 |
屬性名稱(主鍵) |
propValue |
TEXT |
n/a |
屬性值 |
ofMucRoom ( Groupchat室內資料) |
|||
列名 |
類型 |
長度 |
描述 |
roomID |
NUMBER |
n/a |
編號的房間(主鍵) |
creationDate |
VARCHAR |
15 |
創建日期 |
modificationDate |
VARCHAR |
15 |
最后更新日期 |
name |
VARCHAR |
50 |
姓名房間用作公共編號 |
naturalName |
VARCHAR |
255 |
天然名稱室 |
description |
VARCHAR |
255 |
客房描述 |
canChangeSubject |
NUMBER |
n/a |
檢舉指出是否可以改變參與者的主題 |
maxUsers |
NUMBER |
n/a |
馬克斯一些房間居住者 |
canChangeSubject |
NUMBER |
n/a |
檢舉指出是否與會者可以改變的主題或不 |
publicRoom |
NUMBER |
n/a |
檢舉指示是否室將在目錄中列出或不 |
moderated |
NUMBER |
n/a |
檢舉指示是否室主持或不 |
membersOnly |
NUMBER |
n/a |
檢舉指出是否房間是會員制或不 |
canInvite |
NUMBER |
n/a |
檢舉指出是否占用可以邀請其他用戶 |
roomPassword |
VARCHAR |
50 |
密碼數據加入室 |
canDiscoverJID |
NUMBER |
n/a |
檢舉指出是否真正JID的居住者是公共或不 |
logEnabled |
NUMBER |
n/a |
檢舉指出是否房間談話記錄或不 |
subject |
VARCHAR |
100 |
最后為人所知的主題房間 |
rolesToBroadcast |
NUMBER |
n/a |
二元代表的作用,以廣播 |
useReservedNick |
NUMBER |
n/a |
檢舉指出是否用戶只能加入室使用其保留昵稱 |
canChangeNick |
NUMBER |
n/a |
檢舉指出是否可以改變其占用的空間昵稱 |
canRegister |
NUMBER |
n/a |
檢舉顯示用戶是否被允許登記室 |
ofMucRoomProp (名稱值協會的Groupchat房間) |
|||
列名 |
類型 |
長度 |
描述 |
roomID |
NUMBER |
n/a |
編號的房間(主鍵) |
name |
VARCHAR |
100 |
屬性名稱(主鍵) |
propValue |
VARCHAR |
4000 |
屬性值 |
ofMucAffiliation (歸屬的空間用戶) |
|||
列名 |
類型 |
長度 |
描述 |
roomID |
NUMBER |
n/a |
編號的房間(主鍵) |
jid |
TEXT |
n/a |
用戶JID (主鍵) |
affiliation |
NUMBER |
n/a |
一些代表所屬一級 |
ofMucMember (室成員資料) |
|||
列名 |
類型 |
長度 |
描述 |
roomID |
NUMBER |
n/a |
編號的房間(主鍵) |
jid |
TEXT |
n/a |
用戶JID (主鍵) |
nickname |
VARCHAR |
255 |
保留昵稱的會員 |
ofMucConversationLog (室會話日志) |
|||
列名 |
類型 |
長度 |
描述 |
roomID |
NUMBER |
n/a |
編號的空間 |
sender |
TEXT |
n/a |
JID的用戶發送郵件的房間 |
nickname |
VARCHAR |
255 |
昵稱使用時由用戶發出的信息 |
logTime |
VARCHAR |
15 |
日期的消息時,被送到房間 |
subject |
VARCHAR |
50 |
新的主題改變的信息 |
body |
TEXT |
n/a |
消息正文 |
ofPubsubNode (節點pubsub服務) |
|||
列名 |
類型 |
長度 |
描述 |
serviceID |
VARCHAR |
100 |
編號托管服務節點(主鍵) |
nodeID |
VARCHAR |
100 |
編號的節點(主鍵) |
leaf |
NUMBER |
n/a |
檢舉表明節點是否是葉或收集節點 |
creationDate |
VARCHAR |
15 |
創建日期 |
modificationDate |
VARCHAR |
15 |
最后更新日期 |
parent |
VARCHAR |
100 |
編號的父節點(如果有的話) |
deliverPayloads |
NUMBER |
n/a |
檢舉指出是否有效載荷中包含的通知 |
maxPayloadSize |
NUMBER |
n/a |
最大規模的有效載荷的字節 |
persistItems |
NUMBER |
n/a |
檢舉表明節點是否將持續出版項目 |
maxItems |
NUMBER |
n/a |
最大的項目數量將持續 |
notifyConfigChanges |
NUMBER |
n/a |
檢舉指出是否發送通知時,該節點的配置發生了變化 |
notifyDelete |
NUMBER |
n/a |
檢舉指出是否發送通知時,該節點將被刪除 |
notifyRetract |
NUMBER |
n/a |
檢舉指出是否發送通知時,發布的項目將被刪除 |
presenceBased |
NUMBER |
n/a |
檢舉指出是否發送通知只有用戶才 |
sendItemSubscribe |
NUMBER |
n/a |
檢舉指出是否向去年出版項目,以新用戶 |
publisherModel |
VARCHAR |
15 |
Publisher中使用的模式的節點 |
subscriptionEnabled |
NUMBER |
n/a |
檢舉指出是否允許訂閱 |
configSubscription |
NUMBER |
n/a |
檢舉指出是否新的訂戶必須設定為活躍 |
accessModel |
VARCHAR |
10 |
訪問模型所使用的節點 |
payloadType |
VARCHAR |
100 |
類型的有效載荷數據將提供在節點 |
bodyXSLT |
VARCHAR |
100 |
網址的一個XSLT轉換有效載荷的格式為一個郵件正文 |
dataformXSLT |
VARCHAR |
100 |
網址的一個XSLT轉化的有效載荷格式的數據形式結果 |
creator |
VARCHAR |
1024 |
JID的實體建立了節點 |
description |
VARCHAR |
255 |
說明節點 |
language |
VARCHAR |
255 |
默認語言的節點 |
name |
VARCHAR |
50 |
名稱節點 |
replyPolicy |
VARCHAR |
15 |
政策界定業主或出版商是否應得到答復項目 |
associationPolicy |
VARCHAR |
15 |
政策規定誰可以聯系葉節點的集合 |
maxLeafNodes |
NUMBER |
n/a |
馬克斯一些葉節點,一個節點可能會收集 |
ofPubsubNodeJIDs ( JIDs與節點) |
|||
列名 |
類型 |
長度 |
描述 |
serviceID |
VARCHAR |
100 |
編號托管服務節點(主鍵) |
nodeID |
VARCHAR |
100 |
編號的節點(主鍵) |
jid |
VARCHAR |
1024 |
JID實體(主鍵) |
associationType |
VARCHAR |
20 |
協會類型的節點 |
ofPubsubNodeGroups (名冊集團與節點) |
|||
列名 |
類型 |
長度 |
內容 |
serviceID |
VARCHAR |
100 |
編號托管服務節點 |
nodeID |
VARCHAR |
100 |
編號的節點 |
rosterGroup |
VARCHAR |
100 |
名冊組節點所有者可以簽署和檢索項目 |
ofPubsubAffiliation (節點分支機構) |
|||
列名 |
類型 |
長度 |
描述 |
serviceID |
VARCHAR |
100 |
編號托管服務節點(主鍵) |
nodeID |
VARCHAR |
100 |
編號的節點(主鍵) |
jid |
VARCHAR |
1024 |
JID的子公司(主鍵) |
affiliation |
VARCHAR |
10 |
所屬類別 |
ofPubsubItem (項目發布到節點) |
|||
列名 |
類型 |
長度 |
描述 |
serviceID |
VARCHAR |
100 |
編號托管服務節點(主鍵) |
nodeID |
VARCHAR |
100 |
編號的節點(主鍵) |
id |
VARCHAR |
100 |
編號的出版項目(獨特的每個節點)(主鍵) |
jid |
VARCHAR |
1024 |
JID出版商 |
creationDate |
VARCHAR |
15 |
創建日期 |
payload |
TEXT |
n/a |
XML的有效載荷包括在出版項目 |
ofPubsubSubscription (訂閱節點) |
|||
列名 |
類型 |
長度 |
描述 |
serviceID |
VARCHAR |
100 |
編號托管服務節點(主鍵) |
nodeID |
VARCHAR |
100 |
編號的節點(主鍵) |
id |
VARCHAR |
100 |
編號認購(主鍵) |
jid |
VARCHAR |
1024 |
地址接收通知 |
owner |
VARCHAR |
1024 |
JID的子公司,擁有認購 |
state |
VARCHAR |
15 |
國家認購(工作流程中的) |
deliver |
NUMBER |
n/a |
檢舉指出是否通知或未啟用 |
digest |
NUMBER |
n/a |
檢舉表明一個實體是否希望收到通知摘要 |
digest_frequency |
NUMBER |
n/a |
最低數目的毫秒之間發出任何兩個通知消化 |
expire |
VARCHAR |
15 |
日期在租賃認購將結束或已經結束 |
includeBody |
NUMBER |
n/a |
檢舉表明一個實體是否希望收到郵件正文除了有效載荷格式 |
showValues |
VARCHAR |
30 |
存在這些國家的實體希望收到通知 |
subscriptionType |
VARCHAR |
10 |
無論是用戶訂閱的項目或節點(收集節點只) |
subscriptionDepth |
NUMBER |
n/a |
收到通知的兒童一定深度(收集節點只) |
keyword |
VARCHAR |
200 |
關鍵字活動必須符合 |
ofPubsubDefaultConf (默認配置節點) |
|||
列名 |
類型 |
長度 |
描述 |
serviceID |
VARCHAR |
100 |
編號托管服務節點(主鍵) |
leaf |
NUMBER |
n/a |
檢舉指出是否配置屬於葉或收集節點(主鍵) |
deliverPayloads |
NUMBER |
n/a |
檢舉指出是否有效載荷中包含的通知 |
maxPayloadSize |
NUMBER |
n/a |
最大規模的有效載荷的字節 |
persistItems |
NUMBER |
n/a |
檢舉表明節點是否將持續出版項目 |
maxItems |
NUMBER |
n/a |
最大的項目數量將持續 |
notifyConfigChanges |
NUMBER |
n/a |
檢舉指出是否發送通知時,該節點的配置發生了變化 |
notifyDelete |
NUMBER |
n/a |
檢舉指出是否發送通知時,該節點將被刪除 |
notifyRetract |
NUMBER |
n/a |
檢舉指出是否發送通知時,發布的項目將被刪除 |
presenceBased |
NUMBER |
n/a |
檢舉指出是否發送通知只有用戶才 |
sendItemSubscribe |
NUMBER |
n/a |
檢舉指出是否向去年出版項目,以新用戶 |
publisherModel |
VARCHAR |
15 |
Publisher中使用的模式的節點 |
subscriptionEnabled |
NUMBER |
n/a |
檢舉指出是否允許訂閱 |
accessModel |
VARCHAR |
10 |
訪問模型所使用的節點 |
language |
VARCHAR |
255 |
默認語言的節點 |
replyPolicy |
VARCHAR |
15 |
政策界定業主或出版商是否應得到答復項目 |
associationPolicy |
VARCHAR |
15 |
政策規定誰可以聯系葉節點的集合 |
maxLeafNodes |
NUMBER |
n/a |
馬克斯一些葉節點,一個節點可能會收集 |
WEB服務器
Openfire采用內置的jetty作web服務器,在啟動AdminConsolePlugin插件時調用startup()方法啟動jetty服務器,9090為其明文端口,9091為其加密端口。
頁面處理
Openfire沒有采用現在很流行的技術架構(SSH),只使用JSP+JavaBean,但是它有自己的系統設計,就連日志都是自己做的,沒有使用我們熟悉的log4j。
現有的Openfire管理控制台可采用插件方式進行擴展(詳見插件開發說明部分介紹),頁面采用Jsp方式實現,頁面直接調用業務處理邏輯類(通常命名為XXManager)的實例方法,通常通過request對象封裝的方式傳遞頁面展現判定變量,常出現本頁跳轉。每個插件可定義自己的Servlet類和web.xml及web-custom.xml配置文件。
采用裝飾框架方式展現頁面,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裝飾器進行頁面展現。詳見“使用dom4j設計Openfire式導航菜單”部分相關介紹。