2
votes

I am using XMPPFramework to implement group chat functionality in my app. The one-to-one chat works fine, but when I join a room by calling [xmppRoom joinRoomUsingNickname], the stream disconnects without giving any error.

I implemented xmppStreamDidDisconnect:withError too, but it's still giving nil error. The user also leaves the room immediately after joining it, since the stream disconnects. I am also using Reconnect module, but when it reconnects, the room is not auto-joined.

I am using pidgin to test it too, but it works fine there. What could be the reason for immediate disconnection?

PS: I am using testing it on iPhone 5 running on iOS 9.1

Update: It's now giving the following error -

Error Domain=GCDAsyncSocketErrorDomain Code=7 "Socket closed by remote peer" UserInfo={NSLocalizedDescription=Socket closed by remote peer}

3
What are in your XMPP server logs ? Typically that happens when you send invalid malformed XML on the stream.Mickaël Rémond
@MickaëlRémond Yeah that's what I am wondering, but how can I check if it's the same issue and why the disconnection is not happening when I use Pidgin?noob

3 Answers

1
votes

Try this modules

MessageManager.h

//  Created by Deepak MK on 27/11/15.
//

#import <UIKit/UIKit.h>

#import "XMPP.h"
#import <CoreData/CoreData.h>
#import "XMPPFramework.h"
#import "XMPPMessageDeliveryReceipts.h"
#import "XMPPLastActivity.h"
#import "XMPPRosterMemoryStorage.h"
#import "XMPPRoomMemoryStorage.h"
#import "XMPPvCardCoreDataStorage.h"
#import "XMPPvCardTemp.h"
/**
 message manager class manage all message sequence.
 */
@interface MessageManager : NSObject
{

    XMPPStream                                  *xmppStream;

    NSString                                    *password;

    BOOL                                        isOpen;

    BOOL                                        isRegistering;

    id                                          _delgate;

    XMPPRosterCoreDataStorage                    *xmppRosterStorage;

    XMPPRoster                                           *xmppRoster;

    XMPPvCardCoreDataStorage* xmppvCardStorage;
    XMPPvCardTempModule*xmppvCardTempModule;



}

+ (MessageManager *) sharedMessageHandler;

/**
 The stream varible for connecting stream
 */

@property (nonatomic, readonly) XMPPStream          *xmppStream;

/**
 XMPPRoster  varible
 */
@property (nonatomic, strong,readonly) XMPPRoster *xmppRoster;

/**
 XMPPRosterCoreDataStorage  varible 
 */
@property (nonatomic, strong,readonly) XMPPRosterCoreDataStorage *xmppRosterStorage;

/**
 XMPPRoom  varible
 */
@property (nonatomic, strong, readonly)  XMPPRoom *xmppRoom;


/**
 Setting of delegate
 @param delegate class delegate
 */
- (void) setdelegate:(id)delegate;

/**
 Return of delegate
 */
- (id)   delegate;

/**
 connecting stream of Xmpp server
 */

- (void) setupStream;

/**
 Connect user to Xmpp server
 @param jabberID    login user name
 @param myPassword  login password
 */
- (BOOL)connectWithUserId:(NSString*)jabberID withPassword:(NSString*)myPassword;

/**
 Connect user to Xmpp server
 @param userName    login user name
 @param myPassword  login password
 */
- (void) authenticateUserWIthUSerName:(NSString*)userName withPassword:(NSString*)myPassword;


/**
 disconnect user from Xmpp server
 */
- (void) disconnect;

/**
 changes the presence to online
 */
- (void) goOnline;

/**
 changes the presence to offline
 */
- (void) goOffline;

/**
 Register new user to xmpp server
 @param userName    new user name
 @param _password   new password
 @param EmailId     new email id
 */
- (void)registerStudentWithUserName:(NSString *)userName withPassword:(NSString *)_password withEmailId:(NSString *)EmailId;


