成员无法在muc房间中获得成员列表

问题描述:

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

<iq xmlns="jabber:client" from="[email protected]" to="[email protected]/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 [email protected]</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; 
     } 
    } 

} 

确保在配置房间时设置muc#roomconfig_whoisanyone

<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]:

我想我kinna弄清楚什么是错的。从您的代码中,您首先邀请用户,然后将其添加到成员。

你可以尝试颠倒流程。首先将所有内容添加到成员,然后再邀请。否则,当用户获得邀请时,成员可能尚未在Xmpp Server上设置。

这里是我做过什么:

  • 加入一个房间,(如果房间不存在,服务器将创建它)。
  • 在xmppRoomDidCreate中,获取配置表单。
  • 发送配置表和加入全部成员之后。
  • 在didConfigure中发送邀请。

流是有点慢,我建议你添加设置为默认设置在mod_muc。请确保在发送邀请前添加成员。

[编辑]:

下面是配置的房间时,我的形式:

<x xmlns=\"jabber:x:data\" type=\"form\"> 
     <title>Configuration of room [email protected]</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> 

正如你所看到的,对项目的一些差异:

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

我尝试了 “睦#roomconfig_moderatedroom” 设置为1,仍然是所有会员均可获得成员列表。不知道你身边发生了什么。

+0

我改变了对任何人,但结果是一样的。你可以在编辑的页面上看到我的config xml – tolgatanriverdi

+0

编辑我的消息 – tolgatanriverdi

+0

真的很奇怪,也许你把你所有的相关代码从createRoom压缩到InviteUser和你的服务配置文件,然后分享给我,我会试着弄清楚。永远不要让你的问题。 – dichen

让我在swift中添加我的工作代码,你可以检查是否有任何区别。抱歉忍不住更多。

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: "[email protected]@" 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。当所有者发送第一条消息时,所有其他成员将获得推送并开始提取成员列表。

+0

如果业主不发送任何消息,只创建房间会发生什么? 在这种情况下,收款人不知道该组创建的权利? – tolgatanriverdi

+0

在我的应用程序中,仅当用户发送第一个消息时才会创建房间。但是你是对的,这取决于应用程序的行为。 – dichen

+0

@tolgatanriverdi - 请介意共享请问什么是pod问题?我有同样的问题(虽然我没有使用pod,但直接集成了代码),但仍然可能有助于发生什么......非常感谢。 – vikram17000