Roster和Presence

Roster(花名册)可以跟踪其他用户的可用性(“状态”)。Roster还可以为用户分组,如“朋友”和“同事”。其他即时通讯系统参考名单的好友列表,联系人列表等。

Roster实例使用 Roster.getInstanceFor(XMPPConnection) 方法获得.

Roster Entries(Roster 条目)

每个用户在Roster中由RosterEntry表示,这包括:

  • 一个XMPP地址 (例如: jsmith@example.com).
  • 一个你分配给用户的名字(如:”Joe”).
  • entry归属的Roster中的groups列表。如果Roster entry没有对应的group,被称为一个”unfiled entry”。

下面的代码片段打印Roster中的所有entry:

  1. Roster roster = Roster.getInstanceFor(connection);
  2. Collection<RosterEntry> entries = roster.getEntries();
  3. for (RosterEntry entry : entries) {
  4. System.out.println(entry);
  5. }

也可能用方法获得单个的entry、列出未分类的entry、得到一个或全部的group。

Roster中的每个登陆有presence与之关联。Roster.getPresence(String user)方法可以返回一个用户Presence的对象,如果用户不在线或您没有订阅用户的presence将会返回null

注意:一般而言,presence预订一般受用户是否在roster中的约束,但这并不适应所有情况。

一个用户可以有在线或离线两种presence。当用户在线时,他们的可能包含外延信息,如他们正在做什么,他们是否愿意被打扰等等。参考Presence类以获得更多细节信息。

监听Roster和Presence变化

roster类的典型应用就是显示组的树型视图和含有当前presence值的登陆。作为一个例子,参考右图所示的一个Exodus XMPP客户端的roster

presence信息很可能经常变化,roster登陆也可能经常改变或被删除。
为了监听rosterpresence数据的变化,您应该使用RosterListener
下面的代码片段注册了一个rosterRosterListener,它能够在标准输出中打印任何presence的变化。一个标准的客户端可以使用类似的代码用变化的信息来更新roster用户界面。

  1. Roster roster = Roster.getInstanceFor(con);
  2. roster.addRosterListener(new RosterListener() {
  3. // Ignored events public void entriesAdded(Collection<String> addresses) {}
  4. public void entriesDeleted(Collection<String> addresses) {}
  5. public void entriesUpdated(Collection<String> addresses) {}
  6. public void presenceChanged(Presence presence) {
  7. System.out.println("Presence changed: " + presence.getFrom() + " " + presence);
  8. }
  9. });

向Roster中添加Entries

rosterpresence使用一种基于许可的模式,用户只有在被许可的情况下才能被添加到别人的roster中。这样可以保护用户的隐私因为只有经核准的其它用户才能查看他们的 presence信息。因此,只有当其它用户接受您的请求时您才能添加新的roster登陆。

如果一个用户请求presence预订,因此他们可以把您添加到他们的roster中,您必须接受或拒绝该请求。 Smack通过以下三种方式中的一种处理presence预订请求:

  • 自动接受所有presence预订请求。
  • 自动拒绝所有presence预订请求。
  • 手动处理presence预订请求。

通过Roster.setSubscriptionMode(int subscriptionMode)方法设置对请求的处理方式。简易客户端通常使用一种自动方式处理预订请求,而复杂客户端应该手动处理方式,请最终用户接受或拒绝请求。如果使用手动方式,应该注册一个PacketListener以监听Presence.Type.SUBSCRIBE类型的Presence packet