基于XMPP的即时通讯系统的创建(四)— 协议详解

Presence(http://www.cnblogs.com/jiyuqi/tag/xmpp/)node

在XMPP协议中,咱们使用presence来获取用户是否已经上线以及是否能够通讯的状态。
编程

为了可以知道本身联系人的状态以及让联系人知道本身的状态,用户上线后须要订阅联系人的状态,联系人也一样须要订阅用户的状态。
缓存

经过下面的消息订阅联系人的状态:
服务器

当联系人接收/拒绝订阅时,会发送消息的消息体(sucribed/unsubscribe)回应。
网络

一般客户端是自动回应这些消息的,当咱们订阅了联系人的状态以后,也会受到联系人的状态变动信息。
session

还能够经过嵌入(chat/away/xa/dnd)和元素表示更加丰富的信息。
dom

须要注意的是presence节是占用带宽最多的节,任何对该节内容的扩展都须要慎重。另外,presence还提供priority属性用来标识资源的优先级(-127-128),负数优先级的资源将没法接收消息,除非显式指定,这个特性一般是由服务器实现的。
spa

另外,咱们能够经过发送directed presence到其余用户,来避免订阅对方信息,很是适合应用于网络而上的简短交流。
设计

能够经过发送发送下线通知,服务器会完成消息保存,联系人通知等一系列操做。
orm

presence也有其富文本形式,能够包含更多信息,但不建议在presence中使用(资源和带宽)。Publish-Subscribe[XEP-0060]和Personal Eventing Protocal[XEP-0163]提供了相似功能,但presence是针对整个花名册广播的。

服务器返回的花名册中还能够包含更加丰富的信息,包括用户组以及订阅状况。

用户对花名册的修改也能够经过发送IQ-set(rost-push)同步到服务器及其余客户端上(用户可能有手机/pad等)。这种只推送变动的机制能够简化客户端编程并节省流量。

Instant Messaging

消息发送流程

user1向user2发送消息,user1位于domain1,user2位于domain2

user1的client1向server1发送消息节,server1设置from属性

server1投递消息给server2(直接通讯)

server2收到消息并检查user2是否在线并投递

normal

message消息类型

独立消息,将会立刻投递或者缓存,是默认消息类型

chat

用户聊天,经过session 创建,一般处理一系列消息

groupchat

多人聊天,一般此类型会指定一个组件或者模块处理多人聊天,该模块会为每一个参与者发送消息

headline

全体通知,不会缓存,当即投递

error

错误的信息节,反馈错误信息

延时投递

若是用户不在线,则消息被缓存,用户登陆后,消息推送给用户,而且携带消息原始产生时间,用于客户端对消息进行排序。

Chat session

chat session用于用户频繁交流的状况,这相似于现实状况中的聊天,其创建过程为:双方用户在消息交互中知道了对方的Full JID,所以能够直接通讯,响应的机制称为chat session。

状态通知相似于QQ的“正在输入”功能,让交互双方了解即时状态。该功能扩展由XEP-0085定义。若是用户不但愿对方看到本身的状态,能够选择不响应节。已经定义好的状态有:Starting,Active,Composing,Paused,Inactive,Gone

格式化消息

能够在message消息中加入XHTML用于富文本展现。

协议能够在[XEP-0071]中找到。

vCards

也就是虚拟名片,用户在聊天时能够经过虚拟名片查看相关信息。

阻塞和过滤通讯

相似于QQ可黑名单机制,能够对某人隐身,不看某人的消息或屏蔽某个域的消息等等;固然也包括对名单的修改。

更多消息扩展

Extended Stanza Addressing[XEP-0033]

发送一条消息给多个接受者而不经过聊天室

Advanced Message Processing[XEP-0079]

控制消息过时,避免消息被本地存储以及延时投递等

Message Receipt[XEP-00184]

客户端层面确认消息是否已经送达

Message Archiving[XEP-0136]

在服务器上存储消息,而不是在客户端机器上存储

Service Discovery

咱们须要知道系统中有哪些实体,以及该实体支持哪些服务,为了完成这些操做,引入了实体发现和服务发现的概念。

Using Service Discovery with Servers and Services

服务发现一样适用iq-get的disco#items/disco#info这两个查询操做,只是将查询是服务而非实体。

具体的查询步骤较为复杂。

Using Service Discovery with Clients

Explicit Service Discovery

这种场景应用于用户的花名册向用户返回是否在线的信息,这种判断是否在线的信息带有Full JID,所以能够经过disco#info/disco#item来查询。

可是这种查询可能返回某个Full JID携带的所有信息,致使数据量过大,所以引入了下面的方式

Entity Capabilites: Service Discovery Shorthand

是对上面方法的改进,经过将实体支持的特性HASH为一组特征吗,客户端接收该特征码后与本地存储进行比较,若是已有该特征码,则能够得到支持的特性列表;若是客户端没有缓冲该特征码,则从新发送disco#info消息获取,并缓存。

采用此种方法能够节省响应的资源。

而且经过presence节就能够获取客户端支持的功能了。

Data Forms

相似于HTML的表单,有工做流的特征,能够实现用户验证码输入和确认等功能。

由[XEP-0004]定义。

Multi-Party InteractionMCU 基础多人聊天最初被称为groupchat,后来的迭代版本改进为Multi-User Chat(UMC)[XEP-0045]。MCU的基本思想是用户加入到一个聊天室,而聊天室会组播消息,聊天室起到消息反射器的做用聊天室有以下特征3.1    消息在全部的参与者中共享3.2    全部的参与者都有一个room roster3.3    参与者都使用其nickname标识,而不是实际的JabberID3.4    房间共享参与信息3.5    参与者不只限于人,也能够是服务等聊天室有其本身的JID,且该JID是服务器的一个组件,所以具备不一样的域,如服务器的域称为:wonderland.lit,组件的域为conference.wonderland.lit,实现MCU须要相应的组件,服务器根据域的不一样将消息路由到对应的组件上处理。加入聊天流程5.1    用户发送presence消息5.2    聊天室向成员广播该presence5.3    聊天室向用户发送成员的presence5.4    聊天室向用户发送一些历史消息好让用户参与讨论,消息数目可配置,且消息带有时间戳5.5    以后的聊天消息再也不携带时间戳5.6    聊天室之间的消息往来,消息类型为groupchat若是用户向聊天室的成员发送消息,消息类型为chat,但消息实际上使用用户发送给聊天室的,聊天室会改写from/to字段为实际接受者的JID。若是离开聊天室则会发送退席消息

成员管理

群组中有多重角色,不一样的角色拥有不一样的权限,能够将用户临时踢出,或加入黑名单等。

具体有:outcast,visitor,participant,member,moderator,admin,owner。

另外房间也有不一样的类型,有指定名单的,有临时的,有隐藏的,有固定的等。

昵称

用户能够设置其在聊天室内的昵称,参考In-Band Registration[XEP-0077]。

配置

多人聊天能够进行配置,有很是多的可配置项,列出以下。

配置项

做用

allowinvites

是否容许普通成员邀请

changesubject

是否非管理员可以更改聊天室主题

enablelogging

是否开启记录归档

getmemberlist

是否可以获取成员列表

lang

语言

maxuser

最大参与者数量

membersonly

是否仅会员可加入(适用于member类型聊天室)

persistentroom

房间是否为永久(全部成员退出也不会删除)

presencebroadcast

是否广播presence消息,对大room有用

publicroom

该room是否可被发现

roomadmin

设置room管理员

roomdesc

设置room描述

roomname

设置room名称

roomowner

设置room 全部者

whois

控制是否匿名等

数据传输

除了文字以外,MCU还能够传输地理信息,文件和进行远程调用等。


Publish/Subscribe

实际上就是消息系统中的推模式,主要分三个步骤完成:首先订阅一个主题;其次发布一个消息;最后消息被推送到订阅客户端。[XEP-0060]


Subscriptions

订阅者须要订阅一个源,发布者也将消息发布到这个源。

流程:

用户发送订阅请求

服务器响应该订阅请求

若是成功则能够接收消息了,若是失败,则有多是要求更多的配置信息

订阅者对订阅进行配置(可选)

订阅者请求配置项

源返回订阅配置表单

用户解除订阅

服务器返回解除订阅响应

Publishing and Receiving Notifications

主要分为两个部分。

发布方发布消息到源;服务器将源的消息经过message的形式投递给订阅方。

须要注意的是:发布方只负责将消息推送至源,投递的逻辑由订阅方的服务器完成。

Payloads

用户能够选择是否在通知中携带payloads,如通知中包含头像信息时,只须要metadata,无需具体的数据。

是否启用payload能够经过配置项deliver_payloads来实现。

Items

是否保存items也是能够配置的,能够经过persist_items配置。

保存/不保存数据的node分别称为persistent nodes/transient node。

Discovering Nodes

nodes及其服务能够经过disco#info/disco#item来查询

返回的结果能够经过以上两个命令进一步查询,直到找到想要订阅的node。

Personal Eventing

若是用户想订阅某个好友的动态,可使用用户的JID做为datanode,相应的简化协议称为PEP[XEP-0163](Personal Eventing Protocal)。

用户能够应用PEP协议,在本身的Presence消息中包含本身的爱好信息,服务器收到该presence后,将会根据此爱好向用户推送好友的动态。

包括User Tune,User Location,User Activity,User Mood,User Nickname,User Avatar等。

Design Decision

尽可能不要修改XMPP的核心协议,而是应该试着经过新的namespace去扩展它

因为presence占用了大约90%的数据流量,须要控制presence节中的数据

须要尽可能简化XMPP客户端的设计,尤为是须要减小对服务器端的压力

尽可能重用已有协议,而不是从新设计一个

相关文章
相关标签/搜索