青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

woomsg

在路上

gloox代碼分析3 - 注冊模塊

#jabber協議中如何注冊一個用戶?
首先要與服務器建立一個連接, 在完成TLS握手之后就可以進行注冊了,為什么不需要SASL握手呢?因為SASL握手只針對已經注冊的用戶在登陸服務器的時候使用.(修改密碼和刪除用戶的時候需要SASL握手)
下面以openfire作為服務器,注冊一個用戶的過程如下:
(假設已經完成了TLS握手)
1. ( C->S )
<stream:stream
    to='ziz-wrks-tfsxp1'
    xmlns='jabber:client'
    xmlns:stream='http://etherx.jabber.org/streams' 
    xml:lang='en'
    version='1.0'>

TLS握手結束后, 發送新的'hello'消息

2. ( S->C )
<stream:stream
    xmlns:stream='http://etherx.jabber.org/streams'
    xmlns='jabber:client'
    from='ziz-wrks-tfsxp1'
    id='b691538a'
    xml:lang='en' version='1.0'/>

Server回應Client的hello消息.

3. ( S->C )
<stream:features>
  <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
    <mechanism>DIGEST-MD5</mechanism>
    <mechanism>PLAIN</mechanism>
    <mechanism>ANONYMOUS</mechanism>
    <mechanism>CRAM-MD5</mechanism>
  </mechanisms>
  <compression xmlns='http://jabber.org/features/compress'>
    <method>zlib</method>
  </compression>
  <auth xmlns='http://jabber.org/features/iq-auth'/>
  <register xmlns='http://jabber.org/features/iq-register'/>
</stream:features>

服務器支持的features(可以register)

4. ( C->S )
<iq type='get' id='uid1'>
  <query xmlns='jabber:iq:register'/>
</iq>

客戶端請求注冊
5. ( S->C )
<iq type='result' id='uid1'>
  <query xmlns='jabber:iq:register'>
    <username/>
    <password/>
    <email/>
    <name/>
    <x xmlns='jabber:x:data' type='form'>
      <title>XMPP Client Registration</title>
      <instructions>Please provide the following information</instructions>
      <field var='FORM_TYPE' type='hidden'>
        <value>jabber:iq:register</value>
      </field>
      <field label='Username' var='username' type='text-single'>
        <required/>
      </field>
      <field label='Full name' var='name' type='text-single'/>
      <field label='Email' var='email' type='text-single'/>
      <field label='Password' var='password' type='text-private'>
        <required/>
      </field>
    </x>
  </query>
</iq>

服務器返回注冊需要的fields
(其中元素x里面的數據是擴展性的數據表但,暫時忽略)

6. ( C->S )
<iq id='uid2' type='set'>
  <query xmlns='jabber:iq:register'>
    <username>user3</username>
    <password>user@123</password>
    <name/>
    <email/>
  </query>
</iq>

用戶提交注冊信息.

7. ( S->C )
<iq type='result' id='uid2' to='ziz-wrks-tfsxp1/b691538a'/>

服務器返回注冊結果

#如何更改用戶密碼
更改用戶密碼必須在完成與服務器的鏈接之后才能進行,也就是完成與服務器的TLS,SASl握手之后
再進行.

1. ( C->S )
<iq type='set' id='uid3'>
  <query xmlns='jabber:iq:register'>
    <username>user23</username>
    <password>123456</password>
  </query>
</iq>

發送更改密碼的請求

2. ( S->C )
<iq type='result' id='uid3' to='user23@ziz-wrks-tfsxp1/2f21fd1f'/>

返回處理結果(操作成功)

#如何注銷一個用戶
注銷一個用戶必須在完成與服務器的鏈接之后才能進行,也就是完成與服務器的TLS,SASl握手之后
再進行.

1. ( C->S )
<iq type='set' id='uid3' from='testuser@ziz-wrks-tfsxp1/3a418274'>
   <query xmlns='jabber:iq:register'><remove/></query>
</iq>

