李洪強iOS開發之XMPP

XMPP歷史git

這個xmpp框架在2008年開始,不過是一個簡單地RFC實現。提供一個最小的代理去接受三種xmpp的基本類型presence、message、iq。由於framwork只提供了最小的功能實現,它須要第三方的開發者提供許多拓展的代碼。然而,大多數應用使用xmpp須要一些xmpp 拓展 如rosters,capabilities 或者其餘的的拓展http://xmpp.org/xmpp-protocols/xmpp-extensions/

很是清楚地,工程須要實現更多的經常使用的xmpp功能。Roster 支持被添加和一些其餘的XEP。早期版本的XEP,拓展是各自開發的,整合你們開發的拓展簡直是一個噩夢,並且大部分的拓展並非必須的,這個時候開發者們以爲保持簡單、可通用的拓展是必需要的。

因此第二個版本的工程作成了模塊化,工程被分離成一個模塊化的系統,以及一個包含多個拓展的文件夾。開發者能夠簡單地添加他們須要的功能,也讓第三方開發者更加容易提交工程。

第三個版本基於核心線程安全,繼續使用模塊化的代碼,更加容易放置多個模塊。同時第三方開發者已經成長爲了一個開發者社區,不只僅可以添加模板,還包括修復bug、提供技術支持、測試、文檔、建議以及鼓勵等。

介紹
xmpp框架分紅兩部分github

  1. xmpp core
  2. 拓展 XEP

XMPPCore 的類數據庫

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

XMPPStream
XMPPStream是xmpp的核心,這是你須要接觸的主要類,全部的拓展類和定製類須要添加它,它由一些有趣的功能設計,讓框架靈活、可拓展和更加容易在它之上開發

XMPPParser 是XMPPStream 使用的一個類,你通常不須要和它打交道

XMPPJID 提供多個JID(Jabber Identifier) 實現,支持解析JID,並解析JID的多種格式,它實現了NSCopying代理,所以JID能夠被用做NSDictionary的key。它也實現了NSCoding協議。

XMPPElement 是基本的類,用於三種主要的XMPP 元素 XMPPID,XMPPMessage 和XMPPPresence。 XMPPElement 繼承自NSXMLElement

XMPPMddule 提供可選的附加拓展功能,若是你作應用,你可能建立你本身的類,註冊和接受代理。然而,若是你正在實現基本的XEP或者你想要添加特定拓展,你須要建立頂層的XMPPModule。

XMPPLoging 提供一個很是快速、高效、靈活的登陸框架,以後將詳細講到

XMPPInternal 僅僅是一和core和多個拓展有關的個網絡素材

素材:IQ、Message、Presencexcode

繼承關係安全

  • XMPPIQ -> XMPPElement -> NSXMLElement -> NSXMLNode -> NSObject
  • XMPPMessage -> XMPPElement-> NSXMLElement -> NSXMLNode -> NSObject
  • XMPPPresence -> XMPPElement -> NSXMLElement -> NSXMLNode -> NSObjec

NSXML 有一個NSXMLElement+XMPP拓展,這個拓展提供了多個轉換方法讓你的代碼更加簡潔可服務器

  1. [element attributeIntValueForName:@"age"];  

更多你能夠查看  https://github.com/robbiehanson/XMPPFramework/wiki/WorkingWithElements

XMPPStream 配置

 


配置能夠被分紅多個部分網絡

  • 配置如何鏈接xmpp服務器
  • 添加代理
  • 添加模塊
  • 鏈接
  • 校驗
  1. 設置stream的myJID屬性  
  2. xmppStream.myJID = [XMPPJID jidWithString:@"user@gmail.com"];  

 

xmpp stream 會根據XMPP RFC自動最優配置,包括SRV搜索 _xmpp-client._tcp.doman.在以上的例子,使用gmail,谷歌服務器通常返回像這樣的字段"talk.googe.com" xmpp stream 將會鏈接服務器,若是SRV搜索失敗,xmpp stream會簡單地鏈接到JID的doman

若是你知道你鏈接到一個xmpp server,而且這個server沒有SRV記錄,你可以告訴xmpp stream 跳過SRV搜索,以下app

  1. xmppStream.myJID = [XMPPJID jidWithString:@"user@myCompany.com"];  
  2. xmppStream.hostName = @"myCompany.com";  

當你使用一個開發xmpp 服務器,hostname 一樣能夠找到,服務器可能僅僅在本地網絡可用,沒有dns 地址,你能夠這樣作
 
  1. xmppStream.myJID = [XMPPJID jidWithString:@"user@dev1.myCompany.com"];  
  2. xmppStream.hostName = @"192.168.2.27";  

另外一個可選的屬性是端口,默認端口是5222,若是你的服務器端口不同,你須要設置hostPort屬性


添加代理

 


MulticastDelegate介紹
xmpp框架須要支持一個不限制個數的拓展,包括官方的拓展、以及你但願添加到框架中的拓展。因此普通的代理模式不會起做用。XMPP模塊和拓展須要被分開到不一樣的類中,然而每個類都須要接受代理的回調,而基本的NSNotifaciton不能知足要求,應爲一些代理須要返回一個值。

所以MulticastDelegate 容許你使用基本的代理,同時也容許多個類接受相同的代理通知。這樣設計妙在: 你不須要把全部的xmpp 句柄代碼放在單個類中,你可以根據功能把分開放。框架

 
  1. 添加和移除XMPPStream delegate  
  2. [xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];  
  3. ...  
  4. [xmppStream removeDelegate:self];  

添加modules
xmpp框架自帶了一些拓展,固然你也能夠寫你但願的拓展,咱們不會review任何可用的拓展,但咱們會列一些例子

 

XMPPReconnect     意外斷開會自動重連
XMPPRoster            提供基本的roster名冊
XMPPRoom             提供多用戶聊天支持
XMPPPubSub         公開subscribe
以下:less

 
  1. xmppReconnect = [ [XMPPReconnect alloc] init];  
  2.   
  3. // Optional configuration of xmppReconnect could go here.  
  4. // The defaults are fine for our purposes.  
  5.   
  6. [xmppReconnect activate:xmppStream];  
  7.   
  8. // You can also optionally add delegates to the module.  
  9.   
  10. [xmppReconnect addDelegate:self delegateQueue:dispatch_get_main_queue()];  
  11.   
  12. // And that's all that is needed.  
  13. // The module will receive any delegate methods it needs automatically  
  14. // from the xmpp stream, and will continue to do its thing unless you deactivate it.  

鏈接
若是你準備好了,咱們開始鏈接
 
  1. NSError *error = nil;  
  2. if (![xmppStream connect:&error])  
  3. {  
  4.     NSLog(@"Oops, I probably forgot something: %@", error);  
  5. }  

若是你忘記了設置必須的屬性,如myJID,鏈接方法會返回NO,error message裏面會有詳細信息

在鏈接過程當中,客戶端和服務端完成一個xmpp 握手,服務器提示客戶端,可用的它支持的或者必須的代理。一些服務器可能須要安全鏈接經過SSL。/TLS. 這種狀況,會自動創建安全鏈接。若是你鏈接到服務器使用一個不正確的X509證書,你須要實現xmppStream:willSecureWithSettings: 代理方法去頂默認的安全設置

確認
在握手鍊接已經完成後, xmppStreamDidConnect:delegate 方法被激發,這個時候大部分的客戶端須要開始確認過程以下
 
  1. - (void)xmppStreamDidConnect:(XMPPStream *)sender  
  2. {  
  3.     [xmppStream authenticateWithPassword:password error:NULL];  
  4. }  


XMPP logging
xmpp的log有幾個目標

 

1. 支持多級別的log

不是全部log信息有相同的優先級別,如error 這樣的,當其餘的僅僅是information。級別幫助開發者保持log信息完整,以及方便的開關log的能力

 

2. 必須可在一個文件中可配置。當frame包含不少文件,一個全局level 的log不會切。添加debug 一個時間一般意味着開發者僅想在少許文件裏看到log的狀態


3. 必須可在終端用戶配置
xmpp framework的使用者須要根據log報告全局掌控發生了什麼。用於有不一樣的需求,一些想要log報告寫到文件中,其餘的可能想要log報告寫到數據庫,或者放到不一樣的位置基於log報告是來自應用仍是來自xmpp framwork。
我開發了不少客戶端,我看見不少鏈接第三方框架一次又一次地出現相同的問題。第三方庫散亂的log語句。須要用戶註釋掉NSLog 語句,或者經過宏定義轉化

因此與其被笨笨的NSLog戰勝,xmpp framework 使用了一個專業的log 框架CocoaLumberjack 
這個log框架事實上有時候作一樣的事比NSLog 快。同時它還支持不一樣搞得配置,容許用戶添加本身的log語句,添加其餘的格式。

下面你須要知道如何把log  鏈接到XMPPFramework
框架中大部分文件你可以發現如下的兩行

 
  1. // Log levels: off, error, warn, info, verbose  
  2. static const int xmppLogLevel = XMPP_LOG_LEVEL_WARN;  

你能夠看到,有四個級別的log

 

  • Error
  • Warning
  • Info
  • Verbose

你能夠更改任何文件的 log 級別,讓它打印出更多的信息

這裏有個標記可以被設置,當tracing 是YES,打印被調用的方法

請注意tracing 是被和 log levels 分開的,如能夠設置log等級爲warning,同時容許標記以下

 
  1. // Log levels: off, error, warn, info, verbose  
  2. static const int xmppLogLevel = XMPP_LOG_LEVEL_WARN | XMPP_LOG_FLAG_TRACE;  

在代碼中,意味着
  1. XMPPLogTrace(); // Enabled - Will spit out "<FileName>: <MethodName>"  
  2. XMPPLogError(@"I will get logged");  
  3. XMPPLogWarn(@"I will get logged");  
  4. XMPPLogInfo(@"I will NOT get logged");  
  5. XMPPLogVerbose(@"I will NOT get logged");  

xmppStream 有個選項,讓你能夠看見要發送和接受的 xml ,你可以把它轉成XMPPStream以下
// Log levels: off, error, warn, info, verbose
static const int xmppLogLevel = XMPP_LOG_LEVEL_INFO | XMPP_LOG_FLAG_SEND_RECV;

log 的目標是讓你控制和獲得log 語句執行到哪裏了,這意味着你須要配置lumberjack框架當你的程序啓動了,爲了啓動,你可以在appdelegate 作些事情
  1. #import "DDLog.h"  
  2. #import "DDTTYLogger.h"  
  3.   
  4. - (void)applicationDidFinishLaunching:(NSNotification *)aNotification  
  5. {  
  6.     [DDLog addLogger:[DDTTYLogger sharedInstance] withLogLevel:XMPP_LOG_FLAG_SEND_RECV];  
  7.   
  8.     // All your other code...  
  9. }  

更多關於 CocoaLumberJack 消息你可以在它的工程頁面中查看  CocoaLumberJack gitHub頁。 我很是樂意看到你在本身的應用中使用專業的logging 框架,一旦你使用了,你將離不開它 :) 
相關文章
相關標籤/搜索