菜鸟教程小白 发表于 2022-12-13 13:16:58

ios - XMPP Stream 在加入 MUC 房间时断开连接


                                            <p><p>我正在使用 XMPPFramework 在我的应用中实现群聊功能。一对一聊天工作正常,但是当我通过调用 <code></code> 加入房间时,流会断开连接而不会出现任何错误。 </p>

<p>我也实现了 <code>xmppStreamDidDisconnect:withError</code>,但它仍然给出 nil 错误。用户在加入房间后也会立即离开房间,因为流会断开连接。我也在使用重新连接模块,但是当它重新连接时,房间不会自动加入。 </p>

<p>我也在使用 pidgin 来测试它,但它在那里工作正常。立即断开连接的原因可能是什么?</p>

<p>PS:我在运行 iOS 9.1 的 iPhone 5 上测试它</p>

<p>更新:现在出现以下错误 - </p>

<blockquote>
<p>Error Domain=GCDAsyncSocketErrorDomain Code=7 &#34;Socket closed by remote
peer&#34; UserInfo={NSLocalizedDescription=Socket closed by remote peer}</p>
</blockquote></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p><strong>试试这个模块</strong></p>

<p><strong>MessageManager.h</strong></p>

<pre><code>//Created by Deepak MK on 27/11/15.
//

#import &lt;UIKit/UIKit.h&gt;

#import &#34;XMPP.h&#34;
#import &lt;CoreData/CoreData.h&gt;
#import &#34;XMPPFramework.h&#34;
#import &#34;XMPPMessageDeliveryReceipts.h&#34;
#import &#34;XMPPLastActivity.h&#34;
#import &#34;XMPPRosterMemoryStorage.h&#34;
#import &#34;XMPPRoomMemoryStorage.h&#34;
#import &#34;XMPPvCardCoreDataStorage.h&#34;
#import &#34;XMPPvCardTemp.h&#34;
/**
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;

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

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

/**
XMPPRoomvarible
*/
@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 myPasswordlogin password
*/
- (BOOL)connectWithUserId:(NSString*)jabberID withPassword:(NSString*)myPassword;

/**
Connect user to Xmpp server
@param userName    login user name
@param myPasswordlogin 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 contentcontent 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 &lt;NSObject&gt;

/**
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
</code></pre>

<p><strong>MessageManager.m</strong></p>

<pre><code>#import &#34;MessageManager.h&#34;

#import &#34;DDLog.h&#34;
#import &#34;DDTTYLogger.h&#34;
#import &lt;CFNetwork/CFNetwork.h&gt;
#if DEBUG
static const int ddLogLevel = LOG_LEVEL_VERBOSE;
#else
static const int ddLogLevel = LOG_LEVEL_INFO;
#endif

#define kBaseXMPPURL      @&#34;XXXXXXXXXX&#34;

@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;
}



#pragmamark - custom Functions
+ (MessageManager *) sharedMessageHandler
{

    if (sharedMessageHandler == nil)
    {
      sharedMessageHandler = [ init];
    }

    return sharedMessageHandler;
}

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

    return ;
}

- (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 = [ init];
    ;
    ;

}

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

    ;

    isRegistering=NO;

    if (!) {
      return YES;
    }


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

      return NO;
    }

    ];
    password = myPassword;

    NSError *error = nil;
    if (!)
    {
      UIAlertView *alertView = [ initWithTitle:@&#34;Error&#34;
                                                            message:]
                                                         delegate:nil
                                                cancelButtonTitle:@&#34;Ok&#34;
                                                otherButtonTitles:nil];
      ;


      return NO;
    }

    return YES;
}


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

    if ()
    {
      NSError*error =nil;
      ];
      ;

    }
    else
    {
      ;
    }

}


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

    isOpen = YES;
    NSError *error = nil;

    NSLog(@&#34;Stream Connected&#34;);
    if (!isRegistering)
    {
      if([ respondsToSelector:@selector(didGetStreamState:)])
      {
            [didGetStreamState:YES];
      }

      ;
    }
    else
    {
      ;
    }


}

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

    ;
    NSLog(@&#34;Stream Authenticated&#34;);
    if([ respondsToSelector:@selector(didGetAuthenticationState:)])
    {
      [didGetAuthenticationState:YES];
    }



//    if () {
//      NSLog(@&#34;authenticated&#34;);
//      xmppvCardStorage = [ initWithInMemoryStore];
//      xmppvCardTempModule = [ initWithvCardStorage:xmppvCardStorage];
//      ];
//      ;
//       ignoreStorage:YES];
//    }

}

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


    NSLog(@&#34;Delegate is called&#34;);
    XMPPvCardTemp *vCard = ;
    NSLog(@&#34;Stored card: %@&#34;,vCard);
    NSLog(@&#34;%@&#34;, vCard.description);
    NSLog(@&#34;%@&#34;, vCard.name);
    NSLog(@&#34;%@&#34;, vCard.emailAddresses);
    NSLog(@&#34;%@&#34;, vCard.formattedName);
    NSLog(@&#34;%@&#34;, vCard.givenName);
    NSLog(@&#34;%@&#34;, vCard.middleName);

}

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

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


#pragma mark - Stream disconnection

/**
This fuction is used to disconnet user
*/
- (void)disconnect
{
    ;
    ;
}

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