發送注銷用戶的請求

2. ( S->S )

<iq type='result' id='uid3' to='testuser@ziz-wrks-tfsxp1/3a418274'/>

返回處理結果(注銷成功)

總結:
注冊用戶和更改或者注銷用戶的一個區別就是注冊用戶不需要經過SASL握手,而更改和注銷用戶需要.
也就是需要對用戶身份進行驗證.

gloox的注冊模塊
registration.h
registration.cpp
registrationhandler.h
就是對上述協議的封裝,方便創建register stanza,并把收到的消息分發到相應的handler方法.

gloox的client是如何處理xml流的呢?
1. 連接到服務器后,使客戶端進入"receive mode",可以循環的接收數據.
2. 數據流 [接收到的數據 handleReceiveData() ] -> [解析xml數據流,解析成不同的tag, parser()] -> [ 觸發handleTag(), 針對不同的tag分發到不同的handlers做不同的處理 ]
 - stream:stream - ...
 - stream:error - ...
 - Iq           - IqHandler
 - Presence - presenceHandler
 - Message - messageHandler 

Iq消息的處理機制,以及trackID機制:

實質上registration是一個Iqhandler, 它實現的是handleIqID( Stanza *stanza, int context )接口,而不是handleIq( Stanza *stanza )接口,其中context實質上為iqHandler具體實現中的子操作類型,在registration中分別為fetchRegisterFiled, createAccount, changePassword, removeAccount.

對一個Iq Stanza的處理方式可以通過一般的IqHandler - xmlnamespace filer或者IqHandler - TrackID機制來處理.

下面代碼展示了如何注冊/修改密碼/刪除用戶(服務器是openfire):
  1#include <iostream>
  2#include "registration.h" // gloox headers
  3#include "client.h"
  4#include "connectionlistener.h"
  5#include "logsink.h"
  6#include "loghandler.h"
  7
  8#pragma comment( lib, "gloox.lib" )
  9using namespace gloox;
 10
 11#define SERVERNAME   "xxxxxx"
 12#define HEADERTO     "xxxxxx"
 13
 14#define USERNAME     "user123"
 15#define PASSWORD     "user@123"
 16#define NEWPASSWORD  "123456"
 17
 18//
 19// three scenario3
 20// 1 - register user (Note: don't need SASL handshake)
 21// 2 - change password (Note: need SASL handshake)
 22// 3 - delete user (Note: need SASL handshake)
 23//
 24class RegisterImpl : public RegistrationHandler, ConnectionListener, LogHandler {
 25public:
 26  void run();
 27
 28  //implement RegistrationHandler
 29  void handleRegistrationFields( const JID& from, int fields, std::string instructions );
 30  void handleAlreadyRegistered( const JID& from );
 31  void handleRegistrationResult( const JID& from, RegistrationResult regResult );
 32  void handleDataForm( const JID& from, const DataForm &form );
 33  void handleOOB( const JID& from, const OOB& oob );
 34
 35  //implement ConnectionListener
 36  void onConnect();
 37  void onDisconnect( ConnectionError e );
 38  void onResourceBindError( ResourceBindError error );
 39  void onSessionCreateError( SessionCreateError error );
 40  bool onTLSConnect( const CertInfo& info );
 41  void onStreamEvent( StreamEvent event );
 42
 43  //implement LogHandler
 44  void handleLog( LogLevel level, LogArea area, const std::string& message );
 45
 46private:
 47  Registration* register_;
 48  Client* client_;
 49}
