在做添加好友之间,必须要对xmpp的好友订阅有一定的了解,以前我不了解其中原理,盲目的做,以为添加到了各自的列表能够发消息就没事了,后来发现这样会导致很多问题,比如好友上下线无提醒,好友更新了vcard没有提示等一系列和好友相关的问题都出来了。

后来终于重视这个问题,查找相关资料,自行百度,发现很多资料都是只说了单边实现没有设计原理,事实上,那也不算真的实现了,现在我来说下原理和流程,希望对同是做即时通讯的同学们有所帮助;

我们知道,一个好友就对应一个RosterEntry,那我们看怎么来构造一个RosterEntry对象:

/*** Creates a new roster entry.** @param user the user. 用户的jid* @param name the nickname for the entry. 指定给这个用户的昵称(其实我更愿意叫做备注)* @param type the subscription type. 这个用户和我的好友关系类型* @param status the subscription status (related to subscriptions pending to be approbed).这个用户和我的好友状态* @param connection a connection to the XMPP server.连接,不解释*/RosterEntry(String user, String name, RosterPacket.ItemType type,RosterPacket.ItemStatus status, Roster roster, Connection connection) {this.user = user;this.name = name;this.type = type;this.status = status;this.roster = roster;this.connection = connection;}

上面的user和nickname还有Connection相信大家都知道了,Roster是花名册,相信大家也不陌生,通过XmppConnection.getRoster()可以获取到当前连接的花名册,我们重点来说下type和 status是干嘛用的;

凭我们用过qq的经验来看,添加好友是需要有几种状态的,比如我加了你,你同意了,但是你不想把动态让我看到,所以你不一定加我,这就是单方订阅,我加你,但是你拒绝了我 ,那我们就没啥关系,我加了你,你也加了我,那我们就是朋友了,我们是双方订阅,现在我们来捋一捋xmpp中有哪几种状态;

我们先看itemType是个什么鬼,点进去源码看一下;

public static enum ItemType {/*** The user and subscriber have no interest in each other's presence.*/none,/*** The user is interested in receiving presence updates from the subscriber.*/to,/*** The subscriber is interested in receiving presence updates from the user.*/from,/*** The user and subscriber have a mutual interest in each other's presence.*/both,/*** The user wishes to stop receiving presence updates from the subscriber.*/remove}

我们看到,这是一个枚举类型,上面都有注释,为了大家更清楚一些我就给大家翻译一下;none表示我和对方没有任何关系;to表示我发了我请求订阅了对方,对方同意了,但是他没有订阅我;from就是to反过来,他订阅了我,但是我没有订阅他;both表示我们双方互相订阅了;remove表示我想取消以前的订阅;

这种订阅状态是通过发送Presence来实现的。我们结合具体的应用场景来讲一下,怎么来订阅:

一、添加者1、加入到 用户 roster列表<iq type="set"><query xmlns="jabber:iq:roster"><item jid="13548583222@iz28sr0uiyaz" name="13548583222"></item></query></iq>2、发送订阅presence<presence type="subscribe" to="13548583222@iz28sr0uiyaz"></presence>3、对方同意,互相订阅
<presence type="subscribed" to="13548583222@iz28sr0uiyaz"></presence>二、被添加者接受好友添加1 、发送接受请求订阅<presence type="subscribed" to="13548583222@iz28sr0uiyaz"></presence>2、添加到roster列表
<iq type="set"><query xmlns="jabber:iq:roster"><item jid="13548583222@iz28sr0uiyaz"></item></query></iq>3、发送订阅
<presence type="subscribe" to="13548583222@iz28sr0uiyaz"></presence>这时添加者发现已经在花名册中了,只需要发送subscribed就OK了,同时更新自己显示的列表;
添加者:<presence type="subscribed" to="13548583222@iz28sr0uiyaz"></presence>

上面这个流程通过发包的方式呈现,可能大家不是很明白,那么我画一个UML图加深理解;


 到此,两个人就成为了双方的好友了,这时候只要有一方有更新,另一方就会受到与之相关的消息,比如vcard更新,状态更新等;

那么既然加了好友,我们来看下好友列表这块,如果我们只想显示双方都添加对方好友的列表,那我们需要做一个刷选,回归到前面的RosterEntry来,做一个判断:

if ( entry.getType()==ItemType.both) {User user = transEntryToUser(entry);tempUsers.add(user);UserManager.getInstance(mContext).saveUserDetail2Local(user);}

这样的话,好友列表就只有互相都订阅的好友了;

本文属原创,如需转载请注明出处,尊重劳动成果,谢谢!

有问题欢迎下面留言问题;

下面补充一点,关于删除好友出现了删除好友后无需处理就是好友的问题,于是我跟踪了下发送的包,正确的顺序应该是这样的:

如同增加一个名册条目, 如果服务器能成功地处理roster set那么它必须在该用户的名册中更新该条目, 发送一个roster push到该用户的所有感兴趣的资源(其中的'subscription'属性值设为"remove"), 并发送一个IQ result给初始的资源; 详见章节2.3.
另外, 该用户的服务器可能需要生成一个或更多subscription相关的presence节, 如下:
如果该用户对该联系人有一个出席信息订阅, 那么该用户的服务器必须发送一个type为"unsubscribe"的presence节给该联系人(为了对该联系人的出席信息取消订阅).
如果该联系人对该用户有一个出席信息订阅, 那么该用户的服务器必须发送一个type为"unsubscribed"的presence节给该联系人(为了取消该联系人对该用户的订阅).
如果出席信息订阅是相互的, 那么该用户的服务器必须同时发送type为"unsubscribe"presence节和type为"unsubscribed"的的presence节给该联系人.

也就是说,我们需要对于互相订阅的用户,我们需要发送两个presence:

Presence.Type.unsubscribe,和Presence.Type.unsubscribed,同时,我们需要从花名册中移除这个用户:

roster.removeEntry(entry);

asmack搜索添加好友相关推荐

  1. 明日之后怎么找不到朋友服务器,明日之后搜索不到好友 搜索添加好友教程

    1.首先如果你想要加好友,你知道了他的名称,那么你们必须是同一个服务器才行,因为游戏不支持跨服务器体验,所以需要你们同时在一个区里面,这样才可以进行搜索好友添加. 2.其次就是iOS和安卓必须是同时在 ...

  2. 领英改版后无法搜索开发客户?解决方法来了,恢复后可以继续在领英搜索开发客户。

    作为全球最大的职场社交平台,LinkedIn领英截至到2021年11月在全球拥有接近8亿注册用户,3亿多的月活用户,5500多万企业用户. LinkedIn官方数据分布图 尽管与拥有超过10亿用户的I ...

  3. Autojs 微信添加好友脚本

    程序猿日常 大家一起学习参考! 有其他需要的功能脚本可评论留言- 今天分享个微信添加好友脚本,根据手机号搜索添加好友,亮点再添加好友备注时,会填写从支付宝里获取用户的真实姓名 上代码 多多支持下 au ...

  4. 领英更新改版后,怎么登录国际版领英继续搜索开发客户?详细教程

    作为全球最大的职场社交平台,领英截至到2021年11月在全球拥有接近8亿注册用户,3亿多的月活用户,5500多万企业用户. 领英官方数据分布图 尽管与拥有超过10亿用户的Instagram和拥有超过2 ...

  5. 领英关闭中国业务领英职场!怎么保住自己的领英账号和好友并继续使用领英搜索开发客户?

    最近最让外贸人揪心的事情,莫过于领英宣布"领英职场"将于2023年8月9日起正式停止服务- 一.国内版领英职场将停止服务 领英作为全球最大的职场社交平台,根据其官方数据显示,领英全 ...

  6. qq无限时间撤回消息bug_手机QQ新功能汇总,比微信有意思多了

    手机 QQ 的更新相比微信来说更加频繁,虽然多是在小细节上面,但可玩性和实用性都比微信高很多.近期,QQ又为用户准备了不少好玩的更新,一起来看看. 青少年模式上线 打开安卓版新版手机 QQ 的[设置] ...

  7. Linux最佳聊天软件:Skype 4.3轻体验

    Linux最佳聊天软件:Skype 4.3轻体验 自从 2012 年 4 月坚持使用 Linux 单系统以来,对于山寨王腾孙的做派极为厌恶.而自身已没有非要 QQ 不可的场合,所以彻底转向了 Skyp ...

  8. QQ正式上线QID功能 用户可自定义专属身份卡

    12月1日消息,QQ今日正式上线QID功能.用户可设置长度7至10位的ID,ID具有唯一性,一个QQ号仅能对应绑定1个QID.QID内可包含字母.数字,但其中最多包含4个数字.ID确认设置后,可用于搜 ...

  9. Netty网络编程聊天项目

                                     Netty网络编程聊天项目 后端编写 导入依赖    <dependencies><dependency>&l ...

最新文章

  1. PHP MVC框架核心类
  2. jenkins部署流程图_一文教你使用 Jenkins 设计多环境、多项目持续集成环境!
  3. J.U.C并发框架源码阅读(十七)ReentrantReadWriteLock
  4. Menu控件在IE8中子菜单不能正常显示的解决方案(转)
  5. python从入门到实践第二版_【Python入门教程】第二季网络爬虫基础
  6. javascript之函数使用
  7. 项目1-员工(绩效)信息管理系统
  8. ubuntu上打开md文件_Ubuntu 使用教程.md
  9. 金蝶ERP服务器系统中间件,中间件在ERP系统中的作用及发展趋势
  10. 一部火了20年的音乐剧,到底有何魅力?
  11. mysql workbench6.3.5_mysql workbench
  12. 使用 软考免费真题app刷题库 手机小程序版
  13. 前端html-常用分割线
  14. 内向自闭的我,开启了直播首秀
  15. 【油猴脚本】B站弹幕机器人
  16. Git HEAD 分支游离,切回master导致代码丢失的处理
  17. 如何写英文科技论文 papers
  18. Office 365 Certification 考试心得
  19. 扫雷的一个简单实现 - C语言
  20. CSS 空间转换3D和动画

热门文章

  1. 基于SSM的学籍证明打印系统设计与实现。
  2. 微软游戏服务器断网,一玩游戏就断网是什么情况?解决方法分享
  3. windows安装包安装mysql5.7_Windows server 2008 r2上安装MySQL5.7.10步骤
  4. java bigint_Java的long和bigint长度对比详解
  5. 分享几个你看不上但却很暴利的创业项目
  6. [附源码]JAVA+ssm计算机毕业设计高校工资管理系统(程序+Lw)
  7. 幸运字符串(ansistring)
  8. 纯css实现3D立方体
  9. 【git】git冲突解决详解
  10. 锁定计算机后点鼠标屏幕无反应,电脑鼠标点击桌面没有反应怎么办