#pragma mark - setting presence

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

/**
This fuction is used change the presence to Ofline
*/
- (void)goOffline
{
    XMPPPresence *presence = ;
    ;
}


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

    NSXMLElement *status = ;
    ;
    ;

    ;
}

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


    NSString *presenceType = ;            // online/offline
    NSString *myUsername = [ user];
    NSString *presenceFromUser = [ user];
    NSString* presenceState= ;

    NSLog(@&#34;%@is %@ state %@&#34;,presenceFromUser,presenceType,presenceState);

    if (!)
    {

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

      }

      else if() {

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

      }
      else if()
      {

            ];
            ;
      }
      else if()
      {
            ];
      }

    }
    if (xmppRoom)
    {
      ;
    }


}

#pragma mark - subscription
- (void) sendSubscribeMessageToUser:(NSString*)userID
{
    XMPPJID* jbid=;
    XMPPPresence *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)
    {
      ;
    }


    ];
    NSLog(@&#34;Attempting registration for username %@&#34;,xmppStream.myJID.bare);
    password=_password;
    NSError *error = nil;
    BOOL success;

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

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

}

#pragma mark ---delegates of registrtaion


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




    if([ respondsToSelector:@selector(didGetRegistrationState:WithErrorMessage:)])
    {
      [didGetRegistrationState:YES WithErrorMessage:@&#34;Registration with XMPP Successful!&#34;];
    }


}


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

//    DDXMLElement *errorXML = ;
//    NSString *errorCode= [ stringValue];

//    NSString *regError = ;
//   
//   
//    if()
//    {
//      regError=@&#34;Username Already Exists!&#34;;
//    }
//    else
//    {
//      regError= @&#34;Server not connected&#34;;
//    }
    if([ respondsToSelector:@selector(didGetRegistrationState:WithErrorMessage:)])
    {
      [didGetRegistrationState:NO WithErrorMessage:@&#34;Username Already Exists!&#34;];
    }

}



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



//-(void)sendMessageTo:(NSString*)toAdress withContents:(NSString*)messageStr
//{
//   
//   
//    if(&gt; 0)
//    {
//      
//      NSXMLElement *body = ;
//      ;
//      
//      NSXMLElement *message = ;
//      ;
//      ;
//      ;
//      
//      ;
//    }
//}



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

    if(&gt; 0)
    {

      NSXMLElement *body = ;
      ;

      NSXMLElement *message = ;
      ;
      ;
      ;

      ;
    }
    return YES;
}

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

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

    // A simple example of inbound message handling.
    if ()
    {
      NSString *body = [ stringValue];
      if([ respondsToSelector:@selector(didReceiveMessageWithBody:)])
      {
            [ 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 = [ init];

    XMPPJID *roomJID = ;

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

    ;
    ;

    NSXMLElement *history = ;
    ;
    [xmppRoom joinRoomUsingNickname:xmppStream.myJID.user
                            history:history
                           password:nil];


    ;

}

/**
This fuction is used configure new
*/
- (void)ConfigureNewRoom:(id)sender
{
    ;
    ;
    ;
    ;
    ;

}

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

    // I am inviting friends after room is created


}

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

}

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

}

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

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


- (void) requestAllMesssage
{

//    &lt;presence
//    from=&#39;[email protected]/pda&#39;
//    id=&#39;n13mt3l&#39;
//    to=&#39;[email protected]/thirdwitch&#39;&gt;
//    &lt;x xmlns=&#39;http://jabber.org/protocol/muc&#39;&gt;
//    &lt;history since=&#39;1970-01-01T00:00:00Z&#39;/&gt;
//    &lt;/x&gt;
//    &lt;/presence&gt;
//   
//    NSXMLElement *iQ = ;
//    ;
//    ;
//   
//    NSXMLElement *retrieve = ;
//    ;
//    ;
//   
//    NSXMLElement *set = ;
//    ;
//   
//    ;
//    ;
//   
//    ;




}

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

    NSXMLElement *newConfig = ;
    NSArray *fields = ;

    for (NSXMLElement *field in fields)
    {
      NSString *var = ;

      // Make Room Persistent
      if ()
      {

            ;
            ];
      }

      if ()
      {

            ;
            ];
      }

      if ()
      {

            ;
            ];
      }


    }
    //    ;
}

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

}


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

    ;
    return YES;
}


@end
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于ios - XMPP Stream 在加入 MUC 房间时断开连接,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/34610863/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/34610863/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - XMPP Stream 在加入 MUC 房间时断开连接