技术博客 http://www.cnblogs.com/ChenYilong/
新浪微博 http://weibo.com/luohanchenyilong
XMPP 基础
技术博客 http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilong
即时通讯技术简介
• 即时通讯技术( IM )支持用户在线实时交谈。如果要发送一条信息,用户需 要打开一个小窗口,以便让用户及其朋友在其中输入信息并让交谈双方都看 到交谈的内容
• 有许多的 IM 系统,如 AOL IM 、 Yahoo IM 、 MSN 以及 QQ ,它们 最大的区别在于 各自通讯协议的实现 ,所以 即时通讯技术的核心在于它的传输协议
• 协议用来说明信息在网络上如何传输,如果有了统一的传输协议,那么应当 可以实现各个 IM 之间的直接通讯,为了创建即时通讯的统一标准,目前已经 出现过的 IM 协议包括: IETF 的对话初始协议( SIP )和即时通讯对话初始协议 和表示扩展协议( SIMPLE )、应用交换协议( APEX )、显示和即时通讯协议 ( PRIM )及 基于 XML 且开放的可扩展通讯和表示协议( XMPP )协议 (常称 为 Jabber 协议)
• 人们多次努力,试图统一各大主要 IM 供应商的标准( AOL 、 Yahoo 及 Microsoft ),但无一成功,且每一种 IM 仍然继续使用自己所拥有的协议
![](http://img0.tuicool.com/JBvuMf.png)
即时通讯在 垂直 社交应用中的意义
• 和第一代大而全的水平网站(又称综合性网站)不同, 垂直网站注意 力集中在某些特定的领域或某种特定的需求,提供有关这个领域或需 求的全部深度信息和相关服务 ,作为互联网的新亮点,垂直网站正引 起越来越多人的关注。在越来越多的网络吸引老百姓的注意力时,网 民却逐渐走出时髦、好奇的初级阶段,不断在网上寻找着实际、实用 和实惠
• 随着移动互联网应用的发展,现在越来越多的 App 正在向垂直应用迁 移, 垂直应用中同类用户群体之间的沟通,产生聚合 就显得尤为重要 了,因此 目前国内市场的 XMPP 应用开发的人才需求非常大
XMPP 起源
• XMPP 是基于 XML 的协议,用于即时消息( IM )以及在线现场探测。最初, XMPP 作为一个框架开发, 目标是支持企业环境内的即时消息传递和联机状态 应用程序 。当时的即时消息传递网络是私有的,不适合企业使用
• XMPP 前身是 Jabber ( 1998 年) ,是一个开源组织定义的网络即时通信协议
• XMPP 是一个分散型通信网络 ,这意味着,只要网络基础设施允许,任何 XMPP 用户都可以向其他任何 XMPP 用户传递消息。多个 XMPP 服务器也可以 通过一个专门的“服务器 - 服务器 "协议相互通信,提供了创建 分散型社交网 络和协作框架 的可能性
• 尽管 XMPP 的出现是为了 满足“个人 - 个人"即时消息传递的要求 ,但它完全 不必局限于此任务
• XMPP 是一种基于 XML 的协议 ,它继承了在 XML 环境中灵活的发展性。这表明 XMPP 是可扩展的 。可以通过发送扩展的信息来处理用户的需求,以及在 XMPP 的顶端建立如内容发布系统和基于地址的服务等应用程序。而且, XMPP 包含了针对服务器端的软件协议 ,使之能与另一个进行通话,这使得开 发者更容易建立客户应用程序或给一个配置好的系统添加功能
• XMPP 的核心 XML 流 传输协议 的定义使得 XMPP 能够在一个比以往网络通信协 议更规范的平台上。借助于 XML 易于解析和阅读的特性, 使得 XMPP 的协议能 够非常漂亮
• XMPP 的即时通讯扩展应用部分是根据 IETF 在这之前对即时通讯的一个抽象定 义的,与其他业已得到广泛使用的即时通讯协议,诸如 AIM , QQ 等有功能完 整,完善等先进性
• XMPP 的扩展协议 Jingle 使得其支持语音和视频,目前 iOS 尚不支持
• XMPP 的官方文档是 RFC 3920
• XMPP 协议曾经是 Google 力推的即时通信协议, 其代表作品是 GTalk
Google Talk ( GTalk )
• Google Talk 是 Google 的 IM 工具,除了具有 IM 功能外,另外还加上了
Voip 功能, “ 界面清新大方 " ,可直接链接 Gmail ,接受查看邮件
• 由于 Google Talk 是 基于 Jabber 开源标准,这种标准允许用户和其它的 即时讯息系统相连 ,比如苹果电脑的 iChat , GAIM , Trillian Pro 以及 Psi 。 Google Talk 只能够在Windows 平台上运行
• Google Talk 的用户无法使用这种软件与 AIM , MSN Messenger 或者雅 虎Messenger 的用户进行互通
GTalk 界面截图
![](http://img1.tuicool.com/fauA3e.jpg)
GTalk 即将退出 历史舞台
• 2013 年 5 月,在 Google I/O 大会上, Google 推出统一跨平台聊天应用
Hangouts (环聊)取代 Google Talk
• Google Hangouts 不支持 XMPP 协议 。 Google Hangouts 用户与非 Google
服务如 XMPP 协议的强有力支持者 jabber.org 之间的交流无法进行
• 目前, Google Wave 是基于 XMPP 协议的,并且 Google 还开发 Jingle 扩 展进行基于 XMPP 协议的视频聊天。尽管 Google 尚未宣布 Talk 的关闭日 期,不过从 Google 关闭 Reader 和 iCal 支持来看, Talk 关闭之日不会太远
Google Hangouts 宣传截图
Hangouts 目前在中国大陆无法使用,尚不支持 iOS7.0
XMPP 定义
• XMPP : The Extensible Messaging and Presence Protocol (可扩展通讯
和表示协议)
• XMPP 可用于服务类 实时通讯、表示和需求响应 服务中的 XML 数据元 流式传输。 XMPP 以 Jabber 协议为基础,而 Jabber 是即时通讯中常用 的开放式协议
• XMPP 是基于 XML 的协议, 用于即时消息( IM )以及在线现场探测 。 促进服务器之间的 准即时 操作。这个协议 可能 最终允许因特网用户向 因特网上的其他任何人发送即时消息,即使其操作系统和浏览器不同
• XMPP 是一个典型的 C/S 架构,而不是像大多数即时通讯软件一样, 使用 P2P 客户端到客户端的架构,也就是说在大多数情况下,当两个 客户端进行通讯时, 他们的消息都是通过服务器传递的。采用这种架 构,主要是为了简化客户端,将大多数工作放在服务器端进行
• XMPP 中定义了三个角色, 客户端,服务器,网关 。 通信能够在这三 者的任意两个之间双向发生
• 服务器 同时承担了客户端信息记录,连接管理和信息的路由功能
• 网关 承担着与 异构即时通信系统 的互联互通,异构系统可以包括
SMS (短信), MSN , ICQ 等
• 基本的网络形式是 单客户端通过 TCP/IP 连接到单服务器 ,然后在之上 传输 XML流
1. 节点连接到服务器 2. 服务器利用本地目录系统中的证书对其认证 3. 节点指定目标地址,让服务器告知目标状态 4. 服务器查找、连接并进行相互认证 5. 节点之间进行交互
• XMPP 应用传输的是 与即时通讯相关的指令 。在以前这些命令要么用 二进制的形式发送(比如 QQ ),要么用纯文本指令加空格加参数加换 行符的方式发送(比如 MSN )
• 而 XMPP 传输的即时通讯指令的逻辑与以往相仿,只是 协议的形式变 成了 XML 格式的纯文本 。这不但使得解析容易了,人也容易阅读了, 方便了开发和查错
• 而 XMPP 的核心部分就是一个 在网络上分片段发送 XML 的流协议 。这 个 流协议是 XMPP 的即时通讯指令的传递基础,也是一个非常重要的 可以被进一步利用的网络基础协议 ,可以说 XMPP 用 TCP 传的是 XML 流
XMPP 的优缺点
• 优点 - 开放
- 标准( XMPP 的技术规格已被定义在 RFC 3920 及 RFC 3921 ) - 证实可用 - 分散 - 安全
- 可扩展
• 缺点 - 数据负载过重 - 没有二进制传输
XMPP 的传输小结
• XMPP 是一种类似于 HTTP 协议的一种数据传输协议,其过程就 如同“解包装 -- 〉包装"的过程。只需要理解其 接收的类型 及 返 回的类型 ,便可以很好的利用 XMPP 来进行数据通讯
• XMPP 官方网站 -- http://xmpp.org
![](http://postachio-images.s3-website-us-east-1.amazonaws.com/96083b7bb56878d8f4821117b754ca3a/3ac49755bbc44fdc92eee6c2fb8ae099/w600_1df5924a59725b6b62e06f8ec2f8f773.png)
![](http://postachio-images.s3-website-us-east-1.amazonaws.com/96083b7bb56878d8f4821117b754ca3a/3ac49755bbc44fdc92eee6c2fb8ae099/w600_294ebb4315be969ce27596569bf0802f.png)
![](http://img1.tuicool.com/iIbyIf.png)
服务器搭建 -- 安装 MySQL
![](http://img2.tuicool.com/vAJZB3.png)
启动 MySQL 服务器
![](http://img0.tuicool.com/rIVzie.png)
设置 MySQL 命令行搜索路径
• 打开终端,输入:
• vi ~ / .bash_profile
• 输入 i
• 然后粘贴以下内容
#mysql
alias mysql='/usr/local/mysql/bin/mysql'
alias mysqladmin='/usr/local/mysql/bin/mysqladmin'
#ls
alias ls='ls -G ’
• 按 ESC 键
• 输入 :wq
• 重新启动终端程序
![](http://postachio-images.s3-website-us-east-1.amazonaws.com/96083b7bb56878d8f4821117b754ca3a/3ac49755bbc44fdc92eee6c2fb8ae099/w600_897b223fe1bf63457e55de6d396ff5bb.png)
修改 MySQL 的管理员密码
• mysqladmin -u root password “123456"
![](http://postachio-images.s3-website-us-east-1.amazonaws.com/96083b7bb56878d8f4821117b754ca3a/3ac49755bbc44fdc92eee6c2fb8ae099/w600_897b223fe1bf63457e55de6d396ff5bb.png)
安装 MySQL 管理工具 --Navicat Premium
![](http://img1.tuicool.com/JJfmQn.png)
建立数据库连接( 1 )
建立数据库连接( 2 )
![](http://postachio-images.s3-website-us-east-1.amazonaws.com/96083b7bb56878d8f4821117b754ca3a/3ac49755bbc44fdc92eee6c2fb8ae099/w600_897b223fe1bf63457e55de6d396ff5bb.png)
![](http://img0.tuicool.com/mIbeam.png)
新建数据库 --Openfire
![](http://postachio-images.s3-website-us-east-1.amazonaws.com/96083b7bb56878d8f4821117b754ca3a/3ac49755bbc44fdc92eee6c2fb8ae099/w600_897b223fe1bf63457e55de6d396ff5bb.png)
![](http://img1.tuicool.com/QZfAbe.png)
彻底删除 MySQL 的方法
.1. 先停止所有 mysql 有关进程
.2. sudo rm /usr/local/mysql
.3. sudo rm -rf /usr/local/mysql*
.4. sudo rm -rf /Library/StartupItems/MySQLCOM
.5. sudo rm -rf /Library/PreferencePanes/My*
.6. sudo vi /etc/hostconfig # removed the line MYSQLCOM=-YES-
.7. rm -rf ~/Library/PreferencePanes/My*
.8. sudo rm -rf /Library/Receipts/mysql*
.9. sudo rm -rf /Library/Receipts/MySQL*
.10. sudo rm -rf /var/db/receipts/com.mysql.*
显示隐藏文件
• 在终端中输入以下命令,可以切换隐藏文件的显示
• 显示隐藏文件
• defaults write com.apple. finder AppleShowAllFiles Yes && killall Finder
• 不显示隐藏文件
• defaults write com.apple. finder AppleShowAllFiles No && killall Finder
• 提示 :
Ø 在 OS X 10.9 Mavericks 需要将 Finder 修改成 finder 才行,第一个字母换
成小写的 f
Ø 以上命令类似与在 iOS 开发中的
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"com.apple.finder"];
服务器搭建 --Openfire
• 可用服务器地址: http://xmpp.org/xmpp-software/servers/
• 课程选用: Openfire
• Openfire 简介
- 采用 Java 开发,开源的实时协作( RTC )服务器,基于 XMPP ( Jabber )协议
- 安装 Openfire 之前,需要确认是否安装了 JDK
- 如果没有,需要安装 jdk-7u45-macosx-x64
- 可以轻易的构建高效率的即时通信服务器
- 安装和使用简单,并利用 Web 进行管理
- 单台服务器可支持上万 (1000) 并发用户
![](http://postachio-images.s3-website-us-east-1.amazonaws.com/96083b7bb56878d8f4821117b754ca3a/3ac49755bbc44fdc92eee6c2fb8ae099/w600_c7b18a60fe51cda9366815361aa1031d.png)
• 下载并安装:
http://www.igniterealtime.org/projects/openfire/index.jsp
• 安装位置: /usr/local/openfire/
• 安装位置该文件夹的用户访问权限
• 数据库脚本保存在 /usr/local/openfire/resources/database 文件夹下
![](http://postachio-images.s3-website-us-east-1.amazonaws.com/96083b7bb56878d8f4821117b754ca3a/3ac49755bbc44fdc92eee6c2fb8ae099/w600_6b8f0c3ecebf6e2f13545208762e9aa1.png)
修改 /usr/local/openfire/ 目录权限
![](http://img2.tuicool.com/VvQJzm.png)
![](http://img0.tuicool.com/ba2aiu.png)
设置 openfire 数据库
1. 将 /usr/local/openfire/resources/database/openfire_mysql.sql 复
制到桌面 2. 在 Navicat 中新建 Query ,导入该文件并执行
Openfire 设置
1. 在系统偏好中确保 Openfire 服务已经启动
2. 使用浏览器访问: http://localhost:9090
3. 如果需要重新配置,可以修改 /usr/local/openfire/conf / openfire.xml ,将末尾的 true修改为 false
4.重新设置安装openfire,不会影响其中的用户,只是在忘记密码时,进行的操作.
![](http://postachio-images.s3-website-us-east-1.amazonaws.com/96083b7bb56878d8f4821117b754ca3a/3ac49755bbc44fdc92eee6c2fb8ae099/w600_abb74e44f493f0054f6a80679996aa0c.png)
![](http://postachio-images.s3-website-us-east-1.amazonaws.com/96083b7bb56878d8f4821117b754ca3a/3ac49755bbc44fdc92eee6c2fb8ae099/w600_897b223fe1bf63457e55de6d396ff5bb.png)
![](http://img1.tuicool.com/InY3ey.png)
设置服务器(注意域名)
选择数据库连接方式
![](http://postachio-images.s3-website-us-east-1.amazonaws.com/96083b7bb56878d8f4821117b754ca3a/3ac49755bbc44fdc92eee6c2fb8ae099/w600_897b223fe1bf63457e55de6d396ff5bb.png)
![](http://img0.tuicool.com/7Zjuei.png)
设置数据库
![](http://postachio-images.s3-website-us-east-1.amazonaws.com/96083b7bb56878d8f4821117b754ca3a/3ac49755bbc44fdc92eee6c2fb8ae099/w600_897b223fe1bf63457e55de6d396ff5bb.png)
![](http://img1.tuicool.com/VjMfEb.png)
设置管理员密码 -- 不要跳过!
![](http://img2.tuicool.com/iIV3Ur.png)
配置完成并登录
![](http://img0.tuicool.com/3ErEfyz.png)
Openfire 服务器端口
![](http://img1.tuicool.com/U7NZNn.png)
![](http://postachio-images.s3-website-us-east-1.amazonaws.com/96083b7bb56878d8f4821117b754ca3a/3ac49755bbc44fdc92eee6c2fb8ae099/w600_897b223fe1bf63457e55de6d396ff5bb.png)
![](http://img2.tuicool.com/BrUbqy.png)
客户端设置测试 Openfire 服务器
![](http://img0.tuicool.com/QriuQf.png)
![](http://img1.tuicool.com/yQRbIr.png)
• 每个 XMPP 客户端用户必须拥有一个全局惟一标识符 。基于历史原因, 这些标识符称为 Jabber ID 或 JID 。鉴于协议的分布式特征, JID 应包含 联系用户所需的所有信息 , JID 的结构类似于电子邮件地址 ,但不要求 JID 同时也是有效的电子邮件收件人
• 客户端和服务器节点,被统称为 XMPP 实体 ,都拥有 JID 。例如: SomeCorp 公司的员工 John Doe 可能拥有 JID : John.Doe@somecorp.com ,其中somecorp.com 是 SomeCorp 公司的 XMPP 服务器的地址, John.Doe 是 John Doe的用户名
• 还可以使用 JID 连接到其他资源。这允许在一个 XMPP 实体标识符之外 进一步处理拓展
支持 XMPP 协议的客户端
Spark Adium
![](http://img2.tuicool.com/J7ZVJn.png)
![](http://img0.tuicool.com/jIvqui.png)
• 体会 XMPP 目前所能支持的功能 • 并且构思即将开发的 XMPP 项目所能包含的功能
iOS 的 XMPP 框架 --XMPPFramework
• 其他语言可用框架地址:
http://xmpp.org/xmpp-software/libraries/
• 课程选用: XMPPFramework ,唯一可用的 OC 框架
![](http://postachio-images.s3-website-us-east-1.amazonaws.com/96083b7bb56878d8f4821117b754ca3a/3ac49755bbc44fdc92eee6c2fb8ae099/w600_9e271e84e75841175a190125c06bd285.png)
导入 XMPPFramework 框架( 1 )
Ø 下载 XMPPFramework 框架 :
https://github.com/robbiehanson/XMPPFramework
Ø gitclone
git clone https://github.com/robbiehanson/XMPPFramework.git
Ø 导入依赖框架
![](http://postachio-images.s3-website-us-east-1.amazonaws.com/96083b7bb56878d8f4821117b754ca3a/3ac49755bbc44fdc92eee6c2fb8ae099/w600_79c375b47d2e2f99c7ab5c1b7c34370a.png)
![](http://postachio-images.s3-website-us-east-1.amazonaws.com/96083b7bb56878d8f4821117b754ca3a/3ac49755bbc44fdc92eee6c2fb8ae099/w600_f1a2b71c57bbcc6d078124190ca644c0.png)
CocoaLumberjack :日志框架 CocoaAsyncSocket :底层网络框架,实现异步 Socket网络通讯
需要添加 CFNetwork & Security 框架依赖 KissXML : XML 解析框架
需要添加 libxml2.dylib 框架依赖
需要指定如下编译选项:
OTHER_LDFLAGS = -lxml2 HEADER_SEARCH_PATHS = /usr/include/libxml2
libidn
-
设置 XML 头文件搜索路径
![](http://img1.tuicool.com/jyMFFr.png)
设置其他链接标记
![](http://img2.tuicool.com/iUbUb2.png)
导入 XMPPFramework 框架( 2 )
• 将以下 4 个文件夹导入到项目 - Authentication
- Categories - Core
- Utilities
• 另外还需要添加 libresolv.dylib 依赖
导入 XMPPFramework 框架( 3 )
• 导入 XMPP 扩展框架
- Extensions
• 将 Sample_XMPPFramework . h 添加到项目,并且重命名为
XMPPFramework . h
• 在终端输入: git commit -m “ 添加 XMPP 框架 "
• 可以一次性提交所有增加的文件
XMPP 框架常用扩展
• XEP-0045: 多用户聊天
• XEP-0060: 发布 - 订阅
• XEP-0065: SOCKS5 字节流
• XEP-0085: 聊天状态通知
• XEP-0096: 文件传输
• XEP-0172: 用户昵称
• XEP-0184: 消息送达
• CoreDataStorage: 数据存储
• Reconnect :重新连接
• Roster :花名册
• http://xmpp.org/xmpp-protocols/xmpp-extensions/
新建项目并导入 XMPP 框架练习
• 熟练掌握 XMPP 框架的导入过程
• 并且构思即将开发的 XMPP 项目所能包含的功能
CocoaLumberjack
• 是一款高性能的日志输出插件
• 需要配合 XcodeColors 插件一起使用 •https://github.com/robbiehanson/XcodeColors
![](http://postachio-images.s3-website-us-east-1.amazonaws.com/96083b7bb56878d8f4821117b754ca3a/3ac49755bbc44fdc92eee6c2fb8ae099/w600_f52249e4df10a99597b14143ad8aaf36.png)
#import "DDLog.h" !
#import "DDTTYLogger.h" !
!
#ifdef DEBUG!
static const int ddLogLevel = LOG_LEVEL_VERBOSE ;! #else!
static const int ddLogLevel = LOG_LEVEL_OFF;! #endif
应用程序启动后设置跟踪级别
[DDLog addLogger:[DDTTYLogger sharedInstance]];! [[DDTTYLogger sharedInstance] setColorsEnabled: YES ];!
[[DDTTYLogger sharedInstance] setForegroundColor:[UIColor blueColor] backgroundColor: nil forFlag:LOG_FLAG_INFO];!
!
DDLogInfo ( @" 提示信息 " );! DDLogWarn ( @" 警告信息 " );! DDLogVerbose ( @"详细信息 " );! DDLogError ( @" 错误信息 " );
• XMPPStream :是开发过程中最主要交互的类,所有扩展和自定义代
码均要基于此类进行
• XMPPParser :供 XMPPStream 解析使用
• XMPPJID :提供了一个不可变 JID 的实现,遵守 NSCopying 协议和 NSCoding 协议
• XMPPElement :以下三个 XMPP 元素的基类
• XMPPIQ : 请求
• XMPPMessage : 消息
• XMPPPresence : 出席
• XMPPModule :开发 XMPP 扩展时使用
• XMPPLogging : XMPP 的日志框架
• XMPPInternal :整个 XMPP 框架内部使用的核心和高级底层内容
XMPPStream 实例的配置
1. 配置如何连接至 XMPP 服务器 2. 添加 代理 3. 添加模块 4. 开始连接
5. 开始授权 • 注意:
- XMPP 框架仅提供了一个最小的 代理委托系统 用于接收三种 XMPP 类型( IQ 、Message 和 Presence ),如果要实现更多的功能,开发 者还需要编写大量的相关代码
- 为了简化开发, 通常将 XMPPStream 放置在 AppDelegate 中 ,以便 于全局访问
XMPP 框架提供的主要扩展功能
• XMPPReconnect :如果意外中断,自动重连 XMPP 流 • XMPPRoster :标准的XMPP 花名册 • XMPPRoom :提供多人聊天支持 • XMPPPubSub :提供公共订阅支持
• ......
通信类别及公共 XML 属性
• 使用 XMPP 的实时消息传递系统包含三大通信类别: - 消息传递 ,其中数据在有关各方之间传输 - 联机状态 ,允许用户广播其在线状态和可用性 - 信息 / 查询请求 ,它允许 XMPP 实体发起请求并从另一个实体接收响应
• 以上三种类型的 XMPP 节都拥有以下公共属性: - from :源 XMPP 实体的 JID - to:目标接收者的 JID - id :当前对话的可选标识符
- type :节的可选子类型 - xml:lang :如果内容是人们可读的,则为消息语言的描述
XMPP 应用程序功能预设
• 用户登录、注册 • 添加好友 Roster • 好友聊天 • 表情文字( CoreText ) • 聊天状态XEP-0085
• 聊天室群聊 XEP-0045 • 发送文件 XEP-0096 • 语音聊天 XEP-0065