天天看點

gloox 之 MainPage

前言

gloox庫是按照“觀察者”模式設計的,意思就是說一切都是事件驅動的。      
使用gloox有兩種方法可以連接配接到Jabber/XMPP網絡,它們是用戶端或元件。      
第三種是作為伺服器,但是gloox不支援,盡管某些方面支援伺服器。
注意:XMPP詳細規格說明書(RFC 3290)要求,線路上交換的資料隻能是UTF-8編碼方式。
因為gloox不知道輸入的資料是何種編碼,是以傳給gloox的任何資料都必須是有效的UTF-8編碼。      

Event Handlers(事件處理器)

gloox最有用的工具就是事件處理器。
目前,不僅有為RFC中定義的基本協定服務的4種事件處理器,而且還有為XEP實作裡的事件和附加功能服務的衆多事件處理器。
另外,一個登入處理器,一個一般标簽處理器和一個連接配接事件處理器,它們都是有效的。      
幾乎這些處理器都是虛拟接口,你可以通過它派生出子類和實作其中的虛函數。
然後你用各自的協定實作注冊此子類對象。簡單例子如下:
 class MyClass : public PresenceHandler
 {
   public:
     // reimplemented from PresenceHandler
     virtual void handlePresence( Stanza *stanza );

   [...]
 };

 void MyClass::handlePresence( Stanza *stanza )
 {
   // extract further information from the stanza
 }
       
在某些地方你像這樣:      
OtherClass::doSomething() 
{   
   Client *client = new Client( ... );   
   [...]   
   MyClass *handler = new MyClass( ... );      
   //注冊此事件處理器(此處是出席處理)   
   client->registerPresenceHandler( handler ); 
} 
 
現在,在任何時間收到一個出席節(a presence stanza),MyClass::handlePresence()就會被調用,
目前節(current stanza)作為參數被傳入進此函數。
然後你可以使用Stanza類提供的衆多getters(即get字首的成員函數)進一步提取節中的資料。      
幾乎所有的事件處理器都是這樣類似地工作方式。以連接配接處理器(ConnectionListener類)再舉一例:      
class MyClass : public ConnectionListener
 {
   public:
     virtual void onConnect();

     virtual bool onTLSConnect( ... );
 };

 void MyClass::onConnect()
 {
   // do something when the connection is established(連接配接建立時的操作)
 }

 bool MyClass::onTLSConnect( const CertInfo& info )
 {
   // decide whether you trust the certificate, examine the CertInfo structure
   //(稽核CertInfo中的資料,确定是否相信此證書)
   return true; // if you trust it, otherwise return false(相信傳回 true,否則傳回false)
 }
 
注意:ConnectionListener類與衆不同。
如果你想成功地連接配接到一個啟用TLS/SSL的伺服器,必須重新實作ConnectionListener::onTLSConnect()函數。
盡管gloox試着去檢查伺服器證書,但不會自動信任此伺服器。用戶端程式員或使用者不得不自己決定是否信任此伺服器。
“是否信任”是通過onTLSConnect()函數傳回值表示的,讓此函數傳回false,則表示你不信任此伺服器或此證書,
與伺服器的連接配接立刻斷開。      

components(元件)

Jabber/XMPP網絡中的一個元件是加載到伺服器上的,它運作在實際的服務軟體之外,但它有相似的權限。
元件使用XEP-0114中描述的協定去連接配接和驗證一個伺服器。
Component類支援上述協定,利用它可以建立一個新的Jabber元件,就像下面一樣簡單:      
Component *comp = new Component( ... );
comp->connect();      

Clients(用戶端)

一個用戶端可以是最終使用者的聊天視窗,一個自動代理,或是一個沒有和特殊伺服器綁定在一起的簡單實體。
Client類實作了連接配接到一個XMPP伺服器必需的功能。一個漂亮的例子如下:
class MyClass : public ConnectionListener, PresenceHandler
 {
   public:
     void doSomething();

     virtual void handlePresence( ... );

     virtual void onConnect();

     virtual bool onTLSConnect( const CertInfo& info );
 };

 void MyClass::doSomething()
 {
   JID jid( "jid@server/resource" );
   Client *client = new Client( jid, "password" );
   client->registerConnectionListener( this );
   client->registerPresenceHandler( this );
   client->connect();
 }

 void MyClass::onConnect()
 {
   // connection established, auth done (see API docs for exceptions)(連接配接建立,如果異常,請查閱文檔)
 }

 bool MyClass::onTLSConnect( const CertInfo& info )
 {
   // examine certificate info(檢查證書資訊)
 }

 void MyClass::handlePresence( Stanza *stanza )
 {
   // presence info(進一步提取節裡的資料)
 }       
注意:gloox不支援(将來也不會支援)基于5223端口上的連接配接,
也就是說,SSL加密先于任何XML被發送,這是因為曆史原因,況且不符合XMPP标準。
預設情況下,Client::connect()是阻塞的,一直到連接配接終止(調用Client::disconnect()或伺服器關閉連接配接)。      

Blocking vs. Non-blocking Connections ( 阻塞連接配接 與 非阻塞連接配接 比較 )

