IM - XMPP简介

1. 概述

XMPP是一个可扩展的消息与空间协议(Extensible Messaging and Presence Protocol)。

该协议的前身是Jabber(诞生于1999年),以XML为协议载体,具备良好的扩展性。不仅可以传输简单的文本,而且可以携带复杂的数据和各种格式的文件,也就是说XMPP协议不仅可以用在人与人之间的交流,而且可以实现软件与软件软件与人之间的交流,目前支持XMPP协议的即时通讯工具有Gtalk、FaceBook IM、Twitter、网易POPO等等通讯工具。

XMPP有非常丰富的生态资源,例如

如何快速开始XMPP之旅,可以参考:https://xmpp.org/getting-started/

本文重点介绍XMPP协议实现Openfire服务Gajim和Conversejs客户端,对XMPP有一些初步的认识。

XMPP简介

2. 协议介绍

2.1. 优缺点对比

优点

去中心化架构,支持c2s/s2s通信

有利于保障了数据安全,且提高了整个XMPP网络的健壮性

支持c2s/s2s通信

支持扩展协议

Having 459 XEPs(XMPP Extension Protocols):https://xmpp.org/extensions/

Key XMPP technologies(XEPs):

  • Core — information about the core XMPP technologies for XML streaming
  • Jingle — SIP-compatible multimedia signalling for voice, video, file transfer, and other applications
  • Multi-User Chat — flexible, multi-party communication
  • PubSub — alerts and notifications for data syndication, rich presence, and more
  • BOSH — an HTTP binding for XMPP (and other) traffic

Jabber ID (JID)

Jabber Identifiers (JIDs) uniquely identify individual entities in the Jabber network.

  • Template
<JID> = [<node>"@"]<domain>["/"<resource>]
  • Example
UserID: h2018450@openfire.main.server
ServerID: openfire.main.server
分布式部署

缺点

  • XML相比Json,略显臃肿
  • 协议没有区分对待控制信令数据传输,比如从通信通道处理优先级等方面

2.2. 协议样例

2.2.1. 三大顶层通信元素

<presence/> - to exchange presence information

允许用户广播其在线状态和可用性,可以是online、offline、available、unavailable、hide等

<presence from=user1@jabber.org to=user2@jabber.org>
    <status>online</status>
<presence/>

<iq/> - for command exchanges

Information/Query,信息/查询请求,是一个请求/响应机制,用来发送和获取两个实体之间的信息,允许他们通过xml格式完成查询和响应

IQ元素用于不同的目的,它们之间通过不同的命名空间来加以区分。在Jabber/XMPP消息协议里有许多的命名空间,最常用的命名空间是:"jabber:iq:register","jabber:iq:auth","jabber:iq:roster"

  • 创建一个新session
c: <iq to='example.com' type='set' id='sess_1'>  
      <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>  
   </iq>
s: <iq from='example.com' type='result' id='sess_1'/>

<message/> - to transfer messages

用于两个用户之间发送消息

<message from='juliet@example.com' to='romeo@example.net'>
    <body>Are you ok?</body>
</message>

2.2.2. XMPP通信样例

   ...  start a new xmpp stream as below ...
   C: <?xml version='1.0'?>
      <stream:stream
          to='example.com'
          xmlns='jabber:client'
          xmlns:stream='http://etherx.jabber.org/streams'
          version='1.0'>
   S: <?xml version='1.0'?>
      <stream:stream
          from='example.com'
          id='someid'
          xmlns='jabber:client'
          xmlns:stream='http://etherx.jabber.org/streams'
          version='1.0'>

   ...  encryption and resource binding ...

   ...  authentication as below ...
   C: <iq type='get' to='shakespeare.lit' id='auth1'>
          <query xmlns='jabber:iq:auth'>
             <username>bill</username>
          </query>
      </iq>
   S: <iq type='result' id='auth1'>
          <query xmlns='jabber:iq:auth'>
              <username/>
              <password/>
              <digest/>
              <resource/>
          </query>
      </iq>
   C: <iq type='set' id='auth2'>
          <query xmlns='jabber:iq:auth'>
              <username>bill</username>
              <password>Calli0pe</password>
              <resource>office</resource>
          </query>
      </iq>
   S: <iq type='result' id='auth2'/>

   ...  simple chat as below ...
   C:   <message from='juliet@example.com'
                 to='romeo@example.net'
                 xml:lang='en'>
   C:     <body>Art thou not Romeo, and a Montague?</body>
   C:   </message>
   S:   <message from='romeo@example.net'
                 to='juliet@example.com'
                 xml:lang='en'>
   S:     <body>Neither, fair saint, if either thee dislike.</body>
   S:   </message>

   ...  close stream as below ...
   C: </stream:stream>
   S: </stream:stream>

