【问题标题】:how to add roster with subscription mode "both"如何使用订阅模式“两者”添加名册
【发布时间】:2011-08-13 17:48:24
【问题描述】:

我正在使用 smack 3.1.0,当我添加花名册时,我无法订阅“两者”。谁能帮我? 以下是我的代码:

Roster.setDefaultSubscriptionMode(Roster.SubscriptionMode.accept_all);
Roster roster = connection.getRoster();
roster.createEntry("buddy@test.com","me",null)

代码执行后,我在openfire中观察到订阅是“to”

【问题讨论】:

    标签: java xmpp smack


    【解决方案1】:

    重写@mschonaker 的答案以更清楚一点。

    两个用户需要相互订阅接受他们收到的订阅请求。让我们称他们为爱丽丝和鲍勃。 Alice 向 Bob 发送订阅请求:

    Presence subscribe = new Presence(Presence.Type.subscribe);
    subscribe.setTo('bob@example.com');
    connection.sendPacket(subscribe);
    

    当 Bob 收到请求时,他会批准它:

    Presence subscribed = new Presence(Presence.Type.subscribed);
    subscribed.setTo('alice@example.com');
    connection.sendPacket(subscribed);
    

    Bob 也可能对 Alice 的存在感兴趣,所以他订阅了她:

    Presence subscribe = new Presence(Presence.Type.subscribe);
    subscribe.setTo('alice@example.com');
    connection.sendPacket(subscribe);
    

    Alice 需要批准 Bob 的请求:

    Presence subscribed = new Presence(Presence.Type.subscribed);
    subscribed.setTo('bob@example.com');
    connection.sendPacket(subscribed);
    

    Section 3.1 of RFC6121 是目前关于其工作原理的最佳参考。

    【讨论】:

    • 你好。但是在哪里编写这两个订阅双方的代码
    • 如果我使用订阅我必须在这里使用 JID subscribed.setTo(jid);我可以向我的帐户添加条目,但我没有看到该条目。告诉我我该怎么做。
    • @JoeHildebrand 我正在以同样的方式做这些事情,但没有收到任何订阅通知。请看stackoverflow.com/questions/16815531/…
    • 为什么在 bob 订阅 alice 之后 bob 再次向 alice 发送请求....我们可以像 facebook 请求那样以简单的方式实现吗?如果爱丽丝将请求发送给鲍勃。鲍勃会接受它,然后两人都成为朋友@Joe Hildebrand
    • 优秀的例子@JoeHildebrand 非常感谢您的回答。我想问一个问题,我的情况是,当用户 A 订阅用户 B 时,当用户 B 订阅用户 A 时,用户 B 自动订阅用户 A,你得到了我想说的话。
    【解决方案2】:

    两个用户都需要互相订阅。通过发送出席信息订阅节。在 Smack 中:

        Presence presence = new Presence(Presence.Type.subscribe);
        presence.setTo(jid);
        connection.sendPacket(presence);
    

    Section 3.1 of the RFC6121 会给你语义细节。

    【讨论】:

    • 非常感谢,这正是我想要的!
    • 如果用户是从任何其他来源添加的,则侦听数据包侦听器并将订阅发送到 jid,这就是它的工作原理,您可以在名册列表中看到订阅为“两者”。如果使用 subscribed 类型,则订阅将来自 (roster 发送请求) 和 to(roster 发送请求)
    • 你好。但是在哪里编写这两个订阅双方的代码
    • RFC3921 已被 RFC6121 淘汰。此外,您的代码没有多大意义,因为您正在订阅,而不是取消订阅,并且“存在”不是当前范围内的变量。
    • 优秀的例子非常感谢答案。我想问一个问题,我的情况是,当用户 A 订阅用户 B 时,当用户 B 订阅用户 A 时,用户 B 自动订阅用户 A,你得到我想说的话了吗?
    【解决方案3】:

    好的,我为此努力了几天,终于让事情顺利进行了。谢谢@Joe Hildebrand,您的回答让我走上了解决这个问题的正确轨道。我已经实现了手动订阅模式(即用户需要手动接受另一个用户的请求)。

    如果用户没有发回订阅或取消订阅,服务器会继续向用户推送订阅请求(在重新登录时)。因此,您可以将传入的订阅请求本地保存在列表中,并将其显示为“好友请求列表”以供手动接受/拒绝。如果您的应用程序重新启动(并因此重新连接到服务器),服务器将再次推送订阅请求。

    这就是它的工作原理:

    • User1 向 User2 发送订阅状态。
    • 名册条目会自动在 User1 的名册中创建(但不在 User2 的名册中)。
    • User2 收到来自 User1 的订阅请求。
    • User2 向 User2 发回订阅状态(User2 > User1 订阅完成)。
    • User2 检查 User1 是否在 User2 的名单中。 User1 不在 User2 的名单中。 User2 向 User1 发回订阅状态。
    • 在 User2 的花名册中自动创建花名册条目。
    • User1 接收来自 User2 的订阅状态。
    • User1 检查 User2 是否在 User1 的名单中。 User2 在 User1 的名单中。用户 1 向用户 2 发回订阅状态(用户 2 > 用户 1 订阅完成)。

              final Presence newPresence = (Presence) packet;
              final Presence.Type presenceType = newPresence.getType();
              final String fromId = newPresence.getFrom();
              final RosterEntry newEntry = getRoster().getEntry(fromId);
      
              if (presenceType == Presence.Type.subscribe)
              {
                  //from new user
                  if (newEntry == null)
                  {
                      //save request locally for later accept/reject
                      //later accept will send back a subscribe & subscribed presence to user with fromId
                      //or accept immediately by sending back subscribe and unsubscribed right now
                  }
                  //from a user that previously accepted your request
                  else
                  {
                      //send back subscribed presence to user with fromId
                  }
              }
      

    【讨论】:

      【解决方案4】:

      如果您使用的是开放式服务器,您也可以使用User Service plugin,这将创建同时订阅的名册...

      【讨论】:

        【解决方案5】:

        我遇到了同样的问题,但我得到了解决方案如何订阅设置'both'

        当您添加用户时,以下是向用户发送订阅

         Presence pres = new Presence(Presence.Type.subscribed);
                pres.setPriority(24);
                pres.setMode(Presence.Mode.available);
                pres.setTo(friendJid);
        
                RoosterConnection.getConnection().sendStanza(pres);
        

        并且接收端放在连接类中的方法下面,presenceChanged是RosterListener的默认方法。

         @Override
        public void presenceChanged(Presence presence) {
            mBus.post(presence);
            try {
                Presence pres = new Presence(Presence.Type.subscribed);
                pres.setTo(presence.getFrom());
                RoosterConnection.getConnection().sendStanza(pres);
            } catch (SmackException.NotConnectedException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2018-08-30
          • 1970-01-01
          • 2016-08-12
          • 1970-01-01
          • 2018-02-11
          • 2016-12-14
          • 2012-10-01
          • 2017-01-11
          • 1970-01-01
          相关资源
          最近更新 更多