/**
 send message to other user with content
 @param toAdress destination address
 @param content  content of message
 */
- (BOOL)sendMessageTo:(NSString*)toAdress withContents:(NSString*)content;



/**
 This method is used for sending subscribe invitation to user
 @param userID destination address
 */
- (void) sendSubscribeMessageToUser:(NSString*)userID;


/**
 This method is used for setting substate of presence
 @param subState substate of user
 */
- (void) presenceWithStubState:(NSString*)subState;


/**
 This method is used to create new room
 @param ChatRoomJID New room name
 */
- (void) setUpRoom:(NSString *)ChatRoomJID;


/**
 This method is used to destroyRoom
 */
- (void) destroyCreatedRoom;

/**
 This method is used to send message to group
 */
- (BOOL)sendGroupMessageWithBody:(NSString*)_body;



- (void) requestAllMesssage;

@end





/**
 Set of methods to be implemented to act as a restaurant patron
 */
@protocol MessageManagerDelegate <NSObject>

/**
 Methods to be get state of stream
 */
- (void) didGetStreamState:(BOOL)state;

/**
 Methods to be get state of Authentication
 */

- (void) didGetAuthenticationState:(BOOL)state;

/**
 Methods to be get state of registration
 */

- (void) didGetRegistrationState:(BOOL)state WithErrorMessage:(NSString*)errorMessage;

/**
 Methods to get recieved message
 */

- (void) didReceiveMessageWithBody:(NSString *) body;


/**
 Methods to get presence of other user
 */
- (void) didRecievePresence:(NSString*)state withUserName:(NSString*)userName WithSubState:(NSString*)subState;


/**
 Methods to get event of user joined room
 */
- (void) didCreatedOrJoinedRoomWithCreatedRoomName:(NSString*)_roomName;


- (void) didGetUserJoinedToRoomORLeaveRoomWithName:(NSString*)_userName WithPresence:(NSString*)presence;
@end

MessageManager.m

#import "MessageManager.h"

#import "DDLog.h"
#import "DDTTYLogger.h"
#import <CFNetwork/CFNetwork.h>
#if DEBUG
static const int ddLogLevel = LOG_LEVEL_VERBOSE;
#else
static const int ddLogLevel = LOG_LEVEL_INFO;
#endif

#define kBaseXMPPURL        @"XXXXXXXXXX"

@interface MessageManager()


@end

static MessageManager *sharedMessageHandler = nil;

@implementation MessageManager

@synthesize xmppStream;
@synthesize xmppRoster;
@synthesize xmppRosterStorage;
@synthesize xmppRoom;

#pragma mark - self class Delegate
- (void) setdelegate:(id)delegate
{
    _delgate= delegate;
}
- (id)   delegate
{
    return _delgate;
}



#pragma  mark - custom Functions
+ (MessageManager *) sharedMessageHandler
{

    if (sharedMessageHandler == nil)
    {
        sharedMessageHandler = [[super allocWithZone:NULL] init];
    }

    return sharedMessageHandler;
}

+ (id)allocWithZone:(NSZone *)zone {

    return [self sharedMessageHandler];
}

- (id)copyWithZone:(NSZone *)zone {

    return self;
}


#pragma mark - connection setup Functions

/**
 This fuction is used to setup XMPP Stream
 */
- (void)setupStream
{

    // Setup xmpp stream
    //
    // The XMPPStream is the base class for all activity.
    // Everything else plugs into the xmppStream, such as modules/extensions and delegates.

    xmppStream = [[XMPPStream alloc] init];
    [xmppStream setHostName:kBaseXMPPURL];
    [xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];

}

/** 
 This fuction is used to Connect XMPP With userId and Password 
 */
