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

推荐阅读更多精彩内容

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