【问题标题】:Members cannot get member list in a muc room成员无法在 muc 房间获取成员列表
【发布时间】:2017-03-27 06:08:34
【问题描述】:

我正在为我们的聊天应用程序使用 IOS XMPPFramework,我正在创建组并使用以下代码添加选定的成员,并且收件人成功加入了该组。 如果我查询该组管理员的成员列表,成功检索该组的成员,但成员无法获得相同的列表,而是收到以下错误:

<iq xmlns="jabber:client" from="250034370263@conference.chat.meeapps.com.tr" to="16503312600@chat.meeapps.com.tr/15323458207749806891286" id="FF691FF5-D12B-4BAA-AB19-84E7A2B945D4" type="error"><query xmlns="http://jabber.org/protocol/muc#admin"><item affiliation="member"/></query><error code="403" type="auth"><forbidden xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/><text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">Administrator privileges required</text></error></iq>

您可以在下面找到创建和邀请码:

- (void)xmppRoom:(XMPPRoom*)sender didFetchMembersList:(NSArray *)items
{
    CLS_LOG(@"Received MemberList: %@",items);
    if (sender.inviteMemberList) {
        if ([sender.inviteMemberList count]) {

            for (NSString *user in sender.inviteMemberList) {
                [sender inviteUser:[XMPPJID jidWithString:user] withMessage:nil];
            }


            CLS_LOG(@"Adding Members To Group %@",sender.inviteMemberList);
            XMPPIQ *addMemberIQ = [XMPPIQ addMembersToGroup:sender.inviteMemberList withElementId:[self generateMessageID] andNick:sender.nickName andGroupJid:[sender.roomJID bare]];
            CLS_LOG(@"Sending IQ To Add Member: %@",addMemberIQ);
            [xmppStream sendElement:addMemberIQ];
            sender.inviteMemberList = nil;
        }
    }


}

+ (nonnull instancetype) addMembersToGroup:(NSArray *)memberList withElementId:(NSString*)elementId andNick:(NSString*)nick andGroupJid:(NSString*)groupJid
{
    NSXMLElement *queryElement = [self elementWithName:@"query" xmlns:XMPPMUCAdminNamespace];

    for (NSString *member in memberList) {
        NSXMLElement *itemElement = [self elementWithName:@"item"];
        [itemElement addAttributeWithName:@"affiliation" stringValue:@"member"];
        [itemElement addAttributeWithName:@"jid" stringValue:member];

        [queryElement addChild:itemElement];
    }


    return [self iqWithType:@"set" to:[XMPPJID jidWithString:groupJid] elementID:elementId child:queryElement];
}

[编辑] 您还可以在下面的 xml 中找到我的房间配置:

<?xml version="1.0" encoding="UTF-8"?>
<x xmlns="jabber:x:data" type="form">
   <title>Configuration of room 259297300263@conference.chat.meeapps.com.tr</title>
   <field type="hidden" var="FORM_TYPE">
      <value>http://jabber.org/protocol/muc#roomconfig</value>
   </field>
   <field type="text-single" label="Room title" var="muc#roomconfig_roomname">
      <value>osmannn</value>
   </field>
   <field type="text-single" label="Room description" var="muc#roomconfig_roomdesc">
      <value />
   </field>
   <field type="boolean" label="Make room persistent" var="muc#roomconfig_persistentroom">
      <value>1</value>
   </field>
   <field type="boolean" label="Make room public searchable" var="muc#roomconfig_publicroom">
      <value>1</value>
   </field>
   <field type="boolean" label="Make participants list public" var="public_list">
      <value>1</value>
   </field>
   <field type="boolean" label="Make room password protected" var="muc#roomconfig_passwordprotectedroom">
      <value>0</value>
   </field>
   <field type="text-private" label="Password" var="muc#roomconfig_roomsecret">
      <value />
   </field>
   <field type="list-single" label="Maximum Number of Occupants" var="muc#roomconfig_maxusers">
      <value>200</value>
      <option label="5">
         <value>5</value>
      </option>
      <option label="10">
         <value>10</value>
      </option>
      <option label="20">
         <value>20</value>
      </option>
      <option label="30">
         <value>30</value>
      </option>
      <option label="50">
         <value>50</value>
      </option>
      <option label="100">
         <value>100</value>
      </option>
      <option label="200">
         <value>200</value>
      </option>
   </field>
   <field type="list-single" label="Present real Jabber IDs to" var="muc#roomconfig_whois">
      <value>anyone</value>
      <option label="moderators only">
         <value>moderators</value>
      </option>
      <option label="anyone">
         <value>anyone</value>
      </option>
   </field>
   <field type="list-multi" label="Roles for which Presence is Broadcasted" var="muc#roomconfig_presencebroadcast">
      <value>moderator</value>
      <value>participant</value>
      <value>visitor</value>
      <option label="Moderator">
         <value>moderator</value>
      </option>
      <option label="Participant">
         <value>participant</value>
      </option>
      <option label="Visitor">
         <value>visitor</value>
      </option>
   </field>
   <field type="boolean" label="Make room members-only" var="muc#roomconfig_membersonly">
      <value>1</value>
   </field>
   <field type="boolean" label="Make room moderated" var="muc#roomconfig_moderatedroom">
      <value>1</value>
   </field>
   <field type="boolean" label="Default users as participants" var="members_by_default">
      <value>1</value>
   </field>
   <field type="boolean" label="Allow users to change the subject" var="muc#roomconfig_changesubject">
      <value>1</value>
   </field>
   <field type="boolean" label="Allow users to send private messages" var="allow_private_messages">
      <value>1</value>
   </field>
   <field type="list-single" label="Allow visitors to send private messages to" var="allow_private_messages_from_visitors">
      <value>anyone</value>
      <option label="nobody">
         <value>nobody</value>
      </option>
      <option label="moderators only">
         <value>moderators</value>
      </option>
      <option label="anyone">
         <value>anyone</value>
      </option>
   </field>
   <field type="boolean" label="Allow users to query other users" var="allow_query_users">
      <value>1</value>
   </field>
   <field type="boolean" label="Allow users to send invites" var="muc#roomconfig_allowinvites">
      <value>0</value>
   </field>
   <field type="boolean" label="Allow visitors to send status text in presence updates" var="muc#roomconfig_allowvisitorstatus">
      <value>1</value>
   </field>
   <field type="boolean" label="Allow visitors to change nickname" var="muc#roomconfig_allowvisitornickchange">
      <value>1</value>
   </field>
   <field type="boolean" label="Allow visitors to send voice requests" var="muc#roomconfig_allowvoicerequests">
      <value>1</value>
   </field>
   <field type="boolean" label="Allow subscription" var="muc#roomconfig_allow_subscription">
      <value>1</value>
   </field>
   <field type="text-single" label="Minimum interval between voice requests (in seconds)" var="muc#roomconfig_voicerequestmininterval">
      <value>1800</value>
   </field>
   <field type="jid-multi" label="Exclude Jabber IDs from CAPTCHA challenge" var="muc#roomconfig_captcha_whitelist" />
</x>

你能帮我解决这个问题吗?

[编辑 2:] 我已经像下面的代码一样更改了我的代码。而且我也做了和你一样的配置,但结果还是一样。我在服务器端遗漏了什么吗?