- (BOOL)connectWithUserId:(NSString*)jabberID withPassword:(NSString*)myPassword
{

    [self setupStream];

    isRegistering=NO;

    if (![xmppStream isDisconnected]) {
        return YES;
    }


    if (jabberID == nil || myPassword == nil) {

        return NO;
    }

    [xmppStream setMyJID:[XMPPJID jidWithString:jabberID]];
    password = myPassword;

    NSError *error = nil;
    if (![xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error])
    {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error"
                                                            message:[NSString stringWithFormat:@"Can't connect to server %@", [error localizedDescription]]
                                                           delegate:nil
                                                  cancelButtonTitle:@"Ok" 
                                                  otherButtonTitles:nil];
        [alertView show];


        return NO;
    }

    return YES;
}


- (void) authenticateUserWIthUSerName:(NSString*)userName withPassword:(NSString*)myPassword
{

    if ([xmppStream isConnected])
    {
        NSError*error =nil;
        [xmppStream setMyJID:[XMPPJID jidWithString:userName]];
        [xmppStream authenticateWithPassword:myPassword error:&error];

    }
    else
    {
        [self connectWithUserId:userName withPassword:myPassword];
    }

}


#pragma mark ---Delegate of Connect
/**
 This fuction is called when stream is connected
 */
- (void)xmppStreamDidConnect:(XMPPStream *)sender {

    isOpen = YES;
    NSError *error = nil;

    NSLog(@"Stream Connected");
    if (!isRegistering)
    {
        if([[self delegate] respondsToSelector:@selector(didGetStreamState:)])
        {
            [[self delegate]didGetStreamState:YES];
        }

        [xmppStream authenticateWithPassword:password error:&error];
    }
    else
    {
        [xmppStream registerWithPassword:password error:&error];
    }


}

/**
 This fuction is called when User is Authenticated
 */
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender {

    [self goOnline];
    NSLog(@"Stream Authenticated");
    if([[self delegate] respondsToSelector:@selector(didGetAuthenticationState:)])
    {
        [[self delegate]didGetAuthenticationState:YES];
    }



//    if ([xmppStream isAuthenticated]) {
//        NSLog(@"authenticated");
//        xmppvCardStorage = [[XMPPvCardCoreDataStorage alloc] initWithInMemoryStore];
//        xmppvCardTempModule = [[XMPPvCardTempModule alloc] initWithvCardStorage:xmppvCardStorage];
//        [xmppvCardTempModule activate:[self xmppStream]];
//        [xmppvCardTempModule addDelegate:self delegateQueue:dispatch_get_main_queue()];
//        [xmppvCardTempModule fetchvCardTempForJID:[sender myJID] ignoreStorage:YES];
//    }

}

- (void)xmppvCardTempModule:(XMPPvCardTempModule *)vCardTempModule didReceivevCardTemp:(XMPPvCardTemp *)vCardTemp forJID:(XMPPJID *)jid{


    NSLog(@"Delegate is called");
    XMPPvCardTemp *vCard = [xmppvCardStorage vCardTempForJID:jid xmppStream:xmppStream];
    NSLog(@"Stored card: %@",vCard);
    NSLog(@"%@", vCard.description);
    NSLog(@"%@", vCard.name);
    NSLog(@"%@", vCard.emailAddresses);
    NSLog(@"%@", vCard.formattedName);
    NSLog(@"%@", vCard.givenName);
    NSLog(@"%@", vCard.middleName);

}

/**
 This fuction is called when User is  not Authenticated
 */
- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error
{
    NSLog(@"Not Authenticated");

    if([[self delegate] respondsToSelector:@selector(didGetAuthenticationState:)])
    {
        [[self delegate]didGetAuthenticationState:NO];
    }
}


#pragma mark - Stream disconnection

/**
 This fuction is used to disconnet user
 */
- (void)disconnect
{
    [self goOffline];
    [xmppStream disconnect];
}

#pragma mark ---Delegate of disconnect
/**
 This fuction is called when stream is disConnected
 */
