簡要解析XMPP框架及iOS-Objective-C的使用

前言:這兩天看了XMPP框架,查閱了一些資料,寫下這篇文章記錄一下學習筆記node

 

 

1、簡要解析XMPP核心部分  mysql

XMPP框架分爲兩個部分git

    1.核心部分github

    2.擴展部分 sql

擴展部分主要講好友列表(roster)、自動重連(automatic reconnect)、還有一些其餘的實現。數據庫

核心部分包括如下部分:服務器

  • XMPPStream
  • XMPPParser
  • XMPPJID
  • XMPPElement
  • XMPPIQ
  • XMPPMessage
  • XMPPPresence
  • XMPPModule
  • XMPPLogging
  • XMPPInternal

1.XMPPStream網絡

XMPPStream類至關於輸入輸出流,用於鏈接服務器併發送消息。併發

XMPPStream添加和移除代理寫了方法框架

1 - (void)addDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue;
2 - (void)removeDelegate:(id)delegate delegateQueue:(dispatch_queue_t)delegateQueue;
3 - (void)removeDelegate:(id)delegate;

 

XMPP底層就是socket,因此XMPPStream實現了socket協議<GCDAsyncSocketDelegate>

初始化方法

- (id)init
{
    if ((self = [super init]))
    {
        // Common initialization
        [self commonInit];
        
        // Initialize socket
        asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:xmppQueue];
    }
    return self;
}

XMPPStream包含的一些屬性

/** Jabber ID 用於表示用戶身份的地址 */
@property (readwrite, copy) XMPPJID *myJID;

/** 要鏈接的服務器的域名 格式爲talk.google.com  */
@property (readwrite, copy) NSString *hostName;
/** 要鏈接的服務器的端口號 默認爲5222*/
@property (readwrite, assign) UInt16 hostPort;

 

2.XMPPParser

XMPPParser,是XMPPStream的解析器,解析傳遞的信息

 

3.XMPPJID

在XMPP協議中表示一個地址,由如下三個部分組成

  node/username:表示一個向服務器或網關和使用網絡服務的實體(節點、用戶名,用戶的基本標識)

  domain:表示網絡中的網關或者服務器(例如一個JID,username@domain/resource,domian即後面的域名)

  resource:表示一個特定的回話(或者某個設備),鏈接(或地址),或者一個附屬於某個節點ID實體相關的實體對象(或者多人聊天室中的參與者),可用於區分用戶的設備等

還有定義的其餘屬性,

  Bare:就是node+domain,username@domain,即JID除去resource

  Full:一個完整的JID,包含username,domain,resource,比Bare多了resource

 

XMPPJID源碼的一個枚舉,看數字和,很好理解

enum XMPPJIDCompareOptions
{
    XMPPJIDCompareUser     = 1, // 001
    XMPPJIDCompareDomain   = 2, // 010
    XMPPJIDCompareResource = 4, // 100
    
    XMPPJIDCompareBare     = 3, // 011
    XMPPJIDCompareFull     = 7, // 111
};

XMPPJID使用瞭解檔,歸檔,遵照了<NSCoding, NSCopying>協議

 

4.XMPPElement

XMPPElement是3個基本元素(IQ,Message,Presence)的基類

繼承自NSXMLElement

配合分類NSXMLElement+XMPP使用可讓代碼更簡潔和提升可讀性

 

5.XMPPIQ

請求

主要屬性是type(Message和Presence同樣,表示請求或者消息的類型)

<iq Type="result"
from="lightman@google.com/contact" 
to="google.com"
id
= '123456'>
<query xmins="jabber:iq:roster"/>
<iq/>

type屬性:說明了該iq類型爲get,像服務端請求信息

from屬性:當心來源,=JID

to屬性:消息目標,=服務器域名

id屬性,可選,標記該請求ID,當服務器處理完畢請求get類型的iq後,響應的result類型iq和ID與請求iq的ID相同

 

6.Message

<message />節定義了消息語義,<message />節可被看做「推」機制,與Email系統中發生的通訊相似。全部消息節應該擁有‘to’屬性,指定有意的消息接收者

message用於「發送後即忘」的傳輸(發送後不驗證消息是否接收成功),這樣的傳輸主要應用與人類可讀的文本、警告、通知等信息。

 

<message to="lightman@google.com/contact" 
    type="chat">
    <body>
        hello
    < body/>
<meesage/>

 

 

7.Presence

<presence from="">
    <show>顯示的內容<show/>
    <status>顯示的狀態<status/>
<presence/>

presence的狀態

available上線

away離開

do not disturb忙碌

unavailable 下線

 

 

 

2、導入XMPP框架

XMPP在github-wiki上說明的步驟過時了

可是給出了指向stack flow回答的鏈接

http://stackoverflow.com/questions/9091767/up-to-date-instructions-on-how-to-install-xmppframework-manually/30543948#30543948

 

步驟1

必須導入Xcode的文件夾

  • Vendor/CocoaAsyncSocket
  • Vendor/CocoaLumberjack
  • Vendor/KissXML
  • Vendor/libidn
  • Authentication
  • Categories
  • Core
  • Utilities

也能夠導入Extensions,可選

導入的時候要選擇複製進項目中

enter image description here

 

步驟2

導入頭文件XMPPFramework.h,也要賦值選項

導入完的框架

enter image description here

 

步驟3

要導入如下的自帶框架和庫

  • CFNetwork.framework
  • Security.framework
  • libxml2.dylib
  • libresolv.dylib
  • libidn.a

 

注意,在項目Xcode8以後的Xcode9 庫的dylib後綴名改成thd,可能要從新導入

 

步驟4

Build Settings中要添加

other linker flags = -lxml2 

HEADER SEARCH PATHS = /usr/include/libxml2 

 

注意最後還要導入<UIKit/UIkit.h>

 

3、簡要使用XMPP框架

這裏省略配置服務器(用的是openfire)和數據庫(mysql)步驟,網上不少教程

 

步驟1 鏈接服務器

- (void)connect {
  // 建立XMPPStream if (self.xmppStream == nil) { self.xmppStream = [[XMPPStream alloc] init]; [self.xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()]; }
  //設置JID 而後使用XMPPStream鏈接服務器 if (![self.xmppStream isConnected]) { NSString *username = [[NSUserDefaults standardUserDefaults] objectForKey:@"username"]; XMPPJID *jid = [XMPPJID jidWithUser:username domain:@"lizhen" resource:@"Ework"]; [self.xmppStream setMyJID:jid]; [self.xmppStream setHostName:@"10.4.125.113"]; NSError *error = nil; if (![self.xmppStream connect:
&error]) { NSLog(@"Connect Error: %@", [[error userInfo] description]); } } }

 

鏈接成功後悔調用XMPPStreamDelegate的方法

首先會調用

- (void)xmppStream:(XMPPStream *)sender socketDidConnect:(GCDAsyncSocket *)socket

而後會調用

- (void)xmppStreamDidConnect:(XMPPStream *)sender

 

步驟2

鏈接成功後,發送密碼受權

-(void)sendPwdToHost{
    NSError *err = nil;
 //YBUserInfo是自定義數據類型,用於存儲用戶名、密碼等屬性 // 從單例裏獲取密碼
    NSString *pwd = [YBUserInfo sharedWCUserInfo].pwd;
    //使用XMPPStream發送密碼
    [_xmppStream authenticateWithPassword:pwd error:&err];
    
    if (err) {
          NSLog(@"%@",err);
    }
}

 

步驟3

受權成功後,發送消息

-(void)sendOnlineToHost{
    
    XMPPPresence *presence = [XMPPPresence presence];
    
    [_xmppStream sendElement:presence];
    
}

 

與服務器斷開鏈接會調用代理方法

-(void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error

 

受權成功會調用方法

-(void)xmppStreamDidAuthenticate:(XMPPStream *)sender

  

受權失敗會調用方法

-(void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDXMLElement *)error

  

註冊成功會調用方法

-(void)xmppStreamDidRegister:(XMPPStream *)sender

  

註冊失敗會調用方法

-(void)xmppStream:(XMPPStream *)sender didNotRegister:(DDXMLElement *)error

  

退出並斷開鏈接

- (void)disconnect {
    XMPPPresence *presence = [XMPPPresence presenceWithType:@"unavailable"];
    [self.xmppStream sendElement:presence];
      
    [self.xmppStream disconnect];
}

  

 

寫這篇博文目的是加深本身對XMPP的理解

查了一些資料,不少都是全英的,仍是要學好英語

 

 

 

 

轉載請註明出處

相關文章
相關標籤/搜索