iOS XMPP Framework 中文概述
本篇文章翻译XMPP Framework中的Overview of the XMPP Framework部分
介绍
The framework is divided into 2 parts:
1. xmpp核心部分
2. xmpp扩展(roster,XEP's,可选的支持工具等)
xmpp核心部分实现了xmpp规范(RFC 3920)
请不要把聊天与xmpp混淆,xmpp全称是”可扩展消息与存在协议”,它是一种可以用于多种用途的通用协议,事实上目前有很多公司使用这个框架例如家庭自动化,在医院传达警报给护士。
可扩展包括例如支持花名册,自动重连与多种xmpp扩展实现(XEP's).。
XMPP核心
XMPP核心文件在本地命名为”Core”的文件夹中。这些文件包括:
- XMPPStream
- XMPPParser
- XMPPJID
- XMPPElement
- XMPPIQ
- XMPPMessage
- XMPPPresence
- XMPPModule
- XMPPLogging
- XMPPInternal
这个框架的核心是XMPPStream
类,这是你将要交互使用的主要的类,它是所有的扩展与定义代码插入的类,它具有一些使框架灵活,可扩展,易于在上面开发有趣的功能。这些将在稍后的文档中更深入的讨论。
XMPPParser 是XMPPStream使用的内部类。你也许已经猜出它是做什么的了,你不需要以任何方式形式与这个解析器交互。
XMPPJID 提供了一个不变的JID (Jabber Identifier)实现,它支持解析JID's,并以各种形式提取JID的各个部分。它遵守NSCopying协议,一边JID's可以当做NSDictionary的key。它也遵守NSCoding协议。
XMPPElement 是3个主要XMPP元素的基类:XMPPIQ, XMPPMessage & XMPPPresence. XMPPElement扩展NSXMLElement类,因此你有全部的NSXML的功能,检查任何xml元素。在这个章节有更多详细的描述Elements: IQ, Message, & Presence。
XMPPModule 提供可选植入扩展的基础类,如果你正在写你自己应用执行的代码。你很可能仅仅创建你自己的类,注册接受代理调用。但是如果你正在实现一个标准的XEP。或者你想你的应用指定扩展是可被植入,那么你要在XMPPModule上创建,Module在后面更详细的被介绍。
XMPPLogging 提供一个非常快,强大灵活的日志框架,它会在XMPP Logging 章节中讨论。
XMPPInternal 仅仅是关于核心和各种高级底层扩展内部的东西。
元素: IQ, Message, & Presence
XMPPElement扩展NSXMLElement类,因此你有全部的NSXML的功能,检查任何xml元素。
- XMPPIQ -> XMPPElement -> NSXMLElement -> NSXMLNode -> NSObject
- XMPPMessage -> XMPPElement -> NSXMLElement -> NSXMLNode -> NSObject
- XMPPPresence -> XMPPElement -> NSXMLElement -> NSXMLNode -> NSObject
除了NSXML基础功能外,还提供了NSXMLElement+XMPP 类别。这个类别提供各种方便的方法让你的代码更简洁易读。例如:
[element attributeIntValueForName:@"age"];
更多的信息请看Working With Elements页面
XMPPStream配置
一个xmpp stream配置初始化被分为多个部分:
- 配置如何连接到xmpp服务器
- 添加代理
- 添加 modules
- 连接
- 认证
配置连接
对于大部分人来说,这仅涉及一个步骤 - 设置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的讨论可以在这里找到。线程和队列更详细的讨论可以在这里找到。
添加 Modules
这有一些关于这个框架的扩展,当然,你可以如你所愿写尽可能多的扩展。我们不会检查所有可用的扩展,但我们会列出几个在这里示例。
- XMPPReconnect - 自动重新连接,如果你意外断开。
- XMPPRoster - 提供标准的xmpp花名册支持
- XMPPRoom - 提供多人聊天支持.
- XMPPPubSub - 发布订阅
作为例子,我们将会插入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架构日志:
它必须支持多种日志级别.
不是所有的日志消息具有相同的优先级。有些是有关错误的,而其他都只是信息。日志分级帮助开发者保证他们的日志信息完整的,能够打开和关闭他们没有任何困难。它必须在每个文件基础上可配置
一个全局日志级别不会接受当这个框架包含了这么多文件。加上调试的问题往往开发者只希望看到几个文件的日志语句。它必须可配置于终端用户
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):
- Error
- Warning
- Info
- Verbose
您可以更改任何文件的日志级别,要它输出更多的信息。
除了这一点,可启用一个跟踪标记。当启用跟踪,它输出正在调用的方法。
请注意,跟踪是从日志等级分开的。例如,一个可以设置日志级别设置为警告,并启用跟踪像这样:
// 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.
更多信息
想要立刻开始?
扩展你的知识!
iOS XMPP Framework 中文概述的更多相关文章
- iOS XMPP 通信协议实现 图形化直观感受
第一次随笔,实在不知写点什么有用的东西,那就分享一下本人最近的研究所得吧! 是关于iOS-XMPP-通信协议的实现,具体代码比较复杂,三言两句也实在难表达清楚,网上已有很多关于iOS XMPP协议的讲 ...
- ios xmpp开发应用后台模式接收聊天信息处理方案
ios xmpp开发应用后台模式接收聊天信息 最近在使用xmppframwork来实现一个聊天应用,碰到了一个问题,应用进入后台以后,就接收不到消息了: 怎么样才能使应用被切到后台时,应用中的网络连接 ...
- [BS-25] IOS中手势UIGestureRecognizer概述
IOS中手势UIGestureRecognizer概述 一.概述 iPhone中处理触摸屏的操作,在3.2之前是主要使用的是由UIResponder而来的如下4种方式: - (void)touches ...
- iOS:KVO/KVC 的概述与使用
iOS:KVO/KVC 的概述与使用 KVO APP开发技术QQ群:347072638 一,概述 KVO,即:Key-Value Observing,它提供一种机制,当指定的对象的属性 ...
- Django REST FrameWork中文教程2:请求和响应
从这一点开始,我们将真正开始覆盖REST框架的核心.我们来介绍几个基本的构建块. 请求对象REST框架引入了Request扩展常规的对象HttpRequest,并提供更灵活的请求解析.Request对 ...
- Django REST framework 中文教程1:序列化
建立环境 在我们做任何事情之前,我们将使用virtualenv创建一个新的虚拟环境.这将确保我们的包配置与我们正在开展的任何其他项目保持良好的隔离. virtualenv envsource env/ ...
- iOS xmpp协议实现聊天之openfire的服务端配置(一)
今天弄这个openfire服务端的配置直接苦了一逼,只是好在最后最终配置好了.首先感谢@月光的尽头的博客给了我莫大的帮助. 切入正题,首先说一下iOS xmpp协议实现聊天openfireserver ...
- ios xmpp 发送语音图片解决方案
ios xmpp 发送语音,图片解决方案,有需要的朋友可以参考下. 目前做IM多是用的xmpp. 因为项目需求需要实现语音和图片的发送. 发送语音图片有三种方法. 1,xmpp smack.文件传输方 ...
- 【iOS XMPP】使用XMPPFramewok(一):添加XMPPFramework(XCode 4.6.2)
转自:http://www.cnblogs.com/dyingbleed/archive/2013/05/09/3069145.html XMPPFramework GitHub: https://g ...
随机推荐
- CSS中常用的字体单位:px、em、rem和%的区别
在刚接触CSS时,px用的比较多,也很好理解,可是用久了就会发现有些缺陷,特别是在做响应式开发的时候. 那这么多单位到底在什么时候用什么单位合适呢?今天就来探讨一下. 先大致解释一下这些单位的意思: ...
- iOS7光标问题
iOS7光标问题 有网友遇到textView在ios7上出现编辑进入最后一行时光标消失,看不到最后一行,变成盲打,stackOverFlow网站上有大神指出,是ios7本身bug,加上下面一段代码即可 ...
- DirectShow学习笔记
DirectShow, as you might have guessed, is a COM based multimedia framework that makes the task of ca ...
- this的使用、继承、super
1.this的使用 1)可以用于区分局部变量 Person(int age,string name) { this.age=age; this.name=name; } 2)构造方法中,用this调用 ...
- Delphi美化界面 转载
手头的项目做的差不多了,交给客户,结果给出的结论是界面太难看了,至少要做成像QQ类似的界面.(目前是QQ2009界面确实还是不错的,本人也非常喜欢). 1.透明问题. 要重新调整界面确实很麻烦,以前用 ...
- ZJU 1180 Self Numbers(暴力模拟判断,水题)
题目链接 同HDU 1128 , POJ 1316(这个范围小一点). 原本怕超时,以为有技巧或者规律,死命的想,后来发现这就是一道水体,模拟着全部判断一下就好了,10秒呢,完全不怕超时...唔,废话 ...
- call by reference and copy/restore
转自:http://stackoverflow.com/questions/8848402/whats-the-difference-between-call-by-reference-and-cop ...
- jquery的ajax()函数传值中文乱码解决方法介绍
jquery的ajax()函数传值中文乱码解决方法介绍,需要的朋友可以参考下 代码如下: $.ajax({ dataType : ‘json', type : ‘POST', url : ‘http: ...
- lintcode:两个数组的交
题目 返回两个数组的交 样例 nums1 = [1, 2, 2, 1], nums2 = [2, 2], 返回 [2]. 解题 排序后,两指针找相等元素,注意要去除相同的元素 public class ...
- Android 基于Socket的聊天室(一)
Socket是TCP/IP协议上的一种通信,在通信的两端各建立一个Socket,从而在通信的两端之间形成网络虚拟链路.一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信. Client A ...