- (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error
{
    NSLog(@"Stream Disconnected");
    if([[self delegate] respondsToSelector:@selector(didGetStreamState:)])
    {
        [[self delegate]didGetStreamState:NO];
    }
}




#pragma mark - setting presence

/** 
 This fuction is used change the presence to online 
 */
- (void)goOnline
{
    XMPPPresence *presence = [XMPPPresence presence];
    [xmppStream sendElement:presence];
}

/**
 This fuction is used change the presence to Ofline 
 */
- (void)goOffline
{
    XMPPPresence *presence = [XMPPPresence presenceWithType:@"unavailable"];
    [xmppStream sendElement:presence];
}


/**
 This fuction is used change the presence substate
 */
- (void) presenceWithStubState:(NSString*)subState
{
    XMPPPresence *presence = [XMPPPresence presence];// type="available" is implicit

    NSXMLElement *status = [NSXMLElement elementWithName:@"status"];
    [status setStringValue:subState];
    [presence addChild:status];

    [xmppStream sendElement:presence];
}

/**
 This fuction is called when other user state is changed
 */
- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence
{
    DDLogVerbose(@"%@: %@ - %@", THIS_FILE, THIS_METHOD, [presence fromStr]);


    NSString *presenceType = [presence type];            // online/offline
    NSString *myUsername = [[sender myJID] user];
    NSString *presenceFromUser = [[presence from] user];
    NSString* presenceState= [presence status];

    NSLog(@"%@  is %@ state %@",presenceFromUser,presenceType,presenceState);

    if (![presenceFromUser isEqualToString:myUsername])
    {

        if ([presenceType isEqualToString:@"available"])
        {
            if([[self delegate] respondsToSelector:@selector(didRecievePresence:withUserName:WithSubState:)])
            {
                [[self delegate] didRecievePresence:presenceType withUserName:presenceFromUser WithSubState:presenceState];
            }

        }

        else if  ([presenceType isEqualToString:@"unavailable"]) {

             if([[self delegate] respondsToSelector:@selector(didRecievePresence:withUserName:WithSubState:)])
             {
                 [[self delegate] didRecievePresence:presenceType withUserName:presenceFromUser WithSubState:presenceState];
             }

        }
        else if  ([presenceType isEqualToString:@"subscribe"])
        {

            [xmppRoster subscribePresenceToUser:[presence from]];
            [self goOnline];
        }
        else if  ([presenceType isEqualToString:@"subscribed"])
        {
            [xmppRoster subscribePresenceToUser:[presence from]];
        }

    }
    if (xmppRoom)
    {
        [xmppRoom fetchMembersList];
    }


}

#pragma mark - subscription
- (void) sendSubscribeMessageToUser:(NSString*)userID
{
    XMPPJID* jbid=  [XMPPJID jidWithString:userID];
    XMPPPresence *presence = [XMPPPresence presenceWithType:@"subscribe" to:jbid];
    [xmppStream sendElement:presence];
}


#pragma mark - XMPP delegates
/**
 This fuction is called when new IQ is received 
 */
- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq {

    return NO;

}



#pragma mark - RegistrationFunction

/**
 This fuction is user to retister new user
   if stream is connected the it will directly call registeration function
    otherwise it will connect stream and then call registeration process 
 */

- (void)registerStudentWithUserName:(NSString *)userName withPassword:(NSString *)_password withEmailId:(NSString *)EmailId
{

    if (xmppStream==nil)
    {
        [self setupStream];
    }


    [xmppStream setMyJID:[XMPPJID jidWithString:userName]];
    NSLog(@"Attempting registration for username %@",xmppStream.myJID.bare);
    password=_password;
    NSError *error = nil;
    BOOL success;

    if(![ xmppStream isConnected])
    {
         success = [[self xmppStream] connectWithTimeout:XMPPStreamTimeoutNone error:&error];
        isRegistering=YES;
    }
    else
    {
        success = [[self xmppStream] registerWithPassword:_password error:&error];
    }

    if (success)
    {
        NSLog(@"succeed ");
        isRegistering=YES;
    }
    else
    {
        if([[self delegate] respondsToSelector:@selector(didGetRegistrationState:WithErrorMessage:)])
        {
            [[self delegate]didGetRegistrationState:YES WithErrorMessage:@"Stream not connected"];
        }
    }

}

#pragma mark ---delegates of registrtaion


/**
 This fuction is called when new user is registered 
 */
- (void)xmppStreamDidRegister:(XMPPStream *)sender{




    if([[self delegate] respondsToSelector:@selector(didGetRegistrationState:WithErrorMessage:)])
    {
        [[self delegate]didGetRegistrationState:YES WithErrorMessage:@"Registration with XMPP Successful!"];
    }


}


/**
 This fuction is called when registeration process failed 
 */
- (void)xmppStream:(XMPPStream *)sender didNotRegister:(NSXMLElement *)error{

//    DDXMLElement *errorXML = [error elementForName:@"error"];
//    NSString *errorCode  = [[errorXML attributeForName:@"code"] stringValue];

//    NSString *regError = [NSString stringWithFormat:@"ERROR :- %@",error.description];
//    
//    
//    if([errorCode isEqualToString:@"409"])
//    {
//        regError=@"Username Already Exists!";
//    }
//    else
//    {
//        regError= @"Server not connected";
//    }
    if([[self delegate] respondsToSelector:@selector(didGetRegistrationState:WithErrorMessage:)])
    {
        [[self delegate]didGetRegistrationState:NO WithErrorMessage:@"Username Already Exists!"];
    }

}



#pragma mark - send  and recieve message
/**
 This fuction is used to send message to other user with contents of body
 */



//-(void)sendMessageTo:(NSString*)toAdress withContents:(NSString*)messageStr
//{
//    
//    
//    if([messageStr length]> 0)
//    {
//        
//        NSXMLElement *body = [NSXMLElement elementWithName:@"body"];
//        [body setStringValue:messageStr];
//        
//        NSXMLElement *message = [NSXMLElement elementWithName:@"message"];
//        [message addAttributeWithName:@"type" stringValue:@"chat"];
//        [message addAttributeWithName:@"to" stringValue:toAdress];
//        [message addChild:body];
//        
//        [self.xmppStream sendElement:message];
//    }
//}



- (BOOL)sendMessageTo:(NSString*)toAdress withContents:(NSString*)content
{

    if([content length]> 0)
    {

        NSXMLElement *body = [NSXMLElement elementWithName:@"body"];
        [body setStringValue:content];

        NSXMLElement *message = [NSXMLElement elementWithName:@"message"];
        [message addAttributeWithName:@"type" stringValue:@"chat"];
        [message addAttributeWithName:@"to" stringValue:toAdress];
        [message addChild:body];

        [self.xmppStream sendElement:message];
    }
    return YES;
}

#pragma mark  recieve message
/**
 This fuction is called when new message arrived
 */

- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message
{
    DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);

    // A simple example of inbound message handling.
    if ([message body])
    {
        NSString *body = [[message elementForName:@"body"] stringValue];
        if([[self delegate] respondsToSelector:@selector(didReceiveMessageWithBody:)])
        {
            [[self delegate] didReceiveMessageWithBody:body];
        }

    }
}