- (void)xmppRoom:(XMPPRoom *)sender didFetchConfigurationForm:(NSXMLElement *)configForm{

        NSXMLElement *newConfig = [configForm copy];
        NSArray* fields = [newConfig elementsForName:@"field"];
        for (NSXMLElement *field in fields) {
            NSString *var = [field attributeStringValueForName:@"var"];

            if ([var isEqualToString:@"muc#roomconfig_persistentroom"]) {
                [field removeChildAtIndex:0];
                [field addChild:[NSXMLElement elementWithName:@"value" stringValue:@"1"]];

            }else if ([var isEqualToString:@"muc#roomconfig_roomname"]){
                [field removeChildAtIndex:0];
                [field addChild:[NSXMLElement elementWithName:@"value" stringValue:sender.groupName]];

            }
            else if ([var isEqualToString:@"muc#roomconfig_publicroom"]){
                [field removeChildAtIndex:0];
                [field addChild:[NSXMLElement elementWithName:@"value" stringValue:@"0"]];
            }
            else if ([var isEqualToString:@"muc#roomconfig_whois"]) {
                [field removeChildAtIndex:0];
                [field insertChild:[NSXMLElement elementWithName:@"value" stringValue:@"anyone"] atIndex:0];
            }
            else if ([var isEqualToString:@"muc#roomconfig_allow_subscription"]) {
                [field removeChildAtIndex:0];
                [field addChild:[NSXMLElement elementWithName:@"value" stringValue:@"1"]];
            }
            else if ([var isEqualToString:@"muc#roomconfig_membersonly"]){
              [field removeChildAtIndex:0];
              [field addChild:[NSXMLElement elementWithName:@"value" stringValue:@"1"]];
            }
            else if ([var isEqualToString:@"public_list"]){
                [field removeChildAtIndex:0];
                [field addChild:[NSXMLElement elementWithName:@"value" stringValue:@"1"]];
            }
            else if ([var isEqualToString:@"muc#roomconfig_allowinvites"]){
                [field removeChildAtIndex:0];
                [field addChild:[NSXMLElement elementWithName:@"value" stringValue:@"1"]];
            }
        }
        CLS_LOG(@"Sending Configuration: %@",newConfig);
        [sender configureRoomUsingOptions:newConfig];


        if (sender.inviteMemberList) {
            CLS_LOG(@"Adding Members To Group %@",sender.inviteMemberList);
            XMPPIQ *addMemberIQ = [XMPPIQ addMembersToGroup:sender.inviteMemberList withElementId:[self generateMessageID] andNick:sender.nickName andGroupJid:[sender.roomJID bare]];
            CLS_LOG(@"Sending IQ To Add Member: %@",addMemberIQ);
            [xmppStream sendElement:addMemberIQ];
            [sender fetchMembersList];

        }

}

- (void)xmppRoom:(XMPPRoom*)sender didFetchMembersList:(NSArray *)items{

    CLS_LOG(@"Fetched Members: %@",items);

    if (sender.inviteMemberList) {
        if ([sender.inviteMemberList count]) {

            for (NSString *user in sender.inviteMemberList) {
                [sender inviteUser:[XMPPJID jidWithString:user] withMessage:nil];
            }


            sender.inviteMemberList = nil;
        }
    }

}