参考:https://wiki.xmpp.org/web/Programming_XMPP_Clients

3. 服务端

3.1. Openfire

An XMPP server licensed under the Open Source Apache License.

采用Java开发,Github拥有2.4K star,持续更新中。

3.1.1. 如何搭建

  • 启动openfire服务
docker run --name openfire -d --rm \
  -p 0.0.0.0:9090:9090 \
  -p 0.0.0.0:5222-5223:5222-5223 \
  -p 0.0.0.0:5269:5269 \
  -p 0.0.0.0:7070:7070 \
  -p 0.0.0.0:7443:7443 \
  -p 0.0.0.0:7777:7777 \
  -v `pwd`/data:/var/lib/openfire \
  gizmotronic/openfire:4.4.4
  • 访问9090端口,配置postgres数据库(也可以选择embedded database
Database URL: jdbc:postgresql://10.211.28.93:35432/openfiredb
Username/Password: openfire/openfire
openfire dashboard

3.1.2. 测试登录、注册和收发消息

  • 通过ClientOpenfire Dashboard可以完成新用户注册
http://10.211.28.93:9090/user-summary.jsp
  • 通过两个客户端ConversejsGajim可以完成用户登录与收发消息

  • 通过Openfire Dashboard可以完成对所有在线用户的消息广播

3.1.3. 增加两个plugin

56个Plugins,包含websocket、restful-api、draw-io、emails等功能:
https://www.igniterealtime.org/projects/openfire/plugins.jsp

尝试了两个:

  • inVerse: Adds the (third-party, Converse-based) inVerse web client to Openfire.
  • Openfire Meetings: Provides high quality, scalable video conferences.

3.2. Ejabbed

Robust, Scalable and Extensible Realtime Platform (XMPP, MQTT, SIP Server).

采用Erlang开发,Github拥有4.9K star,持续更新中。

3.3. Jackal

An XMPP server written in Go.

采用Go开发,Github拥有1.1K star,持续更新中。

4. 客户端

4.1. Gajim

A fully-featured XMPP client.

采用Python3+GTK开发,支持主流OS,包含Windows/Linux/MacOS等。

Screenshots

contact list

tabbed chat

groupchat window

4.2. Conversejs

A free and open-source XMPP chat client in your browser.

Converse is a web based XMPP/Jabber chat client.

You can either use it as a webchat app, or you can integrate it into your own website.

It's 100% client-side JavaScript, HTML and CSS and the only backend required is a modern XMPP server.

Screenshots

login window
chat window

5. 总结

XMPP历史悠久,生态也很健全。如果对XMPP/Openfire采用的技术不介意,且比较擅长,例如Java开发语言、XML数据流、单体服务,可以在此基础上二次开发。

其实,现在的互联网环境和10几年前相比有很多不同,例如微服务架构、消息中间件、内存数据库、Json数据、Go/Python高级开发预研等。如果IM是核心功能,而不是附属功能的话,建议自行开发设计,可以参考XMPP/Openfire/Gajim/Conversejs等优秀技术。

6. Next

  • Openfire集群搭建
  • Openfire内部架构与实现探究

7. 扩展

四种即时通讯协议对比参考。其中,XMPP应用更广泛,在多个方面更有优势。

  • IMPP(Instant Messaging And PresenceProtocol): 即时信息和空间协议
  • PRIM(Presence and Instant Messaging Protocol): 空间和即时信息协议
  • SIP(Session Initialion Protocol): 回话发起协议
  • XMPP(Extensible Messaging and Presence Protocol): 可扩展消息与存在协议
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 关于XMPP最权威的讲解:http://www.jabbercn.org/RFC3920(这个才是最权威的,下面文...
    随风飘荡的小逗逼阅读 1,556评论 1 5
  • 即时通讯系列阅读 即时通讯基础 即时通讯:XMPP基础 即时通讯:XMPP项目实践-微聊 Smack类库最好的学习...
    JackChen1024阅读 3,829评论 0 11
  • 前面关于即时通讯基础Socket,大家学习使用XMPP之前可以先看看即时通讯系列之Socket简介 前言 前段时间...
    音符上的码字员阅读 4,334评论 3 16
  • 关于xmpp网上资料太多了,可是没有找到一篇比较全面文章,都是得自己东平西凑的学习,这样学比较费劲,于是自己整理多...
    打火石阅读 3,299评论 4 19
  • 要学习基于XMPP协议的IM开发,首先要熟悉XMPP协议本身。 XMPP协议的组成主要的XMPP 协议范本及当今应...
    RichieQ阅读 1,918评论 0 6