一些類型的自動代理采用阻塞連接配接(即預設)比較好。所有的自動代理都是處理伺服器發來的資料。
盡管如此,對最終用戶端或基于圖形界面(GUI)的應用來說就遠遠不足了。
在這種情況下,就要使用非阻塞連接配接了。如果這樣調用ClientBase::connect(false),此函數在連接配接成功後會立即傳回。
然後程式員就有責任初始化一些從套接字收到的資料。
一種簡單的方法是,以一個數字作為逾時參數周期地調用ClientBase::recv()。
此參數預設值-1,意思是此調用會一直阻塞,直到收到一些資料,然後它會自動解析這些資料。
作為周期性地輪詢一種替換辦法,你可以得到連接配接的原始檔案描述符。
然後在其上調用select()函數或當選擇那些資料有效時調用ClientBase::recv()。
你可能直接從檔案描述符得不到任何資料,也沒有辦法為解析器提供資料。      
為了得到檔案描述符,你必須手動設定一個連接配接類,就像這樣:      
 Client* client = new Client( ... );
 ConnectionTCPClient* conn = new ConnectionTCPClient( client, client->logInstance(), server, port );
 client->setConnectionImpl( conn );      
 client->connect( false );
 int sock = conn->socket();      
 [...]
你也可以這樣取出:      
Client* client = new Client( ... );
 client->connect( false );
 int sock = dynamic_cast<ConnectionTCPClient*>( client->connectionImpl() )->socket();      
 [...]      
注意:這些在0.9以後的版本中己經改變,ClientBase::fileDescriptor()不再有效。      

Roster Management (花名冊管理)

其它,RFC3921定義了管理一個人的聯系人清單(花名冊)的協定。gloox 的RosterManager類實作了此功能。
幾個簡單實用的函數可以有效地訂閱或取消訂閱遠端實體的出席。
也可以在沒有實際訂閱此聯系人出席的情況,把他加入到自己的花名冊中。
另外,RosterListener接口類提供了一些回調函數,用于與花名冊有關的各種各樣的事件。
如果你像前面示範那樣建立了一個Client對象,那麼你就己經擁有了一個RosterManager對象,
調用Client::rosterManager()就會傳回此對象的指針。      

Privacy Lists (隐秘清單)

同樣定義于RFC3921中的Privacy Lists。一個隐秘清單可以明确地禁止或允許 從聯系人接收或發給聯系人資料節,區分不同的聯系人。你可以自己定義基于JID,節類型等的規則。不要說gloox實作了非      
常好的隐秘清單。PrivacyManager類和PrivacyListHandler虛拟接口類在在處理隐秘清單上機動靈活。      
 PrivacyManager *p = new PrivacyManager( ... );
 [...]
 PrivacyListHandler::PrivacyList list;
 PrivacyItem item( PrivacyItem::TypeJid, PrivacyItem::ActionDeny,
                   PrivacyItem::PacketMessage, "[email protected]" );
 list.push_back( item );      
 PrivacyItem item2( PrivacyItem::TypeJid, PrivacyItem::ActionAllow,
                    PrivacyItem::PacketIq, "[email protected]" );
 list.push_back( item2 );      
 p->store( "myList", list );      

Authentication (認證)

gloox 支援基于老舊的XEP-0078定義的IQ認證,也支援SASL的機制。更多内容請參考Client類文檔。      

Sending and Receiving fo Chat Messages ( 聊天消息的收發 )

對于消息傳遞,建議使用MessageSession虛拟接口類。它處理消息的收發,消息事件和聊天狀态。
更多細節請參閱MessageSession文檔。      

Protocol Enhancements(XEPs)(擴充協定)

XMPP标準基金會釋出了許多核心協定的擴充,稱為XMPP Extension Protocols(XEPs)(XMPP擴充協定)。
幾個擴充協定己經在gloox中得到實作。      
    * XEP-0004 Data Forms
    * XEP-0012 Last Activity
    * XEP-0013 Flexible Offline Message Retrieval
    * XEP-0022 Message Events (see MessageSession for examples)
    * XEP-0027 Current Jabber OpenPGP Usage (see GPGSigned and GPGEncrypted )
    * XEP-0030 Service Discovery
    * XEP-0045 Multi-User Chat
    * XEP-0047 In-Band Bytestreams
    * XEP-0048 Bookmark Storage
    * XEP-0049 Private XML Storage
    * XEP-0050 Ad-hoc Commands
    * XEP-0054 vcard-temp
    * XEP-0065 SOCKS5 Bytestreams , used with File Transfer and HTTP and SOCKS5 Proxy support
    * XEP-0066 Out of Band Data
    * XEP-0077 In-Band Registration
    * XEP-0078 Non-SASL Authentication (automatically used if the server does not support SASL)
    * XEP-0083 Nested Roster Groups (automatically used if supported by the server. see RosterManager )
    * XEP-0085 Chat State Notifications (see MessageSession for examples)
    * XEP-0091 Delayed Delivery (old spec)
    * XEP-0092 Software Version (integrated into Service Discovery )
    * XEP-0095 Stream Initiation , used with File Transfer
    * XEP-0096 File Transfer
    * XEP-0114 Jabber Component Protocol
    * XEP-0138 Stream Compression (used automatically if gloox is compiled with zlib and if the server supports it)
    * XEP-0145 Annotations
    * XEP-0153 vCard-based Avatars
    * XEP-0203 Delayed Delivery (new spec)      

File Transfer  (檔案傳輸)

為了檔案傳輸,gloox 實作了XEP-0095(流初始化)以及XEP-0096(檔案傳輸)的信号機制,
為傳輸實作了XEP-0065(SOCKS5 Bytestreams 流位元組)。參考 SIProfileFT類。
另外,XEP-0047(In-Band Bytestreams)的實作目前在XEPs 0095 和 0096的信号上還不完整。
是以,gloox也許不适合向遠端傳送檔案。參考InBandBytestreamManager類。      

HTTP and SOCKS5 Proxy support (http和socks5代理支援 )

gloox 有能力穿過http及SOCKS5代理,即便是連鎖代理。參考ConnectionHTTPProxy類 和 ConnectionSocks5Proxy類      

繼續閱讀