GLOOX 1.0 API ----框架

改定履歷:

2011-08-19-------------------新建文本文檔

2011-08-25--------------------增加XMPP官網鏈接

 2011-09-02-------------------新增對GLOOX1.0API文檔Main Page頁翻譯

        

        個人研究XMPP已經有大約一個星期的時間了,基本過程是先看了三天的RFC,包括RFC3290,RFC3291兩個主要協議,然後就是研究GLOOX1.0了。XMPP除了這兩個核心協議之外還有很多的XEP擴展協議。另外比較成熟的XMPP協議棧是GLOOX1.0版。前文已經貼出了RFC文檔,從這篇文章開始詳細介紹GLOOX,由於本人也是邊學邊記錄,有高手飄過時請不吝賜教。

        先貼出一下XMPP一些相關資源:

XMPP官網

gloox官方網站---這裏可以瞭解gloox的官方信息,開發文檔等

gloox1.0API文檔---個人將官方的API文檔整站下載下來打包,方便本地查看,強烈建議大家詳細看一下文檔的Main Page頁,以對整個gloox的設計有一個大的層面上的理解

RFC3920------XMPP核心協議

RFC3921------即時消息和出席信息

xmpp協議PPT----XMPP PPT文檔

 

        先這些吧,以後隨時補充

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

GLOOX協議棧是基於所謂“觀察者”設計模式設計的,如果你熟悉“觀察者”設計模式或者不熟悉但是在去深入瞭解GLOOX之前能去看一下“觀察者”模式會對學習GLOOX很有好處。其主要思想就是將觀察者“註冊”到“被觀察者”那裏,“被觀察者”有什麼風吹草動,觀察者都會知道,而進一步的處理就是在你的程序裏實現“觀察者”的若干虛函數。

環境搭建的話,本人用的是vs2008,下載下來gloox1.0,新建一個工程把gloox下src目錄裏所有的.h和.cpp全部加載,再添加一個工程用於對gloox進行測試,將兩個工程的生成目錄及依賴設置好即可。

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

 補充:博主近日學習GLOOX,重讀了API Main Page頁,覺得Main Page頁對於新手從較高層面上把握GLOOX有很大幫助,且這裏往往是新手容易忽略的最直接的一手資料信息來源,於是決定花時間翻譯出來。限於本人英文水平,大家可參照原英文文檔查看:


Introduction

GLOOX的設計遵循了所謂的觀察者設計模式,含義是一切都是基於事件驅動的。使用GLOOX不如Jabber/XMPP網絡有兩種方式------做爲客戶端或組件。C++ XMPP服務器庫請參考<http://camaya.net/glooxd>.

Note:

XMPP詳細規格說明書(RFC 3290)的11.5小節要求,線路上交換的數據只能是UTF-8編碼方式,由於GLOOX不知道輸入的數據是哪種編碼,所以GLOOX要求輸入數據必須是有效的UTF-8編碼。

Event Handlers:

GLOOX裏最重要的工具就是事件處理器(event hanbdlers),當前,除了有爲RFC中定義的基本協議服務的4種事件處理器,還有爲XEP實現裏的事件和附加功能服務的其它許多事件處理器。另外,一個日誌處理器、一個一般標籤處理器和一個連接事件處理器都是有效的。

通常這些處理器都是虛接口,你可以繼承它們派生出一個類,並且實現一些這些虛函數。然後你可以註冊這樣的一個子類對象到各自的協議實現裏。下面是一個簡單的例子:

class MyClass : public PresenceHandler
 {
   public:
     // reimplemented from PresenceHandler
     virtual void handlePresence( const Presence& presence );

   [...]
 };

 void MyClass::handlePresence( const Presence& presence )
 {
   // extract further information from the Presence object
 }

在某個地方你可以像下面這樣做:
 OtherClass::doSomething()
 {
   Client* client = new Client( ... );
   [...]
   MyClass* handler = new MyClass( ... );
   client->registerPresenceHandler( handler );
 }
然後你可以使用Stanza類提供的衆多getters(即get前綴的成員函數)進一步提取節中的數據
現在,每次接收到一個presence節(非subscription節)時,handlePresence都會被調用,參數是當前節。然後你可以使用Stanza類提供的衆多getters(一般來講是get前綴的方法,此處理解爲獲取stanza各數據的方法)進一步提取節中的數據以進一步處理。

幾乎所以的事件處理器的工作方式都是與這個例子相似的,接下來以使用連接事件處理器(class 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
   return true; // if you trust it, otherwise return false
 }

Note:

ConnectionListener是一個比較奇特的接口。你必須重新實現ConnectionListener::onTLSConnect()這個接口,如果你想成功連接一個啓用了TLS/SSL服務器的話。儘管GLOOX試圖檢查服務器的證書,但不會自動的信任該服務器。必須由客戶端程序員或用戶來決定是否信任此服務器。是否信任就由onTLSConnect()的返回值來表示,FLASE意味着你不信任該服務器,結果就是與服務器的連接中斷。

