Trouble creating xmpp muc room: Code 503 (service unavailable)

后端 未结 1 934
旧巷少年郎
旧巷少年郎 2020-12-08 12:22

My code to create a room:

XMPPRoomCoreDataStorage *rosterstorage = [[XMPPRoomCoreDataStorage alloc] init];
XMPPRoom *xmppRoom = [[XMPPRoom alloc] initWithRoo         


        
1条回答
  •  感情败类
    2020-12-08 13:01

    First, take look here XEP-0045: Multi-User Chat.
    As you can see, first you have to discover which capabilities your user (XMPPJID) has on the Jabber server.

    To do this, send next command to your Jabber Server:

    
        
    
    

    or writen in objective-c using XMPP library functions:

    NSError *error = nil;
    NSXMLElement *query = [[NSXMLElement alloc] initWithXMLString:@"" 
                                                            error:&error];
    XMPPIQ *iq = [XMPPIQ iqWithType:@"get" 
                                 to:[XMPPJID jidWithString:@"jabber.server.com"] 
                          elementID:[xmppStream generateUUID] child:query];
    [xmppStream sendElement:iq];
    

    Now listen response from server in XMPPStream delegate - (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq and server response should be something like this:

    
        
            
            
        
    
    

    or objective c:

    - (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
    {
    
        if([iq isResultIQ])
        {
            if([iq elementForName:@"query" xmlns:@"http://jabber.org/protocol/disco#items"])
            {
                NSLog(@"Jabber Server's Capabilities: %@", [iq XMLString]);
            }
        }
    }
    

    Now for every item returned send IQ to your server for it's properties and figure out which one is type of conference, something like this:

    
        
    
    

    or in objective c:

    - (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
    {
    
        if([iq isResultIQ])
        {
            if([iq elementForName:@"query" xmlns:@"http://jabber.org/protocol/disco#items"])
            {
                NSXMLElement *query = [iq childElement];
                NSArray *items = [query children];
                for(NSXMLElement *item in items)
                {
                    NSError *error = nil;
                    NSXMLElement *sendQuery = [[NSXMLElement alloc] initWithXMLString:@"" 
                                                                                error:&error];
                    XMPPIQ *sendIQ = [XMPPIQ iqWithType:@"get" 
                                                     to:[XMPPJID jidWithString:[item attributeStringValueForName:@"jid"]] 
                                              elementID:[xmppStream generateUUID] 
                                                  child:sendQuery];
                    [xmppStream sendElement:sendIQ];
                }
            }
        }
    }
    

    Listen for responses from server:

    
        
            
            
        
    
    

    and take group chat domain from identity with category:conference

    - (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
    {
    
        if([iq isResultIQ])
        {
            if([iq elementForName:@"query" xmlns:@"http://jabber.org/protocol/disco#items"])
            {
                ...
            }
            else if([iq elementForName:@"query" xmlns:@"http://jabber.org/protocol/disco#info"])
            {
                NSXMLElement *query = [iq childElement];
                NSXMLElement *identity = [query elementForName:@"identity"];
                if([[identity attributeStringValueForName:@"category"] isEqualToString:@"conference"])
                {
                    groupChatDomain = [iq fromStr];
                }
            }
        }
    }
    

    Finally, when we got group chat domain we can create chat room something like this:

    XMPPJID *chatRoomJID = [XMPPJID jidWithUser:@"chat_room" 
                                         domain:groupChatDomain 
                                       resource:@"user"];
    XMPPRoomMemoryStorage *roomMemoryStorage = [[XMPPRoomMemoryStorage alloc] init];
    XMPPRoom *xmppRoom = [[XMPPRoom alloc] initWithRoomStorage:roomMemoryStorage
                                                           jid:roomChatJID
                                                 dispatchQueue:dispatch_get_main_queue()];
    [xmppRoom activate:xmppStream];
    [xmppRoom addDelegate:self delegateQueue:dispatch_get_main_queue()];
    [xmppRoom joinRoomUsingNickname:user history:nil];
    

    and add protocol in your view controller and its delegates:

    - (void)xmppRoomDidCreate:(XMPPRoom *)sender
    - (void)xmppRoomDidDestroy:(XMPPRoom *)sender
    - (void)xmppRoom:(XMPPRoom *)sender didConfigure:(XMPPIQ *)iqResult
    - (void)xmppRoom:(XMPPRoom *)sender didNotConfigure:(XMPPIQ *)iqResult
    - (void)xmppRoomDidJoin:(XMPPRoom *)sender
    - (void)xmppRoomDidLeave:(XMPPRoom *)sender
    - (void)xmppRoom:(XMPPRoom *)sender occupantDidJoin:(XMPPJID *)occupantJID withPresence:(XMPPPresence *)presence
    - (void)xmppRoom:(XMPPRoom *)sender occupantDidLeave:(XMPPJID *)occupantJID withPresence:(XMPPPresence *)presence
    - (void)xmppRoom:(XMPPRoom *)sender didReceiveMessage:(XMPPMessage *)message fromOccupant:(XMPPJID *)occupantJID
    

    Note: Before inviting other users to Chat Room, you have to send and confirm room configurations (other users can be invited but messages can not be sent).
    So you can do this after Room is created (delegate - (void)xmppRoomDidCreate:(XMPPRoom *)sender is called) or your user has joined (delegate - (void)xmppRoomDidJoin:(XMPPRoom *)sender is called) to Chat Room.

    To send and confirm room configuration do one of the following:

    - (void)xmppRoomDidCreate:(XMPPRoom *)sender
    {
        [sender configureRoomUsingOptions:nil];
    }
    

    or

    - (void)xmppRoomDidJoin:(XMPPRoom *)sender
    {    
        [sender configureRoomUsingOptions:nil];
    }
    

    Send nil to accept default options or you can send IQ with syntax as below to your server:

    
        
            
                
                    http://jabber.org/protocol/muc#roomconfig
                
                
                    My Chat Room
                
                  .
                  .
                  .
            
    
    
    

    or objective c code:

    NSError *error = nil;
    NSXMLElement *query = [[NSXMLElement alloc] initWithXMLString:@"" 
                                                            error:&error];
    NSXMLElement *x = [NSXMLElement elementWithName:@"x" 
                                              xmlns:@"jabber:x:data"];
    [x addAttributeWithName:@"type" stringValue:@"submit"];
    NSXMLElement *field1 = [NSXMLElement elementWithName:@"field"];
    [field1 addAttributeWithName:@"var" stringValue:@"FORM_TYPE"];
    NSXMLElement *value1 = [NSXMLElement elementWithName:@"value" 
                                             stringValue:@"http://jabber.org/protocol/muc#roomconfig"];
    [field1 addChild:value1];
    
    NSXMLElement *field2 = [NSXMLElement elementWithName:@"field"];
    [field2 addAttributeWithName:@"var" stringValue:@"muc#roomconfig_roomname"];
    NSXMLElement *value2 = [NSXMLElement elementWithName:@"value" 
                                             stringValue:@"My Chat Room"];
    [field2 addChild:value2];
    
    //Add other fields you need, just like field1 and field2
    
    [x addChild:field1];
    [x addChild:field2];
    
    [query addChild:x];
    
    NSXMLElement *roomOptions = [NSXMLElement elementWithName:@"iq"];
    [roomOptions addAttributeWithName:@"type" stringValue:@"set"];
    [roomOptions addAttributeWithName:@"id" stringValue:[xmppStream generateUUID];
    [roomOptions addAttributeWithName:@"to" stringValue:@"chat_room@conference.jabber.server.com"];
    
    [roomOptions addChild:query];
    
    [sender configureRoomUsingOptions:roomOptions];
    

    and list of all possible Configuration Form fields is here

    0 讨论(0)
提交回复
热议问题