【问题讨论】:

    标签: objective-c xmpp ejabberd xmppframework multiuserchat


    【解决方案1】:

    确保在配置房间时将muc#roomconfig_whois 设置为anyone

     <field
              label='Who May Discover Real JIDs?'
              type='list-single'
              var='muc#roomconfig_whois'>
            <option label='Moderators Only'>
              <value>moderators</value>
            </option>
            <option label='Anyone'>
              <value>anyone</value>
            </option>
      </field>
    

    http://xmpp.org/extensions/xep-0045.html#roomconfig

    [编辑 2]:

    我想我大概知道出了什么问题。在您的代码中,您首先邀请了用户,然后将他们添加到成员中。

    你能试试逆流吗?先全部加入会员,再邀请。否则当用户收到邀请时,Xmpp Server 上可能还没有设置成员。

    这是我做的:

    • 加入房间,(如果房间不存在,服务器将创建它)。
    • 在 xmppRoomDidCreate 中,获取配置表单。
    • 发送配置表单,然后添加所有成员
    • 在 didConfigure 中,发送邀请。

    流程有点慢,我建议你在 mod_muc 中将设置添加为默认设置。只需确保在发送邀请之前添加成员即可。

    [已编辑]:

    这是我配置房间时的表格:

    <x xmlns=\"jabber:x:data\" type=\"form\">
          <title>Configuration of room 1479231695@conference.192.168.100.226</title>
          <field type=\"hidden\" var=\"FORM_TYPE\">
            <value>http://jabber.org/protocol/muc#roomconfig</value>
          </field>
          <field type=\"text-single\" label=\"Room title\" var=\"muc#roomconfig_roomname\">
            <value></value>
          </field>
          <field type=\"text-single\" label=\"Room description\" var=\"muc#roomconfig_roomdesc\">
            <value></value>
          </field>
          <field type=\"boolean\" label=\"Make room persistent\" var=\"muc#roomconfig_persistentroom\">
            <value>1</value>
          </field>
          <field type=\"boolean\" label=\"Make room public searchable\" var=\"muc#roomconfig_publicroom\">
            <value>0</value>
          </field>
          <field type=\"boolean\" label=\"Make participants list public\" var=\"public_list\">
            <value>0</value>
          </field>
          <field type=\"boolean\" label=\"Make room password protected\" var=\"muc#roomconfig_passwordprotectedroom\">
            <value>0</value>
          </field>
          <field type=\"text-private\" label=\"Password\" var=\"muc#roomconfig_roomsecret\">
            <value></value>
          </field>
          <field type=\"list-single\" label=\"Maximum Number of Occupants\" var=\"muc#roomconfig_maxusers\">
            <value>200</value>
            <option label=\"5\">
              <value>5</value>
            </option>
            <option label=\"10\">
              <value>10</value>
            </option>
            <option label=\"20\">
              <value>20</value>
            </option>
            <option label=\"30\">
              <value>30</value>
            </option>
            <option label=\"50\">
              <value>50</value>
            </option>
            <option label=\"100\">
              <value>100</value>
            </option>
            <option label=\"200\">
              <value>200</value>
            </option>
          </field>
          <field type=\"list-single\" label=\"Present real Jabber IDs to\" var=\"muc#roomconfig_whois\">
            <option label=\"moderators only\">
              <value>moderators</value>
            </option>
            <option label=\"anyone\">
              <value>anyone</value>
            </option>
            <value>anyone</value>
          </field>
          <field type=\"list-multi\" label=\"Roles for which Presence is Broadcasted\" var=\"muc#roomconfig_presencebroadcast\">
            <value>moderator</value>
            <value>participant</value>
            <value>visitor</value>
            <option label=\"Moderator\">
              <value>moderator</value>
            </option>
            <option label=\"Participant\">
              <value>participant</value>
            </option>
            <option label=\"Visitor\">
              <value>visitor</value>
            </option>
          </field>
          <field type=\"boolean\" label=\"Make room members-only\" var=\"muc#roomconfig_membersonly\">
            <value>1</value>
          </field>
          <field type=\"boolean\" label=\"Make room moderated\" var=\"muc#roomconfig_moderatedroom\">
            <value>0</value>
          </field>
          <field type=\"boolean\" label=\"Default users as participants\" var=\"members_by_default\">
            <value>1</value>
          </field>
          <field type=\"boolean\" label=\"Allow users to change the subject\" var=\"muc#roomconfig_changesubject\">
            <value>1</value>
          </field>
          <field type=\"boolean\" label=\"Allow users to send private messages\" var=\"allow_private_messages\">
            <value>1</value>
          </field>
          <field type=\"list-single\" label=\"Allow visitors to send private messages to\" var=\"allow_private_messages_from_visitors\">
            <value>anyone</value>
            <option label=\"nobody\">
              <value>nobody</value>
            </option>
            <option label=\"moderators only\">
              <value>moderators</value>
            </option>
            <option label=\"anyone\">
              <value>anyone</value>
            </option>
          </field>
          <field type=\"boolean\" label=\"Allow users to query other users\" var=\"allow_query_users\">
            <value>1</value>
          </field>
          <field type=\"boolean\" label=\"Allow users to send invites\" var=\"muc#roomconfig_allowinvites\">
            <value>1</value>
          </field>
          <field type=\"boolean\" label=\"Allow visitors to send status text in presence updates\" var=\"muc#roomconfig_allowvisitorstatus\">
            <value>1</value>
          </field>
          <field type=\"boolean\" label=\"Allow visitors to change nickname\" var=\"muc#roomconfig_allowvisitornickchange\">
            <value>1</value>
          </field>
          <field type=\"boolean\" label=\"Allow visitors to send voice requests\" var=\"muc#roomconfig_allowvoicerequests\">
            <value>1</value>
          </field>
          <field type=\"text-single\" label=\"Minimum interval between voice requests (in seconds)\" var=\"muc#roomconfig_voicerequestmininterval\">
            <value>1800</value>
          </field>
          <field type=\"jid-multi\" label=\"Exclude Jabber IDs from CAPTCHA challenge\" var=\"muc#roomconfig_captcha_whitelist\"></field>
        </x>
    

    如您所见,物品上存在一些差异:

    • muc#roomconfig_publicroom
    • public_list
    • muc#roomconfig_moderatedroom
    • muc#roomconfig_allowinvites

    我尝试将“muc#roomconfig_moderatedroom”设置为 1,仍然所有成员都可以获取成员列表。不知道你那边发生了什么。

    【讨论】:

    • 我已将其更改为任何人,但结果是相同的。您可以在编辑的页面上看到我的配置 xml
    • 真的很奇怪,也许你把你所有的相关代码,从createRoom到InviteUser,和你的服务配置文件都压缩了,分享给我,我会想办法的。永远不会遇到您的问题。
    • 您可以在以下链接中找到相关代码部分:drive.google.com/file/d/0B3eSt3_PT8YXT1FReGxhU295anc/…
    • 抱歉文件中有错误。此链接中的最新文件:drive.google.com/file/d/0B3eSt3_PT8YXSWF1aFU1aGJvQjQ/…
    • 我发现了最新的问题,它是因为 xmppframework pod 文件已损坏,我重新生成它并解决了问题,当然是按照您的建议进行实施。现在我还有一个问题。当我获取成员列表时,我还获取了主持人列表以显示谁是该组的管理员,服务器成功返回成员列表但不返回主持人列表并给出&lt;error code="403" type="auth"&gt;&lt;forbidden xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"&gt;Moderator privileges required&lt;/text&gt;&lt;/error&gt;&lt;/iq&gt;的结果
    【解决方案2】:

    让我快速添加我的工作代码,您可以检查是否有任何区别。抱歉帮不上忙。

        func onButtonClicked(_ button: UIButton) {
    
            let roomJIDStr = theRoomJidStr // get the roomJid
            self.xmppRoom = joinRoom(with: roomJIDStr, delegate: self)
        }
    
        func joinRoom(with jidString: String, delegate: XMPPRoomDelegate) -> XMPPRoom {
    
            let roomJID = XMPPJID(string: jidString)
            let roomStorage = XMPPRoomCoreDataStorage.sharedInstance()
    
            let room = XMPPRoom(roomStorage: roomStorage, jid: roomJID, dispatchQueue: DispatchQueue.main)!
    
            room.activate(xmppStream)
    
            room.addDelegate(delegate, delegateQueue: DispatchQueue.main)
    
            room.join(usingNickname: xmppStream.myJID.user, history: nil)
    
            return room
        }
    
        public func xmppRoomDidCreate(_ sender: XMPPRoom!) {
            print("xmppRoomDidCreate")
    
            // Accept default settings
            let config = DDXMLElement(name: "x", xmlns: "jabber:x:data")
            sender.configureRoom(usingOptions: config)
    
            // Add members
            let query = DDXMLElement(name: "query", xmlns: XMPPMUCAdminNamespace)
            if let contacts = selectedContacts {
    
                for c in contacts {
    
                    let item = DDXMLElement(name: "item")
                    item.addAttribute(withName: "affiliation", stringValue: "member")
                    item.addAttribute(withName: "jid", stringValue: c.xmppAccount!)
    
                    query?.addChild(item)
                }
            }
    
            let id = XMPPStream.generateUUID()
            let to = sender.roomJID
            let iq = XMPPIQ(type: "set", to: to, elementID: id, child: query)
    
            chatManager.xmppStream.send(iq)
        }
    

    前提条件:

    • 我设置了一些设置为mod_muc默认选项,所以不需要配置房间。

      mod_muc: ## host: "conference.@HOST@" access: - allow access_admin: - allow: admin access_create: muc_create access_persistent: muc_create history_size: 0 default_room_options: allow_user_invites: true anonymous: false members_by_default: true members_only: true moderated: false persistent: true public: false public_list: false

    • 我的代码中没有邀请,我直接将它们添加到成员列表中。并使用ejabberd_mod_offline_post 进行推送通知。当所有者发送第一条消息时,所有其他成员都会收到推送并开始获取成员列表。

    【讨论】:

    • 如果所有者不发送任何消息而只是创建房间会怎样?在那种情况下,接收者不知道创建的组对吗?
    • 在我的应用程序中,只有当用户发送第一个消息时才会创建房间。但你是对的,这取决于应用程序的行为。
    • @tolgatanriverdi - 您介意分享一下 pod 问题是什么吗?我有同样的问题(虽然没有使用 pod,而是直接集成代码),但仍然可能有助于了解正在发生的事情......非常感谢。
    猜你喜欢
    • 2017-03-30
    • 2015-06-23
    • 2015-02-08
    • 1970-01-01
    • 1970-01-01
    • 2015-07-14
    • 1970-01-01
    • 2016-01-29
    • 2014-06-23
    相关资源
    最近更新 更多