关于xmpp网上资料太多了,可是没有找到一篇比较全面文章,都是得自己东平西凑的学习,这样学比较费劲,于是自己整理多方资料并总结一下自己的学习点滴和使用xmpp开发的一些方法,算是方便他人和自己学习和巩固吧。
一、xmpp是什么?
XMPP is the Extensible Messaging and Presence Protocol, a set of open technologies for instant messaging, presence, multi-party chat, voice and video calls, collaboration, lightweight middleware, content syndication, and generalized routing of XML data。
上面是摘自xmpp官方的解释,底下是根据自己理解的翻译,可能有些牵强,不足的地方请大牛指点。
XMPP 是一个扩展的消息和表示协议,是一系列的开源技术用于即时通讯、表示呈现、多方聊天、音频和视频通话、协作、轻量级中间组件、内容聚合和xml数据通用路由。
也可以这样理解用途:可用于服务类实时通讯、表示和需求响应服务中的XML数据元流式传输。
XMPP的前世今生
XMPP的前身是Jabber,一个开源形式组织产生的网络即时通信协议。XMPP目前被IETF国际标准组织完成了标准化工作。标准化的核心结果分为两部分:核心的XML流传输协议;基于XMLFreeEIM流传输的即时通讯扩展应用。
Jabber 是著名的Linux即时通讯服务服务器,它是一个自由开源软件,能让用户自己架即时通讯服务器,可以在Internet上应用,也可以在局域网中应用。
二、xmpp的优势
下面是对官方An Overview of XMPP关键点简单翻译总结,感觉对全面了解xmpp很有用就写在这里。
XMPP有何牛逼之处
1.开源:协议开源,且在客户端、服务、服务组件和一些库都有相应的实现。
2.标准化:IETF组织已经标准化核心的xml流协议(RFC 6120, RFC 6121, and RFC 7622).
3.可靠的:目前以后上万台xmpp服务器在运行,百万的的用户正在使用以xmpp作为即时通讯。
4.去中心化:任何人都可以运行自己xmpp服务器,并且之间可以向发邮件一样互联。
5.安全:SASL 和 TLS安全协议已经被规范到xmpp协议当中了。
6.可扩展性:强大的xml传输可以帮助我们在核心协议上任意扩展。
7.灵活性:xmpp不仅仅是聊天工具,还包括网络管理、协作工具、文件共享、远程监控、web服务和云计算等。
8.多样性:很多公司和开源项目都在使用XMPP技术,所以在使用XMPP时你是不会陷入困境的。
XMPP的关键技术
1.核心:xml流的xmpp技术。
2.jingle:通过 Jingle 可以实现点对点(P2P)的多媒体交互会话控制
3.多人聊天:灵活的多人聊天。
4.订阅通知:通知和订阅
5.BOSH:一个拥有xmpp传输的http绑定。
三、基于XMPP的即时通讯架构
XMPP工作原理
XMPP中定义了三个角色,客户端,服务器,网关。通信能够在这三者的任意两个之间双向发生。服务器同时承担了客户端信息记录,连接管理和信息的路由功能。
网关承担着与异构即时通信系统的互联互通,异构系统可以包括SMS(短信),MSN,ICQ等。基本的网络形式是单客户端通过TCP/IP连接到单服务器,然后在之上传输XML。
XMPP和其他系统互联通信架构
XMPP具体通信过程
四、核心xml流协议
XMPP 的核心数据包类型有Precense,Message,Iq ,此外加上初始化 stream 用到的 Stream 数据包。这些数据包是 XMPP 信息传输的载体,被用于 XMPP 核心功能和扩展功能的实现。
公有属性
在 XML stream 中,每个数据包都是 XML 格式纯文本。而每个 XML 数据包有以下公有属性:
to: 数据包要发送的目的地址
from:数据包发送的源地址
id:数据包标示符
此三项属性在 XML stanza 中最为常见。
to 和 from 属性用于服务器决定该数据包的路由规则。某些情况下,to 和 from 属性可以只有一个,例如:客户端向服务端发送设置配置的 Iq 包只含有 to (不向外路由),客户端向联系人发送 Message 只含有 to (from 属性总是被改写为客户端的地址)。
id 用于节点间判断请求和应答数据包的对应状况,大多数情况可以不处理。
初始化 XML stream,身份验证
在客户端与服务器产生 TCP 连接后,需要与服务器初始化 XML stream,以及进行身份验证。
初始化时,客户端发送 stream 头部 XML:
服务器在收到客户端的 stream 头后,回应一个 stream 头:
接着服务器向客户端发送服务端支持的身份验证方式列表,常见的方式有基于安全传输 SASL 的 BASE64 编码账户密码验证。身份验证的种类多样。
打开stream流对话后客户端和服务端就可以开始会话了,比如我想问服务端获取我的好友列表,我就可以向服务器发送下文中的get类型Iq数据包。
客户端:
该请求的意义为:名为 sawyer 的用户 (登录资源为 iOS) 向 example.com 服务器请求获得 (get) roster 表。
服务器收到请求后,返回 roster 表。
服务端:
可以看到,sawyer 的 roster 表内有3个联系人,分别名为 Romeo,Mercutio,Benvolio,都属于 Friends 分组。Roster 列表中的 JID 信息将会用在稍候客户端发送信息包的目的地址中。
Item 中的 subscription 关系到联系人状态信息的传输,有 none,both,from,to 四种。详细的 subscription 操作在 RFC 3921Managing Subscriptions 章节[7]中定义。
获取完好友列表,我就可以给我的Romeo好友发个问候了,Message 是即时聊天应用中最常用的数据包,其功能是发送用户聊天信息。一个 Message 例子如下:
客户端:
该 message 包将会被服务器转发至 example.net 服务器,随后转交给 romeo 已登录的客户端上(如果该用户没有登录,message 信息会储存在服务端直至用户上线)。
其中,body 标签中包含用户要传输的聊天信息。
要传输格式化的富文本信息,可以通过支持扩展 XEP-0071[8],引入 html 标签。
用户不想聊天了,想关闭会话。
在对话结束时,客户端和服务端要先后发送 stream 尾部 XML,以使整个 XMP stream 闭合。(如果 TCP 异常中断,则服务端直接中断对话)
客户端:
服务端:
五、常用的服务端和前端框架
iOS常用框架及开源作品
1.iOS端常用框架:https://github.com/robbiehanson/XMPPFramework
2.个人感觉不错的Demo:
https://github.com/149393437/ZCXMPPManager
https://github.com/vviicc/QShare_iOS
https://github.com/adow/Dollarss
android常用的框架及开源作品
1.android常用框架:https://github.com/Flowdalic/asmack
2.不错的安卓开源作品:https://github.com/jiangzehui/xmpp
服务端比较常用的聊天服务器。
1.java语言实现的服务器Openfire
openfire采用嵌入式Jetty服务器(相对tomcat而言)集成到工程里,安装完程序,开启服务即可使用。
源码github地址:https://github.com/igniterealtime/Openfire
源码分析地址:http://www.360doc.com/content/13/0601/17/1542811_289727966.shtml
官网地址:http://www.igniterealtime.org/projects/openfire/
2.Erlang语言实现的服务器Ejabberd
源码github地址:https://github.com/processone/ejabberd
官网地址:https://www.ejabberd.im
六、参考文档
1.XMPP官方文档 :https://xmpp.org
2.XMPP官方概要:https://xmpp.org/about/technology-overview.html
3.XMPP核心协议:https://xmpp.org/rfcs/rfc6120.html
4.程序员的世界博客:http://www.voidcn.com/blog/bolg_hero/article/p-2715024.html
5.架构图来源均为网上。