【XMPP】gloox开源代码分析

来源:互联网 发布:现代机械优化设计 编辑:程序博客网 时间:2024/06/05 22:55

最近项目上需要用到gloox的开源代码,结合项目的特性,对XMPP有了部分了解,期间碰到的问题大致如下:

1. Gloox工程的移植

网上有不少Gloox的测试代码,找一份XCode平台下能编译通过的即可,笔者找的一份为“glooxForIos”,

wiki的地址为:http://code.google.com/p/gloox-for-ios/


2. Connect.h分析

Connect.h是gloox的测试类代码,它实现了ConnectionListener, LogHandler, MessageHandler, TLSHandler等几个接口,分别对连接,日志,消息,TLS进行管理,具体的功能看其源码就知道了。

其主要的成员变量有:

    Client *j;    TLSBase* m_tls;    std::string m_send;    const JID rcpt;
Client就是自身的客户端,构建的时候需要传入一个JID作为构造参数;

TLSBase负责对数据的加密,解密,构建安全通道(负责握手)等;

m_send就是传递的消息实体;

rcpt是要与之通信的对象,也需要jid来进行构造。


主要的接口有:

void xtlsSend()void start()

前者负责给其它client发送消息,后再负责初始化client;

在项目中,会发现xtlsSend完全不够用,它发送的消息格式需要重构,发送server能认识的消息。


3. 初始化工作

a. jid的设置

jid不能直接挂上邮件名,比如“**@xx.com”, 这样的设置不会影响认证的过程,但认证之后的present,message会收不到。在后面需要挂上reource标签,比如“/ios”,标明是来自ios的,以示区别。

b.server的地址

这个地址值,在JID中,通过setServer的方式设置进去。

c.auth的方式

在连接成功后,server端会发送认证方式到client,具体如下:

<stream:stream  from='im.example.com'  id='vgKi/bkYME8OAj4rlXMkpucAqe4='  to='juliet@im.example.com'  version='1.0'  xml:lang='en'  xmlns='jabber:client'  xmlns:stream='http://etherx.jabber.org/streams'><stream:features>  <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>    <mechanism>SCRAM-SHA-1-PLUS</mechanism>    <mechanism>SCRAM-SHA-1</mechanism>    <mechanism>PLAIN</mechanism>  </mechanisms>  <pipelining xmlns='urn:xmpp:features:pipelining'/>  <c xmlns='http://jabber.org/protocol/caps'     hash='sha-1'     node='http://prosody.im/'     ver='ItBTI0XLDFvVxZ72NQElAzKS9sU='/></stream:features>


方式有plain,scram-sha-1等方式,此时需要发送指令到server,确定认证方式,详情参见:

http://xmpp.org/extensions/xep-0305.html


d. 修改认证方式

由于项目中server提供的认证方式中有一个token的,没能搞清楚XMPP中是如何通过Token的方式跟系统认证。

于是修改了clientBase中的

 void ClientBase::startSASL( SaslMechanism type )

部分代码如下:

      case SaslMechPlain:      {//        a->addAttribute( "mechanism", "PLAIN" );//        std::string tmp;//        if( m_authzid )//          tmp += m_authzid.bare();////        tmp += '\0';//        if( !m_authcid.empty() )//          tmp += m_authcid;//        else//          tmp += m_jid.username();//        tmp += '\0';//        tmp += m_password;//        a->setCData( Base64::encode64( tmp ) );          a->addAttribute( "mechanism", "TOKEN" );          a->setCData( ((XMPPJabberInfo)XMPPCoreMgr::sharedInstance()->getJabberData()).getJabberToken() );                  break;

这样就能通过server端的认证,但没有走正途。


5. 密码的设置

密码的认证,XMPP要求不高,可以为任意一个密码,但不能为空。


boolClient::handleNormalNode( Tag* tag )

会进行判定,如果密码为空,则不进行登录。

else if( !username().empty() && !password().empty() ){    if( !login() )          {            logInstance().err( LogAreaClassClient, "The server doesn't support"                                           " any auth mechanisms we know about" );            disconnect( ConnNoSupportedAuth );     } }


TBD...


原创粉丝点击