在XMPP协议中,咱们使用presence来获取用户是否已经上线以及是否能够通讯的状态。html
为了可以知道本身联系人的状态以及让联系人知道本身的状态,用户上线后须要订阅联系人的状态,联系人也一样须要订阅用户的状态。node
经过下面的消息订阅联系人的状态:编程
<presence from="alice@wonderland.lit" to="sister@realworld.lit" type="subscribe"/>
当联系人接收/拒绝订阅时,会发送消息的消息体(sucribed/unsubscribe)回应。缓存
一般客户端是自动回应这些消息的,当咱们订阅了联系人的状态以后,也会受到联系人的状态变动信息。安全
还能够经过嵌入<show/>(chat/away/xa/dnd)和<status/>元素表示更加丰富的信息。服务器
<presence> <show>away</show> <status>Having a spot of tea</status> </presence>
须要注意的是presence节是占用带宽最多的节,任何对该节内容的扩展都须要慎重。网络
另外,presence还提供priority属性用来标识资源的优先级(-127-128),负数优先级的资源将没法接收消息,除非显式指定,这个特性一般是由服务器实现的。session
另外,咱们能够经过发送directed presence到其余用户,来避免订阅对方信息,很是适合应用于网络而上的简短交流。dom
能够经过发送<presence type=”unavailable” />发送下线通知,服务器会完成消息保存,联系人通知等一系列操做。ide
presence也有其富文本形式,能够包含更多信息,但不建议在presence中使用(资源和带宽)。Publish-Subscribe[XEP-0060]和Personal Eventing Protocal[XEP-0163]提供了相似功能,但presence是针对整个花名册广播的。
服务器返回的花名册中还能够包含更加丰富的信息,包括用户组以及订阅状况。
用户对花名册的修改也能够经过发送IQ-set(rost-push)同步到服务器及其余客户端上(用户可能有手机/pad等)。这种只推送变动的机制能够简化客户端编程并节省流量。
独立消息,将会立刻投递或者缓存,是默认消息类型
用户聊天,经过session创建,一般处理一系列消息
多人聊天,一般此类型会指定一个组件或者模块处理多人聊天,该模块会为每一个参与者发送消息
全体通知,不会缓存,当即投递
错误信息节,反馈错误信息
若是用户不在线,则消息被缓存,用户登陆后,消息推送给用户,并携带消息原始产生时间,用于客户端对消息进行排序。
能够参考Delayed Delivery[XEP-0203]
chat session用于用户频繁交流的状况,这相似于现实状况中的聊天,其创建过程为:双方用户在消息交互中知道了对方的Full JID,所以能够直接通讯,响应的机制称为chat session。
相似于QQ的“正在输入”功能,让交互双方了解即时状态。
该功能扩展由XEP-0085定义。若是用户不但愿对方看到本身的状态,能够选择不响应<active/>节。
已经定义好的状态有:Starting,Active,Composing,Paused,Inactive,Gone
消息相似于:
<message from=you@yourdomain.tld/work to=daughter@yourdomain.tld type="chat"> <body>Hi honey!</body> <active xmlns="http://jabber.org/protocol/chatstates"/> </message>
能够在message消息中加入XHTML用于富文本展现。
协议能够在[XEP-0071]中找到。
<message from=you@yourdomain.tld/home to=friend@theirdomain.tld type="chat"> <body>I love this movie I saw last night, it's awesome!</body> <html xmlns="http://jabber.org/protocol/xhtml-im"> <body xmlns="http://www.w3.org/1999/xhtml"> <p> I <em>love</em>, this new movie I saw last night, it's <strong>awesome</strong>! </p> </body> </html> </message>
很容易注意到,消息中包含一个不包含格式的文本,以及XHTML格式的文本,是由于考虑到客户端若是不支持HTML,也能够正常展现。
HTML节中不能够包含HEAD中的信息,也不能包含脚本(安全性考虑)。
也就是虚拟名片,用户在聊天时能够经过虚拟名片查看相关信息。
参考[XEP-0054]
虚拟名片服务经过发送IQ请求查看和更新,但须要注意的是,更新虚拟名片时须要发送完整的信息而不是只有要更新的部分。
查询请求:
<iq from=mouse@wonderland.lit/pool id="pw91nf84" to=alice@wonderland.lit type="get"> <vCard xmlns="vcard-temp"/> </iq>
返回的消息:
<iq from=alice@wonderland.lit id="pw91nf84" to=mouse@wonderland.lit/pool type="result"> <vCard xmlns="vcard-temp"> <N> <GIVEN>Alice</GIVEN> </N> <URL>http://wonderland.lit/~alice/</URL> <PHOTO> <EXTVAL>http://www.cs.cmu.edu/~rgs/alice03a.gif</EXTVAL> </PHOTO> </vCard> </iq>
更新名片:
<iq from=alice@wonderland.lit/pda id="w0s1nd97" to=alice@wonderland.lit type="set"> <vCard xmlns="vcard-temp"> <N> <GIVEN>Alice</GIVEN> </N> <URL>http://wonderland.lit/~alice/</URL> <PHOTO>
<EXTVAL>http://www.cs.cmu.edu/~rgs/alice03a.gif</EXTVAL> </PHOTO> <EMAIL> <USERID>alice@wonderland.lit</USERID> </EMAIL> </vCard> </iq>
相似于QQ可黑名单机制,能够对某人隐身,不看某人的消息或屏蔽某个域的消息等等;固然也包括对名单的修改。
该功能可支持的粒度很是细,参考标准[XEP-0016],[XEP-0191]。
发送一条消息给多个接受者而不经过聊天室
控制消息过时,避免消息被本地存储以及延时投递等
客户端层面确认消息是否已经送达
在服务器上存储消息,而不是在客户端机器上存储
咱们须要知道系统中有哪些实体,以及该实体支持哪些服务,为了完成这些操做,引入了实体发现和服务发现的概念。
XMPP 服务发现协议[XEP-0030]定义了两个基本的发现方法。首先发现disco#items,disco#info。
<iq from=hatter@wonderland.lit/home id="xl391n47" to="wonderland.lit" type="get"> <query xmlns="http://jabber.org/protocol/disco#items"/> </iq>
<iq from="wonderland.lit" id="xl391n47" to=hatter@wonderland.lit/home type="result"> <query xmlns="http://jabber.org/protocol/disco#items"> <item jid="conference.wonderland.lit"/> <item jid="notify.wonderland.lit"/> </query> </iq>
<iq from=hatter@wonderland.lit/home id="gq02kb71" to="conference.wonderland.lit" type="get"> <query xmlns="http://jabber.org/protocol/disco#info"/> </iq>
<iq from="conference.wonderland.lit" id="gq02kb71" to=hatter@wonderland.lit/home type="result"> <query xmlns="http://jabber.org/protocol/disco#info"> <identity category="conference" type="text" name="Chatrooms"/> <feature var="http://jabber.org/protocol/muc"/> <feature var="jabber:iq:register"/> <feature var="vcard-temp"/> </query> </iq>
服务发现一样适用iq-get的disco#items/disco#info这两个查询操做,只是将查询是服务而非实体。
具体的查询步骤较为复杂。
这种场景应用于用户的花名册向用户返回是否在线的信息,这种判断是否在线的信息带有Full JID,所以能够经过disco#info/disco#item来查询。
可是这种查询可能返回某个Full JID携带的所有信息,致使数据量过大,所以引入了下面的方式。
是对上面方法的改进,经过将实体支持的特性HASH为一组特征吗,客户端接收该特征码后与本地存储进行比较,若是已有该特征码,则能够得到支持的特性列表;若是客户端没有缓冲该特征码,则从新发送disco#info消息获取,并缓存。
采用此种方法能够节省响应的资源。
而且经过presence节就能够获取客户端支持的功能了。
相似于HTML的表单,有工做流的特征,能够实现用户验证码输入和确认等功能。
由[XEP-0004]定义。
3.1 消息在全部的参与者中共享
3.2 全部的参与者都有一个room roster
3.3 参与者都使用其nickname标识,而不是实际的JabberID
3.4 房间共享参与信息
3.5 参与者不只限于人,也能够是服务等
5.1 用户发送presence消息
5.2 聊天室向成员广播该presence
5.3 聊天室向用户发送成员的presence
5.4 聊天室向用户发送一些历史消息好让用户参与讨论,消息数目可配置,且消息带有时间戳
<delay xmlns="urn:xmpp:delay" stamp="2008-11-07T18:42:03Z"/>
5.5 以后的聊天消息再也不携带时间戳
5.6 聊天室之间的消息往来,消息类型为groupchat
<presence from=dormouse@wonderland.lit/sleepspace to=teaparty@conference.wonderland.lit/Dormouse type="unavailable"/>
群组中有多重角色,不一样的角色拥有不一样的权限,能够将用户临时踢出,或加入黑名单等。
具体有: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还能够传输地理信息,文件和进行远程调用等。
实际上就是消息系统中的推模式,主要分三个步骤完成:首先订阅一个主题;其次发布一个消息;最后消息被推送到订阅客户端。[XEP-0060]
订阅者须要订阅一个源,发布者也将消息发布到这个源。
流程:
若是成功则能够接收消息了,若是失败,则有多是要求更多的配置信息
主要分为两个部分。
发布方发布消息到源;服务器将源的消息经过message的形式投递给订阅方。
须要注意的是:发布方只负责将消息推送至源,投递的逻辑由订阅方的服务器完成。
用户能够选择是否在通知中携带payloads,如通知中包含头像信息时,只须要metadata,无需具体的数据。
是否启用payload能够经过配置项deliver_payloads来实现。
是否保存items也是能够配置的,能够经过persist_items配置。
保存/不保存数据的node分别称为persistent nodes/transient node。
nodes及其服务能够经过disco#info/disco#item来查询
返回的结果能够经过以上两个命令进一步查询,直到找到想要订阅的node。
若是用户想订阅某个好友的动态,可使用用户的JID做为datanode,相应的简化协议称为PEP[XEP-0163](Personal Eventing Protocal)。
用户能够应用PEP协议,在本身的Presence消息中包含本身的爱好信息,服务器收到该presence后,将会根据此爱好向用户推送好友的动态。
包括User Tune,User Location,User Activity,User Mood,User Nickname,User Avatar等。