#pragma mark - create new room

/**
 This fuction is used to setup room with roomId
 */
-(void)setUpRoom:(NSString *)ChatRoomJID
{
    if (!ChatRoomJID)
    {
        return;
    }
    // Configure xmppRoom
    XMPPRoomMemoryStorage *roomMemoryStorage = [[XMPPRoomMemoryStorage alloc] init];

    XMPPJID *roomJID = [XMPPJID jidWithString:ChatRoomJID];

    xmppRoom = [[XMPPRoom alloc] initWithRoomStorage:roomMemoryStorage jid:roomJID dispatchQueue:dispatch_get_main_queue()];

    [xmppRoom activate:xmppStream];
    [xmppRoom addDelegate:self delegateQueue:dispatch_get_main_queue()];

    NSXMLElement *history = [NSXMLElement elementWithName:@"history"];
    [history addAttributeWithName:@" maxchars" stringValue:@"0"];
    [xmppRoom joinRoomUsingNickname:xmppStream.myJID.user
                            history:history
                           password:nil];


    [self performSelector:@selector(ConfigureNewRoom:) withObject:nil afterDelay:4];

}

/**
 This fuction is used configure new
 */
- (void)ConfigureNewRoom:(id)sender
{
    [xmppRoom configureRoomUsingOptions:nil];
    [xmppRoom fetchConfigurationForm];
    [xmppRoom fetchBanList];
    [xmppRoom fetchMembersList];
    [xmppRoom fetchModeratorsList];

}

