即时消息
会话
XMPP的聊天会话没有进行正式谈判,而是自然地进行。发起对话的实体给应答者的bare JID发送一个消息,并且消息被发起者的服务器使用发起者的full JID贴上邮戳。当应答者发送一个回复时,接收人的服务器也会将应答者的full JID贴到回复的消息上。在这时,发起者知道了应答者的full JID,并且应答者知道了发起者的full JID,然后将相互的XMPP资源标识进行“锁定”。当发送接下来的消息时,两者都相互发送节到full JID,除非收到另外一个人的出席变化为止(这可能触发重新发送一个消息到bare JID)。
会话聊天状态
在会话过程中,有时我们需要知道对方正在处于什么状态,比如,我们发送了一个消息给对方,对方迟迟没有回 。我们不确定他是没有看到,还是正在输入一个很长的回复 。
状态(chat states)的通告,定义在聊天状态通告[XEP-0085]。
聊天状态描述了你所参与的对话,可以是以下状态之一:
- starting
某人开始一个对话,但是你还没有参与进来。 - active
你正参与在对话中。当前你没有组织你的消息,而是在关注。 - composing
你正在组织一个消息。 - paused
你开始组织一个消息,但由于某个原因而停止组织消息。 - inactive
你一段时间里没有参与这个对话。 - gone
你参与的这个对话已经结束(例如,你关闭了聊天窗口)。
在对话期间,聊天状态最可能进行如下变化:在composing状态组织完一个消息后,状态变为active,等待消息的回复。但是,从一个具体状态变化到另一个并不是总是有意义。例如,如果你不暂停一小段时间,在你撰写消息期间,你不能长时间地地变成inactive
例如 :你给对方发送消息的时候加入 active 的状态元素 。然后等待对方回应。
<message from="suke@skh.whu.edu.cn"
to="daughter@skh.whu.edu.cn"
type="chat">
<body>Hi honey!</body>
<active xmlns="http://jabber.org/protocol/ chatstates"/>
</message>
对方在开始进行回复之前,她的客户端发送给你一个聊天状态更新,通过添加一个< composing/>元素到一个空的消息里,说明他正在输入:
<message from="daughter@skh.whu.edu.cn"
to="suke@skh.whu.edu.cn"
type="chat">
<composing xmlns="http://jabber.org/protocol/ chatstates"/>
</message>
vCard
vCard-temp[XEP-0054],能让你发布一个电子商务的卡片,叫做vCard,而且能得到其他人已经发布的vCards。
获取vCard
<iq from="beta@skh.whu.edu.cn"
id="pw91nf84"
to="suke@skh.whu.edu.cn"
type="get">
<vCard xmlns="vcard-temp"/>
</iq>
服务器的回应
<iq from="suke@skh.whu.edu.cn"
id="pw91nf84"
to="beta@skh.whu.edu.cn"
type="result">
<vCard xmlns="vcard-temp">
<N>
<GIVEN>suke</GIVEN>
</N>
<URL>http://sku.whu.edu.cn/~suke/</URL>
<PHOTO>
<EXTVAL>http://www.cs.whu.edu/~rgs/ suke03a.gif</EXTVAL>
</PHOTO>
</vCard>
</iq>
阻止和过滤
1、简单阻止:
-
把 jid="gmz@skh.whu.edu.cn" 加入黑名单
<iq from="suke@skh.whu.edu.cn/Psi" id="yu4er81v" to="suke@skh.whu.edu.cn" type="set"> <block xmlns="urn:XMPP:blocking"> <item jid="gmz@skh.whu.edu.cn"/> </block> </iq>
这个操作背后的操作包括:
- 首先,你需要对对方表示成离线。当你对那个JabberID添加了阻止规则,你的服务器发送出一个不可用的出席包,以便你的老板以为你是离线。从那时起,任何时候你更新你的出席(例如,恢复在线),相关的出席节不会被发送到gmz@skh.whu.edu.cn(似乎你永远不再登陆)。
- 其次,你的服务器需要确认对方不能用任何方式找出你在线。这意味着你的服务器对进来的IQ-get或IQ-set使用< service-unavailable/>错误应答,忽略进来的任何< message/>消息(或再次返回一个< service-unavailable/>错误),并且放弃任何进来的< presence/>节。
- 最后,您的服务器需要防止你做一些愚蠢的事情,比如向你之前的上司发送一个消息或IQ请求,这样它会对任何发送给gmz@skh.whu.edu.cn 向外的节回复一个< not-acceptable/>错误。
2、高级阻止和过滤:
有时候你想通过过滤和阻止拥有更多的控制,例如,当你正在登录到你的IM服务器时,你不想要接收到你200个同事的状态更新,因为这样会占据你非常有限的带宽。在另一方面,你又确实想要接收他们发送给你的消息。而且,你也不想阻止所有进来的出席包,因为你想知道你家里人哪一个在线,你需要一个finer-grained协议来控制你的交通过滤规则。
XMPP再次发挥出它的作用。然后简单通讯阻止使用一个基本的阻止列表,full-featured隐私协议使用一种更高级的隐私列表。一个隐私列表是一个针对所有交通匹配的规则列表,包括进来的和出去的。如果一个规则匹配一个出去的包,与规则相关的行为将作用于包。例如,考虑如下的隐私列表:
<list name="mylist">
<item type="jid" value="gmz@skh.whu.edu.cn"
action="deny" order="1">
<iq/>
<message/>
<presence-out/>
</item>
<item type="group" value="C207" action="deny" order="2">
<presence-in/>
</item>
<item action="allow" order="3"/>
</list>
- 来自gmz@skh.whu.edu.cn的消息和第一条规则匹配。因此,如果你的服务器接收到一个来自你的之前的上司的IQ或消息节,它会忽略这个节或返回一个错误。
- 但是,如果你的服务器接收到一个来自你之前的上司的出席节,并且这个节与第一个隐私规则不匹配,那么你的服务器继续让它与第二条规则匹配。由于你不再和你之前的上司一起工作了,所以他不在你名册里的“工作”组。因此,你的服务器继续下一条规则(这个例子中的最后一个规则)。你瞧,进来的出席节匹配最后一个规则,因此你的服务器允许这个节通过。现在你可以看到你之前的上司是否在线,但是他不能和你进行通讯!
特定隐私规则的结合为允许和阻止通讯提供了一个强大的工具,因为你的隐私列表可以包含无限数量的按照任何顺序的隐私规则(通过< item/>元素标识)。每个给定的规则的行为要么是allow,要么是deny,并且处理节的规则类型是基于一个特定的JabberID、名册分组名或者出席订阅状态。最后,节之间要进行匹配,基于他们是否是消息,是否是进来的出席通告(例如,不包括订阅相关的出席节),是否是出去的出席通告、是否是IQ或所有的节(包括订阅相关的节)。在实践中,这些更高级的阻止和允许的方法提供基本的过滤以代替那些简单的阻止(尽管付出更大的复杂度代价)。
更多聊天扩展
- 可扩展节地址[XEP-0033]让你在没有使用聊天室的情况下,同时发送单个消息给多个接收者。
- 高级消息处理[XEP-0079]提供一种控制消息传递的方式;例子包括消息终止和阻止消息因为延迟传递而被脱机存储。
- 消息回执[XEP-0184] 基于标题做你所期望做的:它提供一个端到端的机制来决定是否目的接收人真正的接收到了这个消息。
- 消息归档[XEP-0136]定义了一种在服务器上存储消息的技术,而不是将他们存储到你的本地机子上。