XMPP客戶端登錄開發詳解

jopen 8年前發布 | 16K 次閱讀 XMPP iOS開發

由上篇文章將了如何在MAC本地搭建一個Openfire服務器,今天我們就要著手使用 XMPPFramework來開發 基于XMPP 協議的即時通訊IOS 客戶端系統。今天主要看登錄功能開發,可能有人會質疑,我們都沒有開發注冊功能,怎么開發登錄功能。注冊賬號我們有捷徑,服務器都在本地,當然很好做了。另外就是通過MAC 自帶的客戶端 Messages 進行注冊。

首先,我們需要搭建起來IOS 的工程,并且將XMPPFramework 引入到我們的工程中來,當然我們可以使用源碼 直接導入,也可以使用cocoapods來進行依賴。本文直接使用源碼來進行開發。由于在Github上的源碼有一些問題,所以大家可以來 https://github.com/TerryLMay/TMXMPPClient/tree/master/TMXMPPClient/ThirdTools/XMPPFrameworkio 下載相關的XMPPFramework相關的代碼。

下載關于XMPPFramework的代碼之后,我們需要做的是 創建一個工程,然后將源代碼導入到我們的工程中去。當然直接導入并且編譯會出現libxml找不到的問題。我們需要在工程中導入libxml2.tbd(ios 9之后的名稱) 以及 libresolv.9.tbd(ios 9之后的后綴)。然后在Build Setting的Head search 中加上 頭文件的鏈接地址

${SDKROOT}/usr/include/libxml2

這之后,重新編譯工程即可編譯成功。后面,我們需要做的就是開發登錄功能了,在開始之前,我們還是先看一下怎么注冊一個賬號吧;登錄Openfire后臺,創建一個用戶。

通過在瀏覽器中輸入 (前提 是 openfire服務器以及mysql服務器都已經啟動了)

127.0.0.1:9090     

進入如下界面

XMPP客戶端登錄開發詳解

點擊左上角用戶/組 進入用戶管理界面

XMPP客戶端登錄開發詳解

然后點擊 左側 導航欄中的新建用戶 填寫好用戶信息就可以了。

XMPP客戶端登錄開發詳解

到這邊基本上用戶注冊環節 已經結束了。

開發 登錄功能,基本上包括 登錄界面的開發、XMPP登錄邏輯的開發。登錄界面我們可以 隨便搭建一個登錄界面就可以了。我今天主要是說一下 XMPP登錄部分。

首先,創建關于XMPPLoginManager類,實現XMPPStreamDelegate,我定義了自己的一個宏,表示使用的Openfire服務器的地址 以及 端口號

#define LocalOpenfire 1

if LocalOpenfire

define HOST_NAME @"127.0.0.1"

define HOST_PORT 5222

define CONNECT_IDENTIFIER @"@"

endif

define TIME_OUT 20</code></pre>

然后 定義XMPPStream、XMPPReconnect實例,并且初始化

- (void)initXMPPStream {
    self.loginXmppStream = [[XMPPStream alloc] init];
    [self.loginXmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
}

  • (void)initXMPPReconnect { self.loginReconnectManager = [[XMPPReconnect alloc] init]; [self.loginReconnectManager activate:self.loginXmppStream]; // You can also optionally add delegates to the module. [self.loginReconnectManager addDelegate:self delegateQueue:dispatch_get_main_queue()]; }</code></pre>

    定義 Login按鈕點擊之后的點擊事件調用 XMPPLoginManager中的如下方法進行連接:

    #pragma mark -- connect xmpp method for login viewController

  • (void)connectXMPPServer:(NSString )userName password:(NSString )password { self.userName = userName; self.password = password;

    NSString *myJid = [NSString stringWithFormat:@"%@%@%@", userName, CONNECT_IDENTIFIER, HOST_NAME]; self.loginXmppStream.myJID = [XMPPJID jidWithString:myJid];

    self.loginXmppStream.hostName = HOST_NAME; self.loginXmppStream.hostPort = HOST_PORT;

    NSError *connectError = nil; [self.loginXmppStream connectWithTimeout:TIME_OUT error:&connectError];

    if (connectError) {

      NSLog(@"%@", connectError);
      [self.loginDelegate loginXMPPConnectError:connectError];
    

    } }</code></pre>

    后面就是處理XMPPStream的各種回調就可以了

    #pragma mark -- xmppstream delegate
    //連接xmpp成功之后,使用密碼認證

  • (void)xmppStreamDidConnect:(XMPPStream *)sender {

    NSError *authError = nil; [self.loginXmppStream authenticateWithPassword:self.password error:&authError];

    if (authError) {

      NSLog(@"%@", authError);
      [self.loginDelegate loginXMPPDidNotAuthenticate];
    

    } }

//認證通過之后的處理

  • (void)xmppStreamDidAuthenticate:(XMPPStream *)sender { NSLog(@"%@", @"認證通過"); [self.loginDelegate loginXMPPDidAuthenticate]; }

//連接服務器的超時處理

  • (void)xmppStreamConnectDidTimeout:(XMPPStream *)sender { NSLog(@"連接超時"); [self.loginDelegate loginXMPPConnectDidTimeout]; }

//認證沒有通過處理

  • (void)xmppStream:(XMPPStream )sender didNotAuthenticate:(DDXMLElement )error { NSLog(@"認證失敗"); [self.loginDelegate loginXMPPDidNotAuthenticate]; }</code></pre>

    基本上這樣就可以登錄了,登錄成功之后,可以跳轉到相應的界面。提一下我們 能看到的XMPP交互流程 包括:

    1、XMPP 使用用戶名去連接服務器;

    2、XMPP 連接成功之后,通過密碼去服務器認證

    3、認證成功之后,處理自己想處理的一下事情。

    但其實XMPP 報文交互包括好幾步,我就從別人那邊摘錄一點交互細節過來,就不自己一個個的抓包看了。

    C1: 客戶端初始化流給服務器

<stream:stream to="127.0.0.1" xmlns="jabber:client" xmlns:stream="

S2: 發送 STARTTLS范圍

<stream:features> <starttls xmlns="urn:ietf:params:xml:ns: xmpp-tls"></starttls> <mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"> <mechanism>PLAIN</mechanism> <mechanism>CRAM-MD5</mechanism> <mechanism>ANONYMOUS</mechanism> <mechanism>DIGEST-MD5</mechanism> <mechanism>JIVE-SHAREDSECRET</mechanism> </mechanisms> <compression xmlns="; <method>zlib</method> </compression> <auth xmlns="; <register xmlns="; </stream:features>

C2:客戶端發送 STARTTLS 命令給服務器:

<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>

S3:服務器通知客戶端可以繼續進行:

<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>

C3:TLS 握手成功, 客戶端初始化一個新的流給服務器

<stream:stream to="192.168.1.185" xmlns="jabber:client" xmlns:stream="

S4:服務器通知客戶端可用的驗證機制:

<?xml version='1.0' encoding='UTF-8'?> <stream:stream xmlns:stream="; <register xmlns="; </stream:features>

C4: 客戶端選擇一個驗證機制:

<auth mechanism="DIGEST-MD5" xmlns="urn:ietf:params:xml:ns:xmpp-sasl"></auth>

S5:服務器發送一個 [BASE64] 編碼的挑戰給客戶端:

<challenge xmlns="urn:ietf:params:xml:ns:xmpp-sasl">cmVhbG09IjE5Mi4xNjguMS4xODUiLG5vbmNlPSJlcEJaZlBxU1p0WGlLYzBqdGpwT0I1a01HMHdiY0hsUmNhOE52ZE9SIixxb3A9ImF1dGgiLGNoYXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1kNS1zZXNz</challenge> C5:客戶端發送一個[BASE64]編碼的回應這個挑戰: <response xmlns="urn:ietf:params:xml:ns:xmpp-sasl">Y2hhcnNldD11dGYtOCx1c2VybmFtZT0iYWRtaW4iLHJlYWxtPSIxOTIuMTY4LjEuMTg1Iixub25jZT0iZXBCWmZQcVNadFhpS2MwanRqcE9CNWtNRzB3YmNIbFJjYThOdmRPUiIsbmM9MDAwMDAwMDEsY25vbmNlPSJMNDJ1SE1XK2piemh6N1hzdWRndHN1V1VIT2hNZmFLVUJpcU5iR1p2IixkaWdlc3QtdXJpPSJ4bXBwLzE5Mi4xNjguMS4xODUiLG1heGJ1Zj02NTUzNixyZXNwb25zZT1hN2JhMWZlOThiMDc2ZjUzZWUzNTczM2Q5NDMwODJlYSxxb3A9YXV0aCxhdXRoemlkPSJhZG1pbiI=</response>

S6:服務器通知客戶端驗證成功

<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl">cnNwYXV0aD0yNDZlZDcyOTQ3ZjVhYzFiNWQ2ZDc4ZTkxM2QzMmFjMQ==</success>

C6客戶端初始化一個新流給服務器:

<stream:stream to="192.168.1.185" xmlns="jabber:client" xmlns:stream=" 基本上XMPP的登錄細節就已經清楚了。后面我們看一下 注冊相關的模塊 以及 聯系人請求模塊的開發。如果想獲取源碼的話,請轉到 https://github.com/TerryLMay/TMXMPPClient/tree/master/TMXMPPClient

本文作者:Terry 專注于技術開發;打滾于IOS 技術領域,偶爾也會邁出腳步探索其他領域
地址:http://www.terrylmay.com/terrylmay.github.io/2016/01/31/XMPP%E5%AE%A2%E6%88%B7%E7%AB%AF%E7%99%BB%E5%BD%95%E5%BC%80%E5%8F%91%E8%AF%A6%E8%A7%A3/
</div>

來自: http://www.superqq.com/blog/2016/01/31/xmpp-client-login-dev/

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!