如何使用订阅模式“两者”添加名册

发布于 2024-11-03 10:50:10 字数 399 浏览 6 评论 0原文

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

Roster.setDefaultSubscriptionMode(Roster.SubscriptionMode.accept_all);
Roster roster = connection.getRoster();
roster.createEntry("[email protected]","me",null)

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

i'm using smack 3.1.0, and when i add a roster,i can't get subscription "both". who can help me?
below is my code:

Roster.setDefaultSubscriptionMode(Roster.SubscriptionMode.accept_all);
Roster roster = connection.getRoster();
roster.createEntry("[email protected]","me",null)

after the code execution, i observed in openfire the subscription is "to"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

↘紸啶 2024-11-10 10:50:10

重写 @mschonaker 的答案,使其更清晰一些。

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

Presence subscribe = new Presence(Presence.Type.subscribe);
subscribe.setTo('[email protected]');
connection.sendPacket(subscribe);

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

Presence subscribed = new Presence(Presence.Type.subscribed);
subscribed.setTo('[email protected]');
connection.sendPacket(subscribed);

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

Presence subscribe = new Presence(Presence.Type.subscribe);
subscribe.setTo('[email protected]');
connection.sendPacket(subscribe);

并且 Alice 需要批准 Bob 的请求:

Presence subscribed = new Presence(Presence.Type.subscribed);
subscribed.setTo('[email protected]');
connection.sendPacket(subscribed);

RFC6121 的第 3.1 节 是当前有关其工作原理的最佳参考。

Rewriting @mschonaker's answer to be a little more clear.

Both users need to subscribe to each other and accept the subscription request they received. Let's call them Alice and Bob. Alice sends a subscription request to Bob:

Presence subscribe = new Presence(Presence.Type.subscribe);
subscribe.setTo('[email protected]');
connection.sendPacket(subscribe);

When Bob receives the request, he approves it:

Presence subscribed = new Presence(Presence.Type.subscribed);
subscribed.setTo('[email protected]');
connection.sendPacket(subscribed);

Bob may also be interested in Alice's presence, so he subscribes to her:

Presence subscribe = new Presence(Presence.Type.subscribe);
subscribe.setTo('[email protected]');
connection.sendPacket(subscribe);

And Alice needs to approve Bob's request:

Presence subscribed = new Presence(Presence.Type.subscribed);
subscribed.setTo('[email protected]');
connection.sendPacket(subscribed);

Section 3.1 of RFC6121 is the current best reference for how this works.

谁对谁错谁最难过 2024-11-10 10:50:10

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

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

RFC6121 的第 3.1 节将为您提供语义详细信息。

Both users need to subscribe to each other. By sending a presence subscription stanza. In Smack:

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

Section 3.1 of the RFC6121 will give you the semantic details.

忘羡 2024-11-10 10:50:10

好吧,我努力了几天,终于把事情搞定了。谢谢@Joe Hildebrand,你的回答让我走上了解决这个问题的正确道路。我已经用手动订阅模式实现了它(即用户需要手动接受另一个用户的请求)。

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

其工作原理如下:

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

     Final Presence newPresence = (Presence) packet;
            最终 Presence.Type PresenceType = newPresence.getType();
            最终字符串 fromId = newPresence.getFrom();
            最终 RosterEntry newEntry = getRoster().getEntry(fromId);
    
            if (presenceType == Presence.Type.subscribe)
            {
                //来自新用户
                if (newEntry == null)
                {
                    //在本地保存请求以供以后接受/拒绝
                    //稍后接受将发回订阅&使用 fromId 向用户订阅状态
                    //或者通过立即发送回订阅和取消订阅来立即接受
                }
                //来自之前接受过您请求的用户
                别的
                {
                    //使用fromId将订阅的状态发送回给用户
                }
            }
    

Okay, I toiled hard at this for a couple of days and finally got things working. Thank you @Joe Hildebrand, your answer put me on the right track to solve this. I have implemented it with a manual subscription mode (ie. user needs to accept another user's request manually).

The server keeps pushing subscribe request to the user (upon re-login) if the user hasn't sent a subscribed or unsubscribed back. So what you can do is save the incoming subscribe requests locally in a list and display that as a "friend request list" for manual accept/reject. If your application gets restarted (and hence re-connects to server), the server will push subscribe requests again.

This is how it works:

  • User1 sends subscribe presence to User2.
  • Roster entry gets automatically created in User1's roster (but not in User2's roster).
  • User2 receives subscribe request from User1.
  • User2 sends back a subscribed presence to User2 (User2 > User1 subscription complete).
  • User2 checks if User1 is in User2's roster. User1 is not in User2's roster. User2 sends back a subscribe presence to User1.
  • Roster entry gets automatically created in User2's roster.
  • User1 receives subscribe presence from User2.
  • User1 checks if User2 is in User1's roster. User2 is in User1's roster. User1 sends back a subscribed presence to User2 (User2 > User1 subscription complete).

            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
                }
            }
    
慈悲佛祖 2024-11-10 10:50:10

如果您使用的是 open fire 服务器,您还可以使用 用户服务插件 这将创建具有订阅的名册...

If you are using open fire server you can also use User Service plugin which will create roster with subscription both...

葵雨 2024-11-10 10:50:10

我遇到了同样的问题,但我得到了解决方案,如何订阅设置“两者”,

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

 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();
    }
}

Same problem I was face but I got the solution how subscribe set 'both'

Below is sending subscription to user, when you added the user

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

        RoosterConnection.getConnection().sendStanza(pres);

and Receiving end put below method in connection class and presenceChanged is default method of 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();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文