四、
XMPP-IM (RFC3921)
1、XML Stanza语法
1.1 Message
语法:
类型:
通过属性type指定,可用类型如下:
chat:一对一聊天
error:发送前一消息时发生错误,语法在上一节XMPP-CORE中已经有说明
groupchat:组聊,这个不在本协议范围,需要参考扩展协议JEP-0045
headline:不需要回复的消息
normal:可以是一个一对一的或组聊的消息,这个是缺省类型,也就是说如果不指定type或type的值不可识别,则默认为normal
子元素:
<subject />:消息主题,可以有xml:lang属性,可以有多个subject,通过xml:lang相区分
<body />:消息内容,也可以有xml:lang属性
<thread />:会话线程标识,由发送方创建并在响应包中返回,在stream中必须唯一
1.2 语法
Presence
类型:
unavailable:不在线
subscribe:发送方请求订制接收方的presence
subscribed:发送方已经允许接收方接收presence
unsubscribe:发送方取消订制presence
unsubscribed:订制请求被拒绝或被取消
probe:探测用户当前的presence
error:发送前一presence stanza发生错误
子元素:
<show/>:在线标识,可选值如下:
away:暂时离开
chat:正在聊天中
dnd:繁忙中(Do Not Disturb)
xa:
The entity or resource is away for an extended period (xa = "eXtended Away").
如果没有提供show元素,则默认为在线并available。
<status/>:用自然语言描述的用户在线状态,可以有xml:lang属性,多个status通过xml:lang相区分
<priority/>:标识resource的优生级,取值范围-128~127,默认为0
1.3
IQ
语法
Iq子素都由扩展的命名空间(extended namespace)定义,在jabber:client和jabber:server中只定义了通用的<error/>子元素。
2
、建立Session
在通过stream认证以后(XMPP-Core中已经详细讨论过),client需要与server端建立一个session以进行下一步的通信:
Server advertises session establishment feature to client:
<stream:stream
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'
id='c2s_345'
from='example.com'
version='1.0'>
<stream:features>
<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>
<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>
</stream:features>
Step 1: Client requests session with server:
<iq to='example.com'
type='set'
id='sess_1'>
<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>
</iq>
Step 2: Server informs client that session has been created:
<iq from='example.com'
type='result'
id='sess_1'/>
在建立Session之前,server需要提供一个账号,而账号注册不在本协议范围,需要参考JEP-0077
3
、交换message
格式比较简单,参见协议。
4
、Presence
交换
4.1 initial presence:在建立session以后,client发送一个初始化presence到server,以表示自己已经可能通信。接下来server也需要做两件事:
第一、发送presence probe到联系人清单中subscribed状态的所有用户
第二、广播initial presence到所有的subscription状态的联系人
语法格式具体参见协议。
5
、管理subscription
presence属于个人隐私,要获得某人的presence,必需向对方发送申请,这个是通过presence stanza进行的,语法比较简单,具体参见协议
6
、管理Roster
roster信息位于server端,因此用户可以通过任意的resource访问。
roster通过IQ子元素<query/>管理,命名空间为jabber:iq:roster,query元素可以包含多个item子元素,每一项代表一个联系人,item的主键为JID。
Item中的
subscription
属性说明了相关用户的presence subscription状态,可选值如下:
none:用户与联系人之间没有任何的subscription订制关系;
to:用户有订制联系人的presence信息,但联系人没有订制用户的presence信息;
from:联系人有订制用户的presence信息,但用户没有订制联系人的presence信息;
both:用户与联系人双方之间有相互订制presence信息
每个Item都可以有一个name属性指定昵称。
每个Item可以有一个或多个<group/>子元素,用于联系人分组。
7
、Blocking Communication
很强大的功能,可以灵活设置以阻止特殊的通信,语法如下:
<iq>
<query xmlns='jabber:iq:privacy'>
<list name='foo'>
<item
type='[jid|group|subscription]'
value='bar'
action='[allow|deny]'
order='unsignedInt'>
[<message/>]
[<presence-in/>]
[<presence-out/>]
[<iq/>]
</item>
</list>
</query>
</iq>
8
、总结:message和presence本身还是比较简单,但加上subscription、roster、privacy等等,内容还是很多的,也比较复杂,有些地方还没完全弄懂,需要在进一步的学习和实践在加强。