如何在 xmpp 中将用户添加到名册?

Posted

技术标签:

【中文标题】如何在 xmpp 中将用户添加到名册?【英文标题】:How to add users to a roster in xmpp? 【发布时间】:2015-11-26 04:23:05 【问题描述】:

我已经使用以下代码成功创建了一个用户:

accountmanager = new org.jivesoftware.smack.AccountManager(connection);
accountmanager.createAccount(fbuserid,fbuserid);

但我无法使用以下代码将其他用户添加到已登录用户的名单中:

 public void createEntry(String user, String name, String[] groups) throws XMPPException 
    // Create and send roster entry creation packet.
    RosterPacket rosterPacket = new RosterPacket();
    rosterPacket.setType(IQ.Type.SET);
    RosterPacket.Item item = new RosterPacket.Item(user, name);
    if (groups != null) 
        for (String group : groups) 
            if (group != null) 
                item.addGroupName(group);
            
        
    
    rosterPacket.addRosterItem(item);
    // Wait up to a certain number of seconds for a reply from the server.
    PacketCollector collector = connection.createPacketCollector(
            new PacketIDFilter(rosterPacket.getPacketID()));
    connection.sendPacket(rosterPacket);
    IQ response = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
    collector.cancel();
    if (response == null) 
        throw new XMPPException("No response from the server.");
    
    // If the server replied with an error, throw an exception.
    else if (response.getType() == IQ.Type.ERROR) 
        throw new XMPPException(response.getError());
    

    // Create a presence subscription packet and send.
    Presence presencePacket = new Presence(Presence.Type.subscribe);
    presencePacket.setTo(user);
    connection.sendPacket(presencePacket);

我总是得到空的响应。有人请帮我解决这个问题并提前致谢

【问题讨论】:

是你的代码,还是 Smack 的 Roster 类的主体?您收到的是XMPPError 还是XMPPException - 只是“服务器没有响应”? 它是 Smack 的 Roster 类的主体,我得到了 XMPP 异常。 你在测试你自己的服务器吗? - 检查日志。如果是第 3 方,请联系系统管理员,因为服务器端存在某种错误(但不是未经检查的错误)、名册创建被禁止或服务器实现不符合 XEP。 【参考方案1】:

名册和状态使用基于权限的模型,其中用户必须先授予权限,然后才能将其添加到其他人的名册。这通过确保只有经过批准的用户才能查看他们的存在信息来保护用户的隐私。因此,当您添加新的名册条目时,它将处于待处理状态,直到其他用户接受您的请求。

如果其他用户请求在线状态订阅以便将您添加到他们的名单中,您必须接受或拒绝该请求。 Smack 通过以下三种方式之一处理在线状态订阅请求:

自动接受所有在线状态订阅请求。 自动拒绝所有在线状态订阅请求。 手动处理在线状态订阅请求。模式可以使用 Roster.setSubscriptionMode(Roster.SubscriptionMode) 方法。简单客户端通常使用其中一种自动订阅模式,而全功能客户端应手动处理订阅请求并让最终用户接受或拒绝每个请求。如果使用手动模式,则应注册一个 PacketListener 来侦听 Presence.Type.subscribe 类型的 Presence 数据包。

首先在代码中尝试此操作,以在名册中添加用户并请求用户权限。

    roster = Roster.getInstanceFor(connection);
            if (!roster.isLoaded())
                try 
                    roster.reloadAndWait();
                 catch (SmackException.NotLoggedInException e) 
                    Log.i(TAG, "NotLoggedInException");
                    e.printStackTrace();
                 catch (SmackException.NotConnectedException e) 
                    Log.i(TAG, "NotConnectedException");
                    e.printStackTrace();
                
   roster.createEntry(jID, name, null);

在另一个用户端/从一个用户登录后在您的代码中:

    roster.setSubscriptionMode(Roster.SubscriptionMode.accept_all);

使用户状态在线:

    Presence presence = new Presence(Presence.Type.available);
            presence.setStatus("Online, Programmatically!");
            presence.setPriority(24);
            presence.setMode(Presence.Mode.available);
            roster = Roster.getInstanceFor(connection);

【讨论】:

调用 createEntry() 时出现空指针异常 名册可能没有正确初始化。在我的情况下,我已经像上面一样初始化,检查编辑后的答案。

以上是关于如何在 xmpp 中将用户添加到名册?的主要内容,如果未能解决你的问题,请参考以下文章

如何在名册中添加联系人而不在 xmpp 聊天中发送和接受订阅请求

如何使用 simple-xmpp/node-xmpp 获得 Jabber 用户的名册?

xmpp 框架 - 检测更改的花名册列表

在 Xmpp/Openfire 中从名册中删除一个朋友

动态 XMPP 名册?

修改 XMPP Presence 节