先去吃飯了,回來待續……

Components

Jabber/XMPP網絡中的一個組件是加載到服務器上的,它運行在實際的服務軟件之外,但它有相似的權限,組件使用XEP-0114中描述的協議去連接和驗證一個服務器.類Component 支持該協議並且可以用於創建一個新的Jabber component.簡單的例子如下:

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( Presence* presence )
{
   // presence info
}
Note

GLOOX官方並不支持5223上的連接方式。例如:在XML串先於SSL加密之前被髮送,因爲這是歷史遺留的方法況且不符合標準的XMPP協議。然而,GLOOX提供了一個ConnectionTlS類,做爲附加功能,允許你去綁定一個這樣的連接。

默認情況下,Client::connect()是阻塞的,直到連接終止(Client::disconnect()被調用,或者服務器終止連接)。


阻塞和非阻塞連接

對於某些種類的機器人來說阻塞式的連接(缺省的行爲)是非常理想的方式。幾乎所有的機器人都是對來自於服務器的事件做出響應。然而,對某些終端用戶或帶有GUI應用的客戶端來說就不那麼完美了。

這些情況下就需要用到非阻塞式的連接了。如果調用ClinetBase::connect(false),函數將會在綁定連接後立即返回。接下來程序員就有責任初始化一些從SOCKET接收到的數據。

一種最簡單的方法是以一個超時值(微秒)做爲參數週期性的調用ClientBase::recv(),缺省值-1意味着調用是阻塞的,直到有數據到達,對數據的解析也是自動的。

作爲週期性地輪詢一種替換辦法,你可以獲取連接的原始文件描述符。你可以在該文件描述符上使用select()並且當select上的數據有效時使用ClientBase::recv()。你可能直接從文件描述符得不到任何數據,也沒有辦法爲解析器提供數據。

爲了得到文件描述符,你必須手動設置一個連接類(ConnectionTCPClient),就像這樣:

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 = static_cast<ConnectionTCPClient*>( client->connectionImpl() )->socket();

[...]
顯然,只要你沒有使用setConnectionImpl()設置一個不同的連接類型就會工作。

Note

在0.9以後的版本里這已經發生了改變,ClientBase::fileDescriptor()不在可用了。

Roster Management

RFC3921定義瞭如何管理一個人的聯繫列表(花名冊)。在GLOOX中,類RosterManager實現了這個功能。一組簡單函數有效地實現了訂閱和取消訂閱實體的出席。也可以在沒有實際訂閱此聯繫人出席的情況,把他加入到自己的花名冊中。另外,接口RosterListener對應於各種花名冊相關的事件提供了一組回調函數。

如果你依上所述創建了一個客戶端對象,那麼你可以獲取一個RosterManager對象。Client::rosterManager()返回一個該類對象的指針。

Privacy Lists

同樣地,“隱私列表”也定義在RFC3921中,一個隱祕列表可以明確地禁止或允許 從聯繫人接收或發給聯繫人數據節,區分不同的聯繫人。你可以自己定義基於JID,節類型等的規則。類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 of Chat Messages

對於消息傳輸推薦使用MessageSession接口。它處理消息的發送和接收,也處理包括消息事件和聊天狀態(例如“打字中……”)等。查看MessageSession類文檔以獲取更多細節。

Protocol Extensions (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 Used with File Transfer
XEP-0048 Bookmark Storage
XEP-0049 Private XML Storage
XEP-0050 Ad-hoc Commands
XEP-0054 vcard-temp
XEP-0060 Publish-Subscribe
XEP-0065 SOCKS5 Bytestreams , used with File Transfer and HTTP and SOCKS5 Proxy support
XEP-0066 Out of Band Data , also used with File Transfer
XEP-0077 In-Band Registration
XEP-0078 Non-SASL Authentication (automatically used if the server does not support SASL)
XEP-0079 Advanced Message Processing
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-0106 JID Escaping
XEP-0114 Jabber Component Protocol
XEP-0115 Entity Capabilities (used automatically internally)
XEP-0124 Bidirectional-streams Over Synchronous HTTP (BOSH)
XEP-0131 Stanza Headers and Internet Metadata
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-0172 User Nickname
XEP-0184 Message Receipts
XEP-0199 XMPP Ping
XEP-0203 Delayed Delivery (new spec)
XEP-0206 see BOSH
XEP-0224 Attention
XEP-0256 Last Activity in Presence

更進一步的擴展可以用類StanzaExtensions很容易的實現。

File Transfer

對於文件傳輸,GLOOX實現了XEP-0095(流初始化協議)和XEP-0096(文件傳輸)協議的信號機制;爲傳輸實現了XEP-0065(SOCKS5 Bytestreams 流字節)和XEP-0047(帶內字節流)。參考 SIProfileFT類

HTTP and SOCKS5 Proxy support

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

發佈了31 篇原創文章 · 獲贊 2 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章