clq
2020-10-19 16:30:17 发表
编辑
5.
这时候服务器可发送一个包给对方,提示对方也加自己好友。
服务器:
<presence id="19547f14-369c-4d4a-9e84-4d8a12f09be0" to="ccc@127.0.0.1" from="clq@127.0.0.1" type="subscribe">
<status>您好, 我是clq. 我想添加您到我的联系人列表.</status>
<x xmlns="vcard-temp:x:update">
<photo/>
</x>
<c xmlns="http://jabber.org/protocol/caps" hash="sha-1" node="http://gajim.org" ver="EhDgXYarwDkGz8n/wbp2z37FJWE="/>
</presence>
如果对方同意就会回应两个包给服务器:
<presence id="4cx6D-51" to="clq@127.0.0.1" type="subscribed"/> //同意对方添加
id 是新的。
第二个包可以理解为给对方加注释别名,不过实际上是设置好友信息。实际上可以不发。
<iq id="AixN9-131" type="set">
<query xmlns="jabber:iq:roster">
<item jid="clq@127.0.0.1" name="clq">
<group>Friends</group>
</item>
</query>
</iq>
可以看到这就是前述的“单个好友新增通知”。后面还有一些复杂的操作,主要是通知对方有没有加自己为好友。这其实没有必要,而且现代的 im 大都不支持这样做,特别是标准 xmpp 允许对方将自己地址簿中的好友删除,这显然是不合适的。
因此,xmppmini 并不支持后续的操作。
如果不想理会对方本来是可以不回应的,不过在有些服务器环境下比如 openfire 的时候,不回应的话,下次每次你上线的时候都会自动给您发一次。这显然是不符合现在的 im 系统现状的。为了兼容这种情况,还是明确拒绝得了。消息包为
<presence id="4cx6D-51" to="clq@127.0.0.1" type="unsubscribed"/> //拒绝对方添加
可以看到,只是 type 不同罢了。
另外这个提示对方也加自己好友的消息包可以由服务器多次发送,客户端是会多次提示的。
而客户端也可以通过发送以下包多次通过服务器发送这个提示。
这个包实际上是包3和包4的合集,实际上就是重复添加对方为好友的请求,实际上也就是说现在 xmpp 客户端普通是在请求好友时同时发送包3和包4。
clq
2020-10-28 15:36:19 发表
编辑
6.考虑兼容标准 xmpp 服务器的情况下
实际上众多复杂的好友相关操作信息包也只是由三种包组成。
一种是比较简单的 result 的 iq 包。
二是 "jabber:iq:roster" 好友信息 iq 包。
三是 presence 好友关注状态包。
而相关的各种操作是由用户与好友之前的“好友状态”(实际上是相互是否关注状态)决定的。这个状态客户端全部是通过"jabber:iq:roster" 好友信息 iq 包知晓的。
取得这种状态的方法有两个:一是取好友列表,二是取单个好友状态。而取单个好友状态实际上就是添加好友的消息包,服务器对于好友不同的回应也是不同的。
首先,这个状态为消息包中的节点 subscription 的值。
有 none, both, from, to 四种,实际上还有 remove 。
//subscription 关系到联系人状态信息的传输,有 none, both, from, to 四种,实际上还有 remove
//remove 就是对方删除了你的好友。
//none 是你刚建立的地址,但服务器还没同意是否加入你的好友地址簿,要你发出 presence 请求后才修改为 to
//none 也有可能在对方已经删除你的请求下由服务器主动发过来。注意还不是 "remove"。只有对方也主动删除后才会是 "remove"。
//to 表示你加了对方,但对方没加你。并且要对方回复过同意的 presence 包。这时你可看到对方是否上线。
//from 表示对方加了你,你还没加对方。并且要你回复过同意的 presence 包。这时对方可以看到你是否上线。
//both 这时才是双方互相加了好友。 你发送了 jabber:iq:roster set 请求在服务器中加对方地址,同时发送 presence 要求知道对方在线状态,并且对方回复了同意的 presence 包。
//同时对方也这样做了。这种情况下才会是 both 。
//所以 xmppmini 的处理逻辑是,只要 subscription 不是 remove 就应该让对方的消息通过。因为这时候不是你添加过对方,就是你同意过对方添加。
//但只要状态不是 both 就提示你要加一下对方好友。
//所以当明确对方是好友,而状态不是 both 时最好是依次发送三个包:
//同意对方加自己的包(不论对方是否真的请求过);加对方入地址的 jabber:iq:roster set 包;提示对方加自己的 presence 包。
客户端“添加好友”、“设置好友备注”、“取好友间关注状态”实际上是同一个包。可以理解为:“我要设置某个地址为我的好友,备注名为什么什么”。这时候服务会告诉你
“好的,你们现在是好友了,好友间状态是什么什么”另外根据不同的场景还有可能告诉客户端好友的备注是什么什么。之所以不是每次都返回备注,是因为,服务器可能主动发一个包来告诉客户端,对方已经删除了你之类的,其中只包括了好友间的关注状态。
而且,收到这个包时。服务器还会判断是否你加过对方好友(即 subscription 为 none ),如果没有,还会发一个 presence 包给对方,提示对方也加你的好友。
所以说,对于标准 xmpp 来说,这个 subscription 的值是很重要的。
而在 xmppmini 中,我们可以利用这一点来处理好友间的关系。当本地缓存的 subscription 不是 both 时都自动发送一个 "jabber:iq:roster" 的 set 类型 iq 包去设置用户的备注。这样服务器会回一个相同类型的包给我们,我们就知道好友当前与我们的状态了,如果不是 both ,那么我们就需要告诉用户消息有可能无法送达(实际上标准 xmpp 是可以的,不过我们 xmppmini 中必须限制,因为垃圾消息太多了)。同时提醒用户发送一个提醒对方加了我方为好友的 presence 包。
目前的标准 xmpp 服务器会在客户端登录发送 presence 在线包时会判断如果我加了对方对方没加我,就自动提示对方添加自己好友,这样做显然并不好,这不是间接提示对方说我上线了嘛。应当提示用户,让用户自己决定是否提示对方。现在的标准 xmpp 服务器也会在回复的 "jabber:iq:roster" 中说明是否发送过添加好友的请求。也就是 ask 节点中的内容。
clq
2020-10-28 15:47:47 发表
编辑
7.删除好友
有了以上的知识,删除好友就容易理解了。
客户端发送:
<iq xmlns="jabber:client" type="set" id="1674169c-e422-4a05-abd9-a8a90cc75d24" from="clq@127.0.0.1/gajim.6929J2FG">
<query xmlns="jabber:iq:roster">
<item jid="ccc@127.0.0.1" subscription="remove" />
</query>
</iq>
服务器回应两个包。
<iq type="set" id="809-61" to="clq@127.0.0.1/gajim.6929J2FG">
<query xmlns="jabber:iq:roster">
<item jid="ccc@127.0.0.1" name="ccc" ask="unsubscribe" subscription="none">
<group>Friends</group>
</item>
</query>
</iq>
<iq type="set" id="700-64" to="clq@127.0.0.1/gajim.6929J2FG">
<query xmlns="jabber:iq:roster">
<item jid="ccc@127.0.0.1" subscription="remove" />
</query>
</iq>
同时还会给对方一个 set 的好友信息包,是将状态改为 "none",注意还不是 "remove"。只有对方也主动删除后才会是 "remove"。
clq
2020-10-28 16:57:40 发表
编辑
8.
"jabber:iq:roster"
如果是 get 后面的 item 是没有用处的,服务器会返回全部好友信息 .
另外,对于 openfire 这样的标准 xmpp 服务器,如果添加的用户域名是它的它就会判断用户是否存在。不存在的话就不允许添加。反而是不在服务器上的能加上去。
而 xmppmini 中,这是不检测的。客户端主动添加了,就加入到地址簿中。这样才合理。
服务器最好也不要提示是否有这个用户,那样就给黑客留下了机会。相当于告诉它 “没错,有这个手机号,来骚扰它吧。”
NEWBT官方QQ群1: 276678893
可求档连环画,漫画;询问文本处理大师等软件使用技巧;求档softhub软件下载及使用技巧.
但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件.
验证问题说明申请入群原因即可.