/**
 This fuction is called when new room is created
 */
- (void)xmppRoomDidCreate:(XMPPRoom *)sender
{
    DDLogInfo(@"%@: %@", THIS_FILE, THIS_METHOD);

    // I am inviting friends after room is created


}

/**
 This fuction is called when user joined room
 */
- (void)xmppRoomDidJoin:(XMPPRoom *)sender
{
    [sender fetchMembersList];
    [sender fetchConfigurationForm];
    [self requestAllMesssage];
    DDLogInfo(@"%@: %@", THIS_FILE, THIS_METHOD);
    if([[self delegate] respondsToSelector:@selector(didCreatedOrJoinedRoomWithCreatedRoomName:)])
    {
        [[self delegate] didCreatedOrJoinedRoomWithCreatedRoomName:sender.myRoomJID.bare];
    }

}

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

}

- (void)xmppRoom:(XMPPRoom *)sender occupantDidJoin:(XMPPJID *)occupantJID withPresence:(XMPPPresence *)presence
{
    if([[self delegate] respondsToSelector:@selector(didGetUserJoinedToRoomORLeaveRoomWithName:WithPresence:)])
    {
//        id details =occupantJID;
//        NSString* string = (NSString*)details;
         [[self delegate] didGetUserJoinedToRoomORLeaveRoomWithName:[occupantJID resource] WithPresence:[presence type]];
    }

}
- (void)xmppRoom:(XMPPRoom *)sender occupantDidLeave:(XMPPJID *)occupantJID withPresence:(XMPPPresence *)presence
{
    if([[self delegate] respondsToSelector:@selector(didGetUserJoinedToRoomORLeaveRoomWithName:WithPresence:)])
    {
        [[self delegate] didGetUserJoinedToRoomORLeaveRoomWithName:[occupantJID resource] WithPresence:[presence type]];
    }
}
- (void)xmppRoom:(XMPPRoom *)sender occupantDidUpdate:(XMPPJID *)occupantJID withPresence:(XMPPPresence *)presence
{
    if([[self delegate] respondsToSelector:@selector(didGetUserJoinedToRoomORLeaveRoomWithName:WithPresence:)])
    {
        [[self delegate] didGetUserJoinedToRoomORLeaveRoomWithName:[occupantJID resource] WithPresence:[presence type]];
    }
}


- (void) requestAllMesssage
{

//    <presence
//    from='[email protected]/pda'
//    id='n13mt3l'
//    to='[email protected]/thirdwitch'>
//    <x xmlns='http://jabber.org/protocol/muc'>
//    <history since='1970-01-01T00:00:00Z'/>
//    </x>
//    </presence>
//    
//    NSXMLElement *iQ = [NSXMLElement elementWithName:@"presence"];
//    [iQ addAttributeWithName:@"type" stringValue:@"get"];
//    [iQ addAttributeWithName:@"id" stringValue:@"n13mt3l"];
//    
//    NSXMLElement *retrieve = [NSXMLElement elementWithName:@"retrieve"];
//    [retrieve addAttributeWithName:@"xmlns" stringValue:@"urn:xmpp:archive"];
//    [retrieve addAttributeWithName:@"history since" stringValue:@"1970-01-01T00:00:00Z"];
//    
//    NSXMLElement *set = [NSXMLElement elementWithName:@"set"];
//    [set addAttributeWithName:@"xmlns" stringValue:@"http://jabber.org/protocol/muc"];
//    
//    [retrieve addChild:set];
//    [iQ addChild:retrieve];
//    
//    [xmppStream sendElement:iQ];




}

- (void)xmppRoom:(XMPPRoom *)sender didFetchConfigurationForm:(NSXMLElement *)configForm
{
    DDLogInfo(@"%@: %@", THIS_FILE, THIS_METHOD);

    NSXMLElement *newConfig = [configForm copy];
    NSArray *fields = [newConfig elementsForName:@"field"];

    for (NSXMLElement *field in fields)
    {
        NSString *var = [field attributeStringValueForName:@"var"];

        // Make Room Persistent
        if ([var isEqualToString:@"muc#roomconfig_persistentroom"])
        {

            [field removeChildAtIndex:0];
            [field addChild:[NSXMLElement elementWithName:@"value" stringValue:@"1"]];
        }

        if ([var isEqualToString:@"roomconfig_enablelogging"])
        {

            [field removeChildAtIndex:0];
            [field addChild:[NSXMLElement elementWithName:@"value" stringValue:@"1"]];
        }

        if ([var isEqualToString:@"muc#roomconfig_maxusers"])
        {

            [field removeChildAtIndex:0];
            [field addChild:[NSXMLElement elementWithName:@"value" stringValue:@"100"]];
        }


    }
    //    [sender configureRoomUsingOptions:newConfig];
}

/**
 This fuction is used to destroy created room
 */
- (void) destroyCreatedRoom
{
    [xmppRoom destroyRoom];

}


- (BOOL)sendGroupMessageWithBody:(NSString*)_body
{

    [xmppRoom sendMessageWithBody:_body];
    return YES;
}


@end
0
votes

Generally when the server is closing the connection, you get this error. There are two reasons when the server closes the connection:

  1. You are not sending regular pings if the client idle.
  2. You are logging in from some different client with the same credentials, and in the server settings have the setting: Always kick - If there is a resource conflict, immediately kick the other resource. in Server>server settings>resource policy.

Please check the server settings. use this for server setting http://docs.ejabberd.im/admin/guide/installation/

And also check for App Transport Security Setting in your project. if it is not added then add the below code to info.plist

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
</plist>
0
votes

The actual problem was that I was changing subject of the Room, just after creating the room. On removing the code for changing the subject of the room, it started working fine. Here's the code I was using -

-(XMPPRoom *)createRoom:(XMPPJID *)roomJid withSubject:(NSString*)subject{
    XMPPRoomMemoryStorage *roomStorage = [[XMPPRoomMemoryStorage alloc]init];
    XMPPRoom *xmppRoom = [[XMPPRoom alloc] initWithRoomStorage:roomStorage
                                                           jid:roomJid
                                                 dispatchQueue:dispatch_get_main_queue()];

    [xmppRoom activate:self.xmppStream];
    [xmppRoom addDelegate:self delegateQueue:dispatch_get_main_queue()];
//    if(subject){
//        [xmppRoom changeRoomSubject:subject];
//    }
    return xmppRoom;
}
-(GroupCore *)createRoomAndGroup:(XMPPJID *)roomJid withSubject:(NSString*)subject{
    XMPPRoom* xmppRoom = [self createRoom:roomJid withSubject:subject];
    GroupCore* group = [appDelegate.coreDataController addGroup:xmppRoom withOptions:CreateOnly];
    if(!xmppRoom.roomSubject){
        group.name = subject;
    }
    //[appDelegate saveContext];
//    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
//        [group joinRoom];
//    });
    return group;
}