本篇文章翻译XMPP Framework中的Overview of the XMPP Framework部分 css
The framework is divided into 2 parts:
1. xmpp核心部分
2. xmpp扩展(roster,XEP's,可选的支持工具等)html
xmpp核心部分实现了xmpp规范(RFC 3920)git
请不要把聊天与xmpp混淆,xmpp全称是”可扩展消息与存在协议”,它是一种能够用于多种用途的通用协议,事实上目前有不少公司使用这个框架例如家庭自动化,在医院传达警报给护士。github
可扩展包括例如支持花名册,自动重连与多种xmpp扩展实现(XEP's).。objective-c
XMPP核心文件在本地命名为”Core”的文件夹中。这些文件包括:数据库
这个框架的核心是XMPPStream
类,这是你将要交互使用的主要的类,它是全部的扩展与定义代码插入的类,它具备一些使框架灵活,可扩展,易于在上面开发有趣的功能。这些将在稍后的文档中更深刻的讨论。安全
XMPPParser 是XMPPStream使用的内部类。你也许已经猜出它是作什么的了,你不须要以任何方式形式与这个解析器交互。服务器
XMPPJID 提供了一个不变的JID (Jabber Identifier)实现,它支持解析JID's,并以各类形式提取JID的各个部分。它遵照NSCopying协议,一边JID's能够当作NSDictionary的key。它也遵照NSCoding协议。markdown
XMPPElement 是3个主要XMPP元素的基类:XMPPIQ, XMPPMessage & XMPPPresence. XMPPElement扩展NSXMLElement类,所以你有所有的NSXML的功能,检查任何xml元素。在这个章节有更多详细的描述Elements: IQ, Message, & Presence。网络
XMPPModule 提供可选植入扩展的基础类,若是你正在写你本身应用执行的代码。你极可能仅仅建立你本身的类,注册接受代理调用。可是若是你正在实现一个标准的XEP。或者你想你的应用指定扩展是可被植入,那么你要在XMPPModule上建立,Module在后面更详细的被介绍。
XMPPLogging 提供一个很是快,强大灵活的日志框架,它会在XMPP Logging 章节中讨论。
XMPPInternal 仅仅是关于核心和各类高级底层扩展内部的东西。
XMPPElement扩展NSXMLElement类,所以你有所有的NSXML的功能,检查任何xml元素。
除了NSXML基础功能外,还提供了NSXMLElement+XMPP 类别。这个类别提供各类方便的方法让你的代码更简洁易读。例如:
[element attributeIntValueForName:@"age"];
更多的信息请看Working With Elements页面
一个xmpp stream配置初始化被分为多个部分:
对于大部分人来讲,这仅涉及一个步骤 - 设置stream的myJID属性。例如:
xmppStream.myJID = [XMPPJID jidWithString:@"user@gmail.com"];
该xmpp stream 将查找遵循XMPP RFC的剩余信息,这包括正在进行的SRV查找_xmpp-client._tcp.domain。在上面的例子中,使用Gmail,谷歌服务器可能会返回相似"talk.google.com",而后xmpp stream将会连接到该服务器,若是SRV查找查找失败,那么xmpp stream 将会简单连接到JID's domain。
若是你知道你正在链接到不具备xmpp SRV记录的xmpp服务器,你能够告诉xmpp stream 经过指定的主机名跳过SRV查找,例如:
xmppStream.myJID = [XMPPJID jidWithString:@"user@myCompany.com"];
xmppStream.hostName = @"myCompany.com";
主机名也会派上用场,当你使用一个开发xmpp服务器,可能服务器是在背地网络可用的,或者不具备DNS地址等,例如:
xmppStream.myJID = [XMPPJID jidWithString:@"user@dev1.myCompany.com"];
xmppStream.hostName = @"192.168.2.27";
另外一个可选的属性是主机端口,默认状况下,并按照xmpp规范。几乎全部的服务器上的端口都在5222运行,若是你的服务器在不一样的端口上运行,那能够设置主机端口的属性。
XMPPStream有一些旨在使框架灵活,可扩展,易于在上面开发有趣的功能。其中之一使用MulticastDelegate。
什么是MulticastDelegate?
xmpp framework须要支持扩展的数量不受限制,这包括对这个框架的官方扩展,以及任何数量的扩展或你想要插入这个框架的自定义代码。所以传统的代理模式是行不通的,xmpp 模块和扩展须要分开到本身单独的类,但每一个类都须要接受代理方法。而标准NSNotification架构将没法胜任,一些代理要求返回变量。(加上它真的很烦人要从userInfo字典的通知中提取参数)。
所以一个MulticastDelegate容许你使用一个标准的代理模式插入框架中,但它容许多个类接受想用的代理通知。这样作的好处是,你没必要把全部的xmpp处理代码在一个类中。你能够认为你合适的方法分开处理在不一样的类中。
你能够任什么时候间添加/删除XMPPStream的代理对象:
[xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
...
[xmppStream removeDelegate:self];
更多关于MulticastDelegate的讨论能够在这里找到。线程和队列更详细的讨论能够在这里找到。
这有一些关于这个框架的扩展,固然,你能够如你所愿写尽量多的扩展。咱们不会检查全部可用的扩展,但咱们会列出几个在这里示例。
做为例子,咱们将会插入XMPPReconnect模块在咱们的stream:
xmppReconnect = [ [XMPPReconnect alloc] init];
// Optional configuration of xmppReconnect could go here.
// The defaults are fine for our purposes.
[xmppReconnect activate:xmppStream];
// You can also optionally add delegates to the module.
[xmppReconnect addDelegate:self delegateQueue:dispatch_get_main_queue()];
// And that's all that is needed.
// The module will receive any delegate methods it needs automatically
// from the xmpp stream, and will continue to do its thing unless you deactivate it.
当你准备好,你能够开始链接进程:
NSError *error = nil;
if (![xmppStream connect:&error])
{
NSLog(@"Oops, I probably forgot something: %@", error);
}
若是你忘记设置必需的属性,例如myJID,那么connect方法会返回NO,错误消息会通知你的问题。
在链接过程当中,客户端和服务器通过一个xmpp握手。在此期间,服务器通知各类它支持以及须要的各类协议给客户端。有些服务器可能须要链接经过SSL/TLS。若是是这样的状况下,xmpp stream将自动保护链接,若是你正在链接服务器以不正确X509证书,你可能须要实现xmppStream:willSecureWithSettings: 代理方法来改变默认的安全设置。
全部的链接握手结束后xmppStreamDidConnect: 代理方法被调用。这一般是大多数客户端应启动验证过程:
- (void)xmppStreamDidConnect:(XMPPStream *)sender { [xmppStream authenticateWithPassword:password error:NULL]; }
这有几个目标对于整个XMPP架构日志:
它必须支持多种日志级别.
不是全部的日志消息具备相同的优先级。有些是有关错误的,而其余都只是信息。日志分级帮助开发者保证他们的日志信息完整的,可以打开和关闭他们没有任何困难。
它必须在每一个文件基础上可配置
一个全局日志级别不会接受当这个框架包含了这么多文件。加上调试的问题每每开发者只但愿看到几个文件的日志语句。
它必须可配置于终端用户
xmpp framework 须要对日志语句彻底控制,用户有不少不一样的需求。一些想要日志声明到一个文件中,一些可能想要日志声明到数据库里。或者可能他们须要针对日志声明在不一样的地方,取决于日志声明来源于app中仍是xmpp framework。
我从事客户端多年来的工做,我看到第三方框架一遍又一遍发生一样的问题。第三方库自带散落着的NSLog语句,最终须要用户经过库注释掉NSLog语句,或者将它们转换为一些原始的自定义宏的版本。
xmpp framework 采用了专业的日志框架CocoaLumberjack。这个日志框架实际上比的NSLog更快,作一样的事情时也是如此。此外,它还支持大量不一样的配置,并容许终端用户甚至能够添加本身的自定义日志记录,筛选和格式化。
下面是你须要知道的XMPPFramework有关日志的设置:
对于在框架内部大多数文件顶部你会发现以下:
// Log levels: off, error, warn, info, verbose
static const int xmppLogLevel = XMPP_LOG_LEVEL_WARN;
如你所见有4个日志级别(加上 XMPP_LOG_LEVEL_NONE):
您能够更改任何文件的日志级别,要它输出更多的信息。
除了这一点,可启用一个跟踪标记。当启用跟踪,它输出正在调用的方法。
请注意,跟踪是从日志等级分开的。例如,一个能够设置日志级别设置为警告,并启用跟踪像这样:
// Log levels: off, error, warn, info, verbose
static const int xmppLogLevel = XMPP_LOG_LEVEL_WARN | XMPP_LOG_FLAG_TRACE;
就代码而言意味着:
XMPPLogTrace(); // Enabled - Will spit out "<FileName>: <MethodName>"
XMPPLogError(@"I will get logged");
XMPPLogWarn(@"I will get logged");
XMPPLogInfo(@"I will NOT get logged");
XMPPLogVerbose(@"I will NOT get logged");
除此以外,XMPPStream有一个选项使你可以看到正在发送的原始XML sent/received。你能够把它放在XMPPStream.m像这样:
// Log levels: off, error, warn, info, verbose
static const int xmppLogLevel = XMPP_LOG_LEVEL_INFO | XMPP_LOG_FLAG_SEND_RECV;
当你启动应用程序,您须要配置lumberjack框架。对于初学者来讲,你能够这样简单的设置在你的AppDelegate:
#import "DDLog.h"
#import "DDTTYLogger.h"
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[DDLog addLogger:[DDTTYLogger sharedInstance] withLogLevel:XMPP_LOG_FLAG_SEND_RECV];
// All your other code...
}
更多关于Lumberjack信息参考这里。
For more information about Lumberjack take a look at its project page.
想要马上开始?
扩展你的知识!