;
 50
 51void RegisterImpl::run() {
 52  client_ = new Client(SERVERNAME);
 53  client_->setHeaderTo(HEADERTO);
 54  client_->registerConnectionListener(this);
 55  register_ = new Registration( client_ );
 56  register_->registerRegistrationHandler( this );
 57  client_->logInstance().registerLogHandler( LogLevelDebug, LogAreaAll, this  );
 58  
 59  // run scenario2 and scenario3 need enable username and
 60  // password to run SASL, scenario1 did not need.
 61  client_->setUsername(USERNAME);
 62  client_->setPassword(PASSWORD);
 63
 64  client_->connect();
 65
 66  delete register_;
 67  delete client_;
 68}

 69
 70void RegisterImpl::handleRegistrationFields( const JID& from, int fields, std::string instructions ) {
 71  // register account
 72  std::cout<<"impl# register instruction: "<<instructions<<std::endl;
 73  RegistrationFields vals;
 74  vals.username = USERNAME;
 75  vals.password = PASSWORD;
 76  register_->createAccount( fields, vals );
 77}

 78
 79void RegisterImpl::handleAlreadyRegistered( const JID& from ) {
 80  std::cout<<"impl# the count already exists."<<std::endl;
 81}

 82
 83void RegisterImpl::handleRegistrationResult( const JID& from, RegistrationResult regResult ) {
 84  if( regResult == RegistrationSuccess ) {
 85    std::cout<<"impl# operation success."<<std::endl;
 86  }
 else {
 87    std::cout<<"impl# operation failed."<<std::endl;
 88  }

 89
 90  client_->disconnect();
 91}

 92
 93void RegisterImpl::handleDataForm( const JID& from, const DataForm &form ) {
 94  //TODO:
 95}

 96
 97void RegisterImpl::handleOOB( const JID& from, const OOB& oob ) {
 98  //TODO:
 99}

100
101void RegisterImpl::onConnect() {
102  std::cout<<"impl# connect to server success."<<std::endl;
103  //operation
104
105  // scenario1 - register
106  // this will invoke handleRegistrationResult() to createAccount
107  // Note: doesn't need SASL handshake
108  register_->fetchRegistrationFields(); 
109
110  // scenario2 - change password
111  // Note: need SASL handshake, in gloox, set the username & password in clientbase, will
112  //       run the SASL handshake.
113  // register_->changePassword( client_->username(), NEWPASSWORD );
114
115  // scenario3 - delete account
116  // Note: need SASL handshake,
117  // register_->removeAccount();
118}

119
120void RegisterImpl::onDisconnect( ConnectionError e ) {
121  std::cout<<"impl# disconnected."<<std::endl;
122}

123
124void RegisterImpl::onResourceBindError( ResourceBindError error ) {
125  //TODO:
126}

127
128void RegisterImpl::onSessionCreateError( SessionCreateError error ) {
129  //TODO:
130}

131
132bool RegisterImpl::onTLSConnect( const CertInfo& info ) {
133  std::cout<<"impl# tls connect to server success."<<std::endl;
134  return true;
135}

136
137void RegisterImpl::onStreamEvent( StreamEvent event ) {
138  //TODO:
139}

140
141void RegisterImpl::handleLog( LogLevel level, LogArea area, const std::string& message ) {
142  std::cout<<"impl-log# "<<message<<std::endl;
143}

144
145int main( int argc, char* argv[] ) {
146  RegisterImpl impl;
147  impl.run();
148  return 0;
149}

posted on 2008-11-06 12:59 ysong.lee 閱讀(4590) 評論(3)  編輯 收藏 引用

Feedback

# re: gloox代碼分析3 - 注冊模塊 2008-11-14 19:09 ly

hao  回復  更多評論   

# re: gloox代碼分析3 - 注冊模塊 2008-11-14 19:13 ly

client_->setHeaderTo(HEADERTO);
錯誤提示在client 里找不到setHeaderTo?????什么問題?
我把你這句去掉后,改成
client_->disableRoster();
發現能注冊成功,但是,登陸提示:sasl failed。
登陸不成功!~~~什么原因~~~望解答!~~  回復  更多評論   

# re: gloox代碼分析3 - 注冊模塊 2008-11-18 13:01 ysong.lee

1. 我對gloox進行了修改,client_->setHeaderTo(HEADERTO); 是自己添加的方法,目的是為了fix gloox不能連接到gtalk server的問題,通過修改,可以自己控制ClientBase::header()方法中在發送hello信息時候的to屬性,這在服務器是gtalk server的時候是有用的,如果我們的服務器地址設置為talk.google.com,則header()方法默認to="talk.google.com",這是錯誤的,應該為to="gmail.com".

2. sasl failed。登陸的時候需要sasl 驗證,如果服務器為gtalk server, 當你接收到服務器發送的以下信息的時候
(Server -> Client)
<stream:features>
<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
<mechanism>PLAIN</mechanism>
<mechanism>X-GOOGLE-TOKEN</mechanism>
</mechanisms>
</stream:features>

需要進行sasl驗證,發送的驗證數據格式為:
'\0'+username+'\0'+password 的base64編碼, username和password必須是經過認證的.
例如:
'\0' + 'ysong.lee@gmail.com' + '\0' + 123456 -> 經過base64編碼處理
(Client -> Server)
<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="PLAIN">
AHlzb25nLmxlZUBnbWFpbC5jb20AeXNvbmdAMTk4NA==
</auth>

3. 如果還有疑問,可以參考我的另外一篇文章“如何利用jabber協議與gtalk服務器通訊 - 建立會話”,里面詳細描述了如何登陸到gtalk服務器.

4. 做XMPP的程序,仔細閱讀從server到client和client的server的xml數據流,并參考標準協議,問題都可以解決:), 還有問題可以發email給我.

@ly
  回復  更多評論   


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美fxxxxxx另类| 久久婷婷麻豆| 一本久道久久综合狠狠爱| 国产午夜精品全部视频在线播放| 欧美一区亚洲二区| 日韩午夜精品| 另类尿喷潮videofree| 日韩视频永久免费| 久久亚洲捆绑美女| 久久精品国产v日韩v亚洲| 免费观看久久久4p| 亚洲免费av观看| av72成人在线| 亚洲亚洲精品三区日韩精品在线视频| 欧美日韩色综合| 亚洲一区高清| 欧美一区综合| 欧美电影免费观看网站| 欧美1区2区| 国产精品二区二区三区| 亚洲欧美视频一区二区三区| 欧美一区二区三区在线视频| 欧美一区二区黄| 免费亚洲电影| 亚洲影视在线播放| 新67194成人永久网站| 久久综合一区二区三区| av不卡在线| 国产精品区一区二区三| 毛片av中文字幕一区二区| 欧美日韩一区三区| 国产一区视频观看| 亚洲一区二区三区精品视频| 欧美性猛交xxxx乱大交退制版 | 亚洲精品久久久久久久久久久久久| 亚洲激情av| 国产一区二区三区久久久| 日韩视频在线播放| 男同欧美伦乱| 亚洲欧美日韩爽爽影院| 亚洲乱码精品一二三四区日韩在线 | 欧美日韩国产不卡在线看| 国产一区二区三区在线观看免费 | 免费欧美电影| 欧美成人三级在线| 媚黑女一区二区| 国产精品免费看片| 一卡二卡3卡四卡高清精品视频| 久久久亚洲国产天美传媒修理工| 亚洲午夜久久久| 国产一区二区三区最好精华液| 欧美一区二区视频97| 国产欧美日韩一区二区三区在线| 亚洲图片欧洲图片av| 欧美在线视频一区| 亚洲国产婷婷| 午夜精品久久久99热福利| 一本综合精品| 一区二区在线观看视频| 亚洲福利国产精品| 欧美深夜福利| 久久精品免费电影| 牛牛影视久久网| 久久国产直播| 欧美三级不卡| 亚洲精品麻豆| 亚洲第一福利视频| 性8sex亚洲区入口| 欧美精品一区视频| 久久综合九色99| 国产精品视频久久| 欧美91视频| 久久国产毛片| 国产精品一级| 亚洲一区精品电影| 亚洲一区二区高清视频| 欧美激情1区2区3区| 农夫在线精品视频免费观看| 国产欧美综合在线| 亚洲欧美日韩国产综合在线| 亚洲国产精品福利| 欧美中在线观看| 亚洲精品乱码久久久久久蜜桃麻豆| 欧美日韩国产一区精品一区| 欧美激情成人在线| 一本久道久久综合婷婷鲸鱼| 欧美夫妇交换俱乐部在线观看| 老司机午夜精品视频在线观看| 国产网站欧美日韩免费精品在线观看 | 久久九九全国免费精品观看| 午夜视频精品| 欧美一区观看| 欧美在线日韩在线| 韩日在线一区| 美女福利精品视频| 99re6这里只有精品视频在线观看| 99精品福利视频| 国产精品久久久久久影院8一贰佰| 亚洲欧美在线视频观看| 欧美wwwwww| 亚洲自拍偷拍一区| 国产精品一二三| 毛片精品免费在线观看| 亚洲宅男天堂在线观看无病毒| 美日韩精品视频| 欧美在线亚洲| 亚洲一区二区三区四区五区午夜| 黄色成人免费观看| 国产精品自在在线| 国产精品久久网站| 欧美人成在线| 欧美日韩精品久久久| 久久国产加勒比精品无码| 99精品免费| 在线视频亚洲一区| 亚洲欧美日本伦理| 亚洲欧美视频| 韩日精品在线| 韩日在线一区| …久久精品99久久香蕉国产| 国产精品久在线观看| 欧美小视频在线观看| 国产精品久久二区二区| 国产精品高潮呻吟| 欧美视频福利| 国产亚洲综合在线| 久久久久久久成人| 亚洲欧美日韩精品一区二区| 日韩视频精品在线| 99亚洲伊人久久精品影院红桃| 亚洲看片网站| 一区二区三区欧美| 亚洲欧美日韩中文视频| 久久米奇亚洲| 亚洲久色影视| 久久精品国产免费看久久精品| 亚洲欧美日韩综合aⅴ视频| 久久av二区| 欧美三级免费| 亚洲国产婷婷综合在线精品 | 亚洲午夜视频在线观看| 性18欧美另类| 欧美日本免费| 亚洲国产精品一区二区久| 亚洲一区二区成人在线观看| 美国成人直播| 亚洲欧美电影在线观看| 欧美成人69av| 91久久在线视频| 麻豆91精品| 亚洲一区二区免费在线| 欧美日韩激情小视频| 亚洲精品美女在线观看| 亚洲香蕉伊综合在人在线视看| 亚洲欧美中文字幕| 亚洲美女福利视频网站| 欧美激情一级片一区二区| 久久黄金**| 欧美日韩在线一区二区三区| 亚洲高清免费在线| 久久综合网色—综合色88| 亚洲欧美区自拍先锋| 国产精品亚洲综合色区韩国| 一本色道久久综合亚洲精品不卡| 亚洲国产日日夜夜| 麻豆av福利av久久av| 最近看过的日韩成人| 在线欧美三区| 欧美激情区在线播放| 欧美v国产在线一区二区三区| 亚洲激情六月丁香| 亚洲国产精品久久久久婷婷老年 | 欧美激情在线狂野欧美精品| 久热精品视频在线| 亚洲婷婷在线| 久久综合电影| 亚洲男人影院| 蜜桃精品久久久久久久免费影院| 亚洲精品久久久久久久久久久| aa亚洲婷婷| 日韩亚洲一区二区| 欧美亚洲视频| 亚洲一区二区视频在线| 亚洲午夜av| 国产日韩欧美中文| 亚洲视屏一区| 一本一本大道香蕉久在线精品| 欧美亚洲在线| 久久aⅴ国产欧美74aaa| 欧美日韩中文字幕综合视频 | 亚洲风情在线资源站| 亚洲资源av| 小嫩嫩精品导航| 欧美视频在线观看 亚洲欧| 免费在线观看一区二区| 国产亚洲精品一区二555| 亚洲一二三四久久| 一区二区三区四区五区视频| 美女精品在线观看| 亚洲精品免费一二三区|