XMPP

iOS 的 XMPP framework 简介

登陆 - 验证密码上线 - 断开 - 好友状态 - 接收消息和发送消息 - 获取好友信息(列表&名片)和添加删除好友 - 聊天室 - 消息回执 - 添加AutoPing 为了监听服务器是否有效,增加心跳监听。


XMPP 协议简单介绍

1. 为什么选择XMPP协议

2. XMPP的基本网络结构 - 2.1 XMPP客户端 - 2.2 XMPP服务器 - 2.3 XMPP网关

3. 服务器端介绍 - 3.1 什么是Openfire - 3.2 为什么使用Openfire

4. XMPP协议的组成 RFC 3920 XMPP

5. XMPP地址格式

6. XMPP消息格式 - 6.1 message type属性 + to属性 + from属性 - 6.2 presence - 6.3 iq (Info / Query)


《移动IM开发那些事》

通讯方式选择 - P2P + 服务器中转

网络连接方式 - 基于TCP的长连接 + 基于HTTP短连接PULL的方式

协议选择 - XMPP + SIP + MQTT + 私有协议

私有协议的设计 - 序列化选择 + 协议格式设计

其他问题 - 协议加密 + 快速连接(登录) + 连接保持 + 消息可达 + 文件上传优化


Overview of the XMPP Framework

Up to date instructions on how to install XMPP Framework manually?

Introduction


框架分为2个部分:

1. XMPP Core

2. The extensions (roster, XEP's, optional supporting utilities, etc)

拓展包含如名单支持,自动重连和多样的XMPP拓展实现。


XMPP Core {#core}


XMPP框架的核心文件在 "Core" 文件夹中,文件如下:

XMPPStream

XMPPParser

XMPPJID

XMPPElement

XMPPIQ

XMPPMessage

XMPPPresence

XMPPModule

XMPPLogging

XMPPInternal

框架的核心是 XMPPStream 类,这是你主要用到的类,同时这个类是所有拓展和自定义代码要接入的地方。它有许多有趣的特性,被用于使框架灵活,可拓展,易于从上层开发。我们将在本文档的后面深入的讨论这些。

XMPPParser  XMPPStream 的内部类。你可以大胆的猜想它是干嘛的。在任何情况下,你都不需要与 parser 打交道。

XMPPJID 提供了一个不可变的 JID (Jabber Identifier)实现。它支持 JID's 解析,同时抽取了JID在多种形式下的不同部分。它遵循 NSCopying 协议,以便 JID's 可能用作 NSDictionary 中的keys。也遵循 NSCoding 协议。

XMPPElement 是3个主要的 XMPP 元素的基础类: XMPPIQ & XMPPMessage & XMPPPresence。其拓展了 NSXMLElement,因此你拥有整 NSXML foundation 用于观察任何 XML元素。更多细节在 section Elements: IQ, Message, & Presence.

XMPPModule 为可选可拓展提供了基础类。如果自己写app,就会想创建自己的类,注册获得自己的delegate调用。

XMPPLogging 提供快速,强大,灵活的日志框架。XMPP Logging

XMPPInternal 关联 core 和多种高级底层的拓展


Elements: IQ, Message, & Presence


XMPPElement 扩展 NSXMLElement,因此你拥有整 NSXML foundation 用于观察任何 XML元素。

XMPPIQ -> XMPPElement -> NSXMLElement -> NSXMLNode -> NSObject

XMPPMessage -> XMPPElement -> NSXMLElement -> NSXMLNode -> NSObject

XMPPPresence -> XMPPElement -> NSXMLElement -> NSXMLNode -> NSObject

除了 NSXML foundation,框架提供 NSXMLElement+XMPP 分类,有多样的便利方法来确保编码更加精确可读。如:

[element  attributeIntValueForName:@"age"];

更多信息,戳 Working With Elements


XMPPStream Configuration {#configuration}


XMPPStream 实例的配置分为几步:

Configuring how to connect to the xmpp server

Adding delegates

Adding modules

Connecting

Authenticating


Configuring the connection

对大多数人,只需简单一步,设置 stream 的 myJID 属性。如:

xmppStream.myJID = [XMPP   JIDjidWithString:@"user@gmail.com"];

The xmpp stream will figure out the rest by following the XMPP RFC. This involves doing an SRV 搜索 for _xmpp-client._tcp.domain。上面的列子,用 gmail, google 服务器将很可能返回像 "talk.google.com",之后 xmppStream 将连接服务器。如果 SRV 搜索失败,之后 xmppStream 将简单的连接 JID's 域名。

如果你知道连接的 xmpp 服务器没有 xmpp SRV 记录,你能告诉 xmppStream 跳过 SRV 搜索,通过指定 hostName。如

xmppStream.myJID = [XMPP  JIDjidWithString:@"user@myCompany.com"];

xmppStream.hostName = @"myCompany.com";

当你用一个开发 xmpp 服务器,hostname 也很容易得到。但是服务器仅能在本地网络获得,或者没有 DNS 地址。如:

xmppStream.myJID = [XMPP  JIDjidWithString:@"user@dev1.myCompany.com"];

xmppStream.hostName =@"192.168.2.27";

另一个可选属性是 hostPort。默认,根据 xmpp 说明,几乎所有服务器运行 port 5222。但是,如果你的服务器运行不同的 port,你也能设置 hostPort 属性。


Adding Delegates

XMPPStream 有许多有趣的特性,被用于使框架灵活,可拓展,易于从上层开发。其中之一就是运用 MulticastDelegate。

What is a MulticastDelegate?

xmpp 框架需要支持一个非限制数量的拓展。这包含官方拓展,也包含其他拓展或者自定义代码。因此传统的代理模式不行了。XMPP 模块和拓展需要被分离为他们自己独立的类,然而,所有这些类需要获得 delegate 方法。同时,标准的 NSNotification 架构也不起作用了,因为一些代理要求一个返回值。(而且,从 notification 的 userInfo 字典中提取参数真TM烦人)

因此一个多播代理允许你用标准模式接入框架,但是它允许多类获得相同的 delegate 通知。好处在于你可以把所有 xmpp 处理代码放进一个类中。也能分离处理代码到多个类中,一切由你决定。

你能在任何时候把自己作为一个XMPPStream的 delegate 添加 / 删除。

[xmppStream   addDelegate:self    delegateQueue:dispatch_get_main_queue()];...

[xmppStream   removeDelegate:self];

关于多播代理的更多细节 here    关于线程和队列的更多细节 here


Adding Modules

框架中附带许多拓展,当然,你想写多少就写多少。我们不可能 review 所有拓展,但是我们将列举一些

XMPPReconnect - 如果意外断连,自动重连流

XMPPRoster - provides support for standard xmpp roster.

XMPPRoom - provides multi-user chat support.

XMPPPubSub - Publish subscribe

例如,我们将接入 XMPPReconnect 到我们的流中

xmppReconnect = [ [XMPPReconnect   alloc]   init];

// xmppReconnect 的可选配置写这儿

// The defaults are fine for our purposes.

[xmppReconnect   activate:xmppStream];

// 你也可以选择性的为模块增加 delegates

[xmppReconnect   addDelegate:self   delegateQueue:dispatch_get_main_queue()];

// 这就是所有需要做的

// 从 xmpp 流,模块将自动获得任何它需要的 delegate 方法,同时继续做它的事情。除非失效。


Connecting

当你准备好了,你可以开始连接过程:

NSError *error = nil;

if  ( ![xmppStream   connect:&error] )   {

      NSLog(@"Oops, I probably forgot something:%@", error);

}

如果你忘记设置必要的属性,如 myJID,之后连接方法将返回 NO,同时 error 信息将通知你。

在连接过程中,客户端和服务器将经历 xmpp 握手。其中,服务器通知客户端多种协议,有它支持的,也有要求的。一些服务器可能要求通过 SSL/TLS (startTLS) 安全连接。如果是这样的话,xmppStream 将自动安全连接。如果你连接服务器,用不合适的 X509 证书,你可能需要实现xmppStream:willSecureWithSettings: 代理方法来警告默认安全设置。


Authenticating

在所有连接握手完成之后,xmppStreamDidConnect: 代理方法被调用。这是一般大多数客户端应该开始验证过程的地方。很简单:

- (void)xmppStreamDidConnect:(XMPPStream *)sender  {  

     [xmppStream   authenticateWithPassword:password   error:NULL];

}


XMPP Logging

通过 xmpp 框架的 logging 有几个目的:

必须支持几个 log 等级

不是所有 log 信息都有相同的优先级。有些关于 errors,而有些只是信息。levels 帮助开发者保持他们的日志信息完整,无障碍的打开关闭它们的能力。

必须基于每个文件可配置

必须对最终用户可配置


xmpp framework 用专业 log 框架:CocoaLumberjack,特别厉害。

这里有你需要知道的关于 XMPPFramework 如何 logging

框架中大多数文件的头部,会发现:

// Log levels: off, error, warn, info, verbose

static  const  int  xmppLogLevel = XMPP_LOG_LEVEL_WARN;

看到了吧,有4种 log levels (还有 XMPP_LOG_LEVEL_NONE)

Error

Warning

Info

Verbose

你能改变任何文件的 log level 来获得更多信息。

此外,有一个 Trace flag 可以用,当 enabled,将打印被调用的方法。

记住,tracing独立于 log levels,如,同时设置:

// 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有一个可选的,允许你查看 raw XML 被发送和接受。在 XMPPStream.m 中打开:

// Log levels: off, error, warn, info, verbose

static  const  int  xmppLogLevel = XMPP_LOG_LEVEL_INFO | XMPP_LOG_FLAG_SEND_RECV;

回调所有 logging 的目的是让你控制什么被log和这些log的状态。所以当app启动时,你将配置 lumberjack 框架。对于新手,下面这样配:in your AppDelegate

#import  "DDLog.h"

#import  "DDTTYLogger.h"

- (void)applicationDidFinishLaunching:(NSNotification*)aNotification  {    

     [DDLog  addLogger:

                   [DDTTYLogger  sharedInstance]  withLogLevel:XMPP_LOG_FLAG_SEND_RECV];

}

更多关于 Lumberjack 信息 project page

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,198评论 6 514
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,334评论 3 398
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,643评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,495评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,502评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,156评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,743评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,659评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,200评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,282评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,424评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,107评论 5 349
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,789评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,264评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,390评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,798评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,435评论 2 359

推荐阅读更多精彩内容

  • 关于XMPP最权威的讲解:http://www.jabbercn.org/RFC3920(这个才是最权威的,下面文...
    随风飘荡的小逗逼阅读 1,491评论 1 5
  • XMPP使用 : http://blog.csdn.net/liuhongwei123888/article/de...
    shenchao123444阅读 1,273评论 1 2
  • 注册,获取好友列表,聊天 我们的注册功能实现上跟登录功能的步骤大致相当 首先需要在我们的XMPPManager类中...
    Axela阅读 608评论 1 0
  • 一、即时通讯技术 即时通讯技术(IM -- Instant Messaging)-> 支持用户在线实时交谈 有许多...
    iOS_成才录阅读 8,483评论 10 76
  • 我和他在一起出乎好多人意料,和他高中相识,大学在一起,现在在一起287天。 听着《告白气球》,和他聊着天,写着...
    你是我的走影阅读 290评论 0 2