如何获取用户所属的 XMPP(ejabberd)服务器上的 MultiUserChat 组列表?

问题描述 投票:0回答:1

我正在运行一个 ejabberd XMPP 服务器,要求所有 MultiUserChat 房间默认配置为私有。只有管理员用户才能创建多用户聊天组,只有管理员授予成员资格后,用户才能加入。

ejabberd.yml MUC 配置如下:

#Access Rules
access_rules:
  local:
    allow: local
  c2s:
    deny: blocked
    allow: all
  announce:
    allow: admin
  configure:
    allow: admin
  muc_create:
    allow: admin
  pubsub_createnode:
    allow: admin
  trusted_network:
    allow: loopback
  register:
    allow:
        user: admin
        
#Modules
modules:
  mod_muc:
    access:
      - allow
    access_admin:
      - allow: admin
    access_create: muc_create
    access_persistent: muc_create
    access_mam:
      - allow
    default_room_options:
      allow_change_subj: false
      allow_private_messages: false
      allow_private_messages_from_visitors: nobody
      allow_query_users: false
      allow_subscription: false
      allow_user_invites: false
      allow_visitor_nickchange: false
      allow_visitor_status: false
      anonymous: false
      captcha_protected: false
      logging: false
      mam: false
      members_by_default: true
      members_only: true
      moderated: true
      password_protected: false
      persistent: true
      presence_broadcast:
        - moderator
        - participant
        - visitor
      public: false
      public_list: false

后端应用程序使用 Smack v4.4.6 客户端让管理员用户连接到服务器,并根据需要授予现有用户 MUC 频道的成员资格。管理员客户端授予房间成员资格的演示:

package com.example.xmpp;

import java.io.IOException;
import java.net.InetAddress;

import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jivesoftware.smackx.muc.MultiUserChat;
import org.jivesoftware.smackx.muc.MultiUserChatManager;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPException;
import org.jxmpp.jid.EntityBareJid;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.jid.parts.Resourcepart;

public class AdminClient {
    
    public static void main(String[] args){

        String username = "admin";
        String password = "password";
        String resource = "local";
        
        String host = "example.com";
        int port = 5222;
        String domain = "example.com";
        
        String channelName = "exampleChannel";
        
        try {
        
            XMPPTCPConnectionConfiguration.Builder builder = XMPPTCPConnectionConfiguration.builder()
                    .setHostAddress(InetAddress.getByName(host))
                    .setPort(port)
                    .setUsernameAndPassword(username, password)
                    .setXmppDomain(JidCreate.domainBareFrom(domain))
                    .setCompressionEnabled(true)
                    .setSecurityMode(ConnectionConfiguration.SecurityMode.required)
                    ;
            
            XMPPTCPConnectionConfiguration conf = builder.build();
            XMPPTCPConnection connection = new XMPPTCPConnection(conf);
            connection.connect().login();
            
            //MUC Manager
            MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(connection);
            
            //Create MUC room object
            EntityBareJid jid = JidCreate.entityBareFrom(channelName);  //Room JID
            Resourcepart resourcePart = Resourcepart.from(resource);    //Admin user resource part
            MultiUserChat muc = manager.getMultiUserChat(jid);          //MUC object for room
            
            //Add member to room
            String memberUsername = "user1";
            EntityBareJid memberJid = JidCreate.entityBareFrom(memberUsername);
            muc.grantMembership(memberJid);
            
            //Disconnect
            connection.disconnect();
            
        } catch(IOException | XMPPException | SmackException | InterruptedException e) {
            e.printStackTrace();
        }
    
    }

}

客户端应用程序也将使用适用于 android 的 Smack 4.4.6 构建,并且需要监控用户已被授予会员资格的房间。 目前我无法知道服务器上有哪些多用户聊天室,也不知道是否已授予成员资格(无需主动尝试加入)。

现在,我已经实现了一个 REST API 服务来返回后端应用程序存储的频道名称列表,用户可以使用该列表,该列表在应用程序启动时调用。为了避免必须定期调用此 API,我还会在授予新成员资格时发送 firebase 通知,以便受影响的客户知道将其添加到他们的列表并加入。 但是,如果可能的话,我更愿意通过直接查询 XMPPServer 来实现。

Smack 客户端是否可以使用以下方法:

  1. 拉出所有多用户聊天室的列表(包括私人聊天室,因为所有聊天室都是这样配置的)
  2. 为当前连接的用户拉出所有房间成员分配的列表?

(严格来说1.如果2.可以自己完成就不需要了)

xmpp ejabberd smack multiuserchat
1个回答
0
投票

给定一个房间的 JID,可以知道成员列表。然而,给定一个用户 JID,不可能知道它所属的房间列表。 我在https://xmpp.org/extensions/xep-0045.html

中找不到任何这样的东西

然后我开始研究 MucSub,它是 MUC 协议的实验性补充,在 ejabberd 的 mod_muc 中实现。并找到了一个棘手的解决方案......

如果您的用户(或管理员)添加为成员并添加为订阅者,则用户(或管理员)可以请求给定用户的订阅房间列表,您知道这等同于房间列表他是会员的地方。

© www.soinside.com 2019 - 2024. All rights reserved.