GLOOX 1.0 API ----框架

转自:http://blog.csdn.net/kkaxiao/article/details/6702298

 

改定履历:

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实现里的事件和附加功能服务的其它许多事件处理器。另外,一个日志处理器、一个一般标签处理器和一个连接事件处理器都是有效的。

通常这些处理器都是虚接口,你可以继承它们派生出一个类,并且实现一些这些虚函数。然后你可以注册这样的一个子类对象到各自的协议实现里。下面是一个简单的例子:

  1. class  MyClass :  public  PresenceHandler  
  2.  {  
  3.     public :  
  4.       // reimplemented from PresenceHandler   
  5.       virtual   void  handlePresence(  const  Presence& presence );  
  6.   
  7.    [...]  
  8.  };  
  9.   
  10.   void  MyClass::handlePresence(  const  Presence& presence )  
  11.  {  
  12.     // extract further information from the Presence object   
  13.  }  

在某个地方你可以像下面这样做:
  1. OtherClass::doSomething()  
  2. {  
  3.   Client* client =  new  Client( ... );  
  4.   [...]  
  5.   MyClass* handler =  new  MyClass( ... );  
  6.   client->registerPresenceHandler( handler );  
  7. }  
然后你可以使用Stanza类提供的众多getters(即get前缀的成员函数)进一步提取节中的数据
现在,每次接收到一个presence节(非subscription节)时,handlePresence都会被调用,参数是当前节。然后你可以使用Stanza类提供的众多getters(一般来讲是get前缀的方法,此处理解为获取stanza各数据的方法)进一步提取节中的数据以进一步处理。

几乎所以的事件处理器的工作方式都是与这个例子相似的,接下来以使用连接事件处理器(class ConnectionListener)为例,再举一例:

  1. class  MyClass :  public  ConnectionListener  
  2.  {  
  3.     public :  
  4.       virtual   void  onConnect();  
  5.   
  6.       virtual   bool  onTLSConnect( ... );  
  7.  };  
  8.   
  9.   void  MyClass::onConnect()  
  10.  {  
  11.     // do something when the connection is established   
  12.  }  
  13.   
  14.   bool  MyClass::onTLSConnect(  const  CertInfo& info )  
  15.  {  
  16.     // decide whether you trust the certificate, examine the CertInfo structure   
  17.     return   true // if you trust it, otherwise return false   
  18.  }  

Note:

ConnectionListener 是一个比较奇特的接口。你必须重新实现ConnectionListener::onTLSConnect()这个接口,如果你想成功连接一个启用了TLS/SSL服务器的话。尽管GLOOX试图检查服务器的证书,但不会自动的信任该服务器。必须由客户端程序员或用户来决定是否信任此服务器。是否信任就由onTLSConnect()的返回值来表示,FLASE意味着你不信任该服务器,结果就是与服务器的连接中断。

先去吃饭了,回来待续……

Components

Jabber/XMPP网络中的一个组件是加载到服务器上的,它运行在实际的服务软件之外,但它有相似的权限,组件使用XEP-0114中描述的协议去连接和验证一个服务器.类Component 支持该协议并且可以用于创建一个新的Jabber component.简单的例子如下:

  1. Component* comp =  new  Component( ... );  
  2. comp->connect();  

Clients

一个客户端可以是终端用户的聊天客户端,一个机器人或者是一个没有和特殊服务器绑定在一起的简单实体。类Client实现了连接一个XMPP 服务器所需要的功能。一个例子如下:

  1. class  MyClass :  public  ConnectionListener, PresenceHandler  
  2. {  
  3. public :  
  4.       void  doSomething();  
  5.   
  6.       virtual   void  handlePresence( ... );  
  7.   
  8.       virtual   void  onConnect();  
  9.   
  10.       virtual   bool  onTLSConnect(  const  CertInfo& info );  
  11. };  
  12.   
  13. void  MyClass::doSomething()  
  14. {  
  15.    JID jid(  "jid@server/resource"  );  
  16.    Client* client =  new  Client( jid,  "password"  );  
  17.    client->registerConnectionListener(  this  );  
  18.    client->registerPresenceHandler(  this  );  
  19.    client->connect();  
  20. }  
  21.   
  22. void  MyClass::onConnect()  
  23. {  
  24.     // connection established, auth done (see API docs for exceptions)   
  25. }  
  26.   
  27. bool  MyClass::onTLSConnect(  const  CertInfo& info )  
  28. {  
  29.     // examine certificate info   
  30. }  
  31.   
  32. void  MyClass::handlePresence( Presence* presence )  
  33. {  
  34.     // presence info   
  35. }  
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),就像这样:

  1. Client* client =  new  Client( ... );  
  2. ConnectionTCPClient* conn =  new  ConnectionTCPClient( client, client->logInstance(), server, port );  
  3. client->setConnectionImpl( conn );  
  4.   
  5. client->connect(  false  );  
  6. int  sock = conn->socket();  
  7.   
  8. [...]  

有可能像下面这样获取文件描述符:
  1. Client* client =  new  Client( ... );  
  2. client->connect(  false  );  
  3. int  sock =  static_cast <ConnectionTCPClient*>( client->connectionImpl() )->socket();  
  4.   
  5. [...]  
显然,只要你没有使用setConnectionImpl()设置一个不同的连接类型就会工作。

Note

在0.9以后的版本里这已经发生了改变,ClientBase::fileDescriptor()不在可用了。

Roster Management

RFC3921 定义了如何管理一个人的联系列表(花名册)。在GLOOX中,类RosterManager实现了这个功能。一组简单函数有效地实现了订阅和取消订阅实体的出席。也可以在没有实际订阅此联系人出席的情况,把他加入到自己的花名册中。另外,接口RosterListener对应于各种花名册相关的事件提供了一组回调函数。

如果你依上所述创建了一个客户端对象,那么你可以获取一个RosterManager对象。Client::rosterManager()返回一个该类对象的指针。

Privacy Lists

同样地,“隐私列表”也定义在RFC3921中,一个隐秘列表可以明确地禁止或允许 从联系人接收或发给联系人数据节,区分不同的联系人。你可以自己定义基于JID,节类型等的规则。类PrivacyManager 和类PrivacyListHandler虚接口在隐私列表的处理上比较灵活。

 

  1. PrivacyManager* p =  new  PrivacyManager( ... );  
  2. [...]  
  3. PrivacyListHandler::PrivacyList list;  
  4. PrivacyItem item( PrivacyItem::TypeJid, PrivacyItem::ActionDeny,  
  5.                   PrivacyItem::PacketMessage,  "[email protected]"  );  
  6. list.push_back( item );  
  7.   
  8. PrivacyItem item2( PrivacyItem::TypeJid, PrivacyItem::ActionAllow,  
  9.                    PrivacyItem::PacketIq,  "[email protected]"  );  
  10. list.push_back( item2 );  
  11.   
  12. 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类.

 

(###)

你可能感兴趣的:(XMPP,gloox)