1 参考资料
- XMPP官网
- XMPP中文
- xmpp基本概念 (作者:RiverLi,来源:简书)
- Openfire官网
- Openfiregithub地址
- Openfire教程网
- Smack github地址
2 即时通讯的相关知识
2.1 即时通讯的概述
即时通讯(Instant Messaging)是目前Internet上最为流行的通讯方式,各种各样的即时通讯软件也层出不穷;服务提供商也提供了越来越丰富的通讯服务功能,常见的即时通讯工具有QQ、微信等。然而如果要搭建一个即时通讯系统,离不开即时通讯协议,今天要介绍的是基于XMPP协议的即时通讯系统。
即时通讯协议就是即时通讯系统在通讯时所需要遵循的规范,它定义了一些标准化的通讯数据格式和网络架构等。
即时通讯的常用协议
- 即时信息和空间协议(IMPP)
- 空间和即时信息协议(PRIM)
- 针对即时通讯和空间平衡扩充的进程开始协议(SIP)
- 可扩展通讯和表示协议(XMPP)
- 私有协议(自定义协议):为了更满足特定的需求和安全性,有些开发者会重新定义一套协议,这个成本是非常巨大的,一般是大厂干的事(例如腾讯)。
2.2 XMPP的相关知识
2.2.1 XMPP的定义
XMPP(可扩展通讯和表示协议)是基于可扩展标记语言(XML)的协议,它继承了在XML环境中灵活的发展性,可用于实时消息传递、呈现和请求/响应业务。XMPP使用TCP传输XML数据流,属于应用层协议,而非传输层协议。XMPP官网 XMPP中文
XMPP协议的前身是Jabber
,采取XMPP协议来实现IM主要是考虑XMPP协议是以XML为基础的。这表明XMPP是可扩展的,所以XMPP信息不仅可以是简单的文本,而且可以携带复杂的数据和各种格式的文件,也就是说XMPP协议不仅可以用在人与人之间的交流,而且可以实现软件与软件或软件与人之间的交流,目前支持XMPP协议的即时通讯工具有Gtalk、FaceBook IM、Twitter、网易POPO等等通讯工具,具有非常好的发展情景。
2.2.2 XMPP的基本网络结构
XMPP中定义了三个角色,客户端,服务器,网关。
- 服务器:同时承担了客户端信息记录,连接管理和信息的路由功能。
- 网关:一个特殊用途的服务器端的服务,主要功能是把xmpp翻译成外部消息系统,并把返回的消息翻译成xmpp。基本的网络形式是单客户端通过TCP/IP连接到单服务器,然后在其之上传输XML。
- 客户端:通过TCP连接直接连接到服务器,并通过xmpp获得由服务器以及联合服务器所提供的全部功能。多个不同的客户端可以同时登陆并且并发的连接到一个服务器,每个不同资源的客户端通过xmpp地址的资源标识符来区分。
2.2.3 XMPP的通讯原理
XMPP通讯过程中传输的是与即时通讯相关的指令。只是协议的形式变成了XML格式的纯文本。
- Client1连接到服务器;
- 服务器利用本地目录系统中的证书对其认证;
- Client1指定目标Client2地址,让服务器告知目标状态;
- 服务器查找、连接并进行相互认证;
- Client之间(Client1与Client2)进行交互。
下面是一个XMPP通讯过程示例:
客户端(minstone)连接到一个XMPP服务器(127.0.0.1:5222/TCP),发送一条消息“Bye Bye”到另一个客户端(test),然后注销。
- 1.客户端(minstone)发送连接请求到服务器
客户端:
<?xmlversion='1.0'?>
<stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" to="127.0.0.1">
- 2.服务器对请求应答
服务器:
<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'
from='127.0.0.1' id='1461777714'>
- 3.服务器利用本地目录系统的证书对其认证
客户端:
<iq type="set" id="auth_2" to="127.0.0.1" >
<query xmlns="jabber:iq:auth">
<username>minstone</username>
<password>mypassword</password>
<resource>Work</resource>
</query>
</iq>
- 4.服务器将相应的结果返回给用户端
服务器:
<iq from="127.0.0.1" id='auth_2' type='result'/>
- 5.用户发送消息请求,并注销
客户端:
<message to="[email protected]" >
<subject>Bye Bye</subject>
<body>test 1449</body>
</message>
<presence type="unavailable" >
<status>Logged out</status>
</presence>
</stream:stream>
- 6.服务器返回注销信息
服务器:
</stream:stream>
以文档的观点来看,客户端或服务器发送的所有XML文本连缀在一起,从<stream>
到</stream>
构成了一个完整的XML文档。其中的stream标签就是所谓的XML Stream(XML流)。在<stream>
与</stream>
中间的那些<message>...</message>
这样的XML元素就是所谓的XML Stanza(XML节点)。XMPP核心协议通信的基本模式就是先建立一个stream,然后协商一堆安全之类的东西,中间通信过程就是客户端发送XML Stanza,一个接一个的。服务器根据客户端发送的信息以及程序的逻辑,发送XML Stanza给客户端。但是这个过程并不是一问一答的,任何时候都有可能从一方发信给另外一方。通信的最后阶段是</stream>
关闭流。
资料:xmpp基本概念
2.2.4 XMPP协议优点
- 开放:XMPP协议是自由、开放、公开的,并且易于了解。而且在客户端、服务器、组件、源码库等方面,都已经各自有多种实现。
- 标准:互联网工程工作小组(IETF)已经将Jabber的核心XML流协议以XMPP命名,正式列为认可的实时通信及Presence技术。而XMPP的技术规格已被定义在RFC 3920及RFC 3921。任何IM供应商在遵循XMPP协议下,都可与Google Talk实现连接。
- 证实可用:第一个Jabber(现在XMPP)技术是Jeremie Miller在1998年开发的,现在已经相当稳定;数以百计的开发者为XMPP技术而努力。今日的互联网上有数以万计的XMPP服务器运作着,并有数以百万计的人们使用XMPP即时通讯软件。
- 分布式:XMPP网络的架构和电子邮件十分相像;XMPP核心协议通信方式是先创建一个stream,XMPP以TCP传递XML数据流,没有中央主服务器。任何人都可以运行自己的XMPP服务器,使个人及组织能够掌控他们的实时传讯体验。
- 安全:任何XMPP协议的服务器可以独立于公众XMPP网络(例如在企业内部网络中),而使用SASL及TLS等技术的可靠安全性,已自带于核心XMPP技术规格中。
- 可扩展:XML命名空间的威力可使任何人在核心协议的基础上建造定制化的功能;为了维持通透性,常见的扩展有支持音视频传输的扩展协议
Jingle
。 - 弹性佳:XMPP除了可用在实时通信的应用程序,还能用在网络管理、内容供稿、协同工具、文件共享、游戏、远程系统监控等。
- 多样性:用XMPP协议来建造及布署实时应用程序及服务的公司及开放源代码计划分布在各种领域;用XMPP技术开发软件,资源及支持的来源是多样的,使得使你不会陷于被“绑架”的困境。
2.2.5 XMPP的协议缺点
- 数据负载太重:随着通常超过70%的XMPP协议的服务器的数据流量的存在和近60%的数据被重复转发,XMPP协议目前拥有一个大型架构中存在的数据提供给多个收件人。目前新的协议正在研究,以减轻这一问题。
- 没有二进制数据:XMPP协议的方式被编码为一个单一的长的XML文件,因此无法提供二进制数据。因此,文件传输协议一样使用外部的HTTP。如果不可避免,XMPP协议还提供了带编码的文件传输的所有数据使用的Base64。
3 Openfire相关知识
3.1 Openfire的定义
Openfire一款基于Java开发的开源实时协作(RTC)服务器,基于XMPP(Jabber)协议。您可以使用它轻易的构建高效率的即时通信服务器。
Openfire安装和使用都非常简单,并利用Web进行管理。单台服务器可支持上万并发用户。由于是采用开放的XMPP协议,您可以使用各种支持XMPP协议的IM客户端软件登录服务。
资料: 官网 github地址 Openfire教程网
3.2 Openfire的安装配置
安装配置过程请参照:Openfire安装教程
配置完成如下:
3.3 使用Spark登录Openfire
Spark是一款使用java开发的开源即时通讯工具,它可以登录基于XMPP协议搭建的即时通讯服务器并在其之上进行通讯(可理解为精简版QQ)。
登录方式请参考上述Openfire安装教程
博客内容,这里不再赘述。
4 Smack的相关知识
4.1 Smack的定义
Smack是一个开源,易于使用的XMPP(jabber)客户端类库。它封装了针对XMPP协议的即时通讯过程中的一些操作,如登录,注册,发送消息等等,使得开发者不必关心XMPP中大量的xml数据的处理。Spark就是使用了smack开发。
缺点:API并非为大量并发用户设计,每个客户要1个线程,占用资源大,一般1台机器只能模拟有限(数千个)客户。
注:
-
Smack是针对java开发的,所以适用于Android,smack所依赖的jar包可以通过FindJar找到,也可以通过
gradle
引用Maven库里面的library。 -
针对iOS,通常使用第三方库XMPPFramework
-
针对JS,网络上也提供了许多第三方库 Converse.js Strophe.js
4.2 Smack的示例
下面是一段smack的登录示例代码:
XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder()
.setXmppDomain("jabber.org") //xmpp服务器域名
.setHost("earl.jabber.org") //xmpp服务器主机地址
.setPort(8222) //xmpp服务器端口
.build();
AbstractXMPPConnection conn = new XMPPTCPConnection(config);
conn.connect();//建立连接
conn.login("username", "password");//用户登录
smack一直在更新升级,不同版本代码差异巨大,而且官方文档不够详细,网上找的资料基本是旧版本的代码,这个很坑!
5 后记
有兴趣的同学可以去github上看看本人写的安卓端的xmpp示例应用Android XMPP Demo