我正在使用 Smack 3.1.0,在添加联系人时,无法获得订阅 "both"。谁能帮助我?以下是我的代码:
Roster.setDefaultSubscriptionMode(Roster.SubscriptionMode.accept_all);
Roster roster = connection.getRoster();
roster.createEntry("buddy@test.com","me",null)
代码执行后,我在Openfire中观察到该订阅为“to”。
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);
RFC6121第3.1节是目前最好的参考,用于说明这项工作原理。
双方用户都需要相互订阅,通过发送出席订阅的 stanza。在 Smack 中:
Presence presence = new Presence(Presence.Type.subscribe);
presence.setTo(jid);
connection.sendPacket(presence);
RFC6121的3.1节将为您提供语义细节。
好的,我为此努力了几天,最终让事情有了进展。感谢 @Joe Hildebrand 的回答,让我找到了解决问题的正确方向。我已经采用手动订阅模式(即用户需要手动接受另一个用户的请求)来实现它。
如果用户尚未发送订阅或取消订阅请求,服务器会不断地向用户推送订阅请求。因此,您可以将收到的订阅请求保存在本地列表中,并将其显示为“好友请求列表”,以供手动接受/拒绝。如果您的应用程序重新启动(从而重新连接到服务器),服务器将再次推送订阅请求。
它是如何工作的:
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
}
}
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();
}
}