李洪强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 框架,一旦你使用了,你将离不开它 :) 
相关文章
相关标签/搜索