XMPP Fraameweork心拍包類、断線重連類

4043 ワード

1.XMPPStream:xmpp基礎サービス類;2.XMPPAtoPingとXMPPPingの2つの種類:心拍傍受類。3.XMPPReconnect:接続を失ったら、自動的に再接続する参考資料:http://www.jianshu.com/p/d9de0267c52a http://www.jb51.net/article/96760.htm
部分コード:1.XMPPを初期化する
//     , ...
//   init  ,     setupStream  , ...

/** Setup the XMPP stream */
- (void)setupStream {
    //1.  XMPP     
    _xmppStream = [[XMPPStream alloc] init];
    [_xmppStream addDelegate:self delegateQueue: dispatch_get_main_queue()];
    //(1)       
    [self.xmppStream setHostName:SERVER];
    //(2)     
    [self.xmppStream setHostPort:5222];
    //(3)        
    NSString * userName = [NSString stringWithFormat:@"%@@%@",name, SERVER_NAME];
    //(4)  JID --     XMPP    
    XMPPJID * myJID = [XMPPJID jidWithString:userName resource:XMPPJIDRESOURCE];
    [self.xmppStream setMyJID:myJID];
    
    //2.
    //(1)      
    self.xmppRosterStorage = [XMPPRosterCoreDataStorage sharedInstance];
    self.xmppRoster = [[XMPPRoster alloc] initWithRosterStorage:self.xmppRosterStorage];
    //(2)      
    [self.xmppRoster activate:self.xmppStream];
    //   _xmppRosterMemoryStorage   _xmppRoster      
    [self.xmppRoster addDelegate:self delegateQueue:dispatch_get_main_queue()];
    //(3)          ,        
    [self.xmppRoster setAutoAcceptKnownPresenceSubscriptionRequests:NO];
    [self.xmppRoster setAutoFetchRoster:YES];
    //3.    
    [self.xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:nil];
    //4.     、      
    //(1)     
    _xmppAutoPing = [[XMPPAutoPing alloc] init];
    _xmppAutoPing.pingInterval = 20.f; //      
    [_xmppAutoPing activate:_xmppStream];
    [_xmppAutoPing addDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];
    //(2)       
    _xmppReconnect = [[XMPPReconnect alloc] init];
    _xmppReconnect.autoReconnect = YES;
    _xmppReconnect.reconnectDelay = 0.f;//       ,        ,   
    _xmppReconnect.reconnectTimerInterval = 3.f;//   3       
    [_xmppReconnect activate:_xmppStream];
    [_xmppReconnect addDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];
}
2.pingについて、こちらのやり方は、クライアントが20 sごとにpingパケットを送信し、クライアントが送信した二回のpingパケットがサーバに送られた後、サーバーから戻ってきたPongパケットを受け取っていない場合、手動で接続を切断することです。
#pragma mark - XMPPAutoPingDelegate
- (void)xmppAutoPingDidReceivePong:(XMPPAutoPing *)sender{
    //      1    ,   ping ,       
    if (pingTimeoutCount > 0) {
        pingTimeoutCount = 0;
    }
}
- (void)xmppAutoPingDidTimeout:(XMPPAutoPing *)sender {
    //       , disconnect 
    pingTimeoutCount++;
    if (pingTimeoutCount >= 2) {
        [self.xmppStream disconnect];
    }
}
3.重連類を初期化したら、重連類代理のフィードバックを記入し、XMPPが接続を切断すると、フィードバック方法を実行します。
#pragma mark - XMPPReconnectDelegate
- (void)xmppReconnect:(XMPPReconnect *)sender didDetectAccidentalDisconnect:(SCNetworkConnectionFlags)connectionFlags {
    QCLog(@"xmpp      。");
}
- (BOOL)xmppReconnect:(XMPPReconnect *)sender shouldAttemptAutoReconnect:(SCNetworkConnectionFlags)connectionFlags {
    reconnectCount++;
    self.isReconnecting = YES;
    QCLog(@"xmpp    ... %@ ", @(reconnectCount));
    
    if (reconnectCount < 5) {
    }
    else if (reconnectCount >= 5 && reconnectCount <= 10) {
        [self.xmppReconnect resSetupReconnectTimerWithTimerInterval:9.f];
    }
    else if (reconnectCount > 10 && reconnectCount <= 15) {
        [self.xmppReconnect resSetupReconnectTimerWithTimerInterval:15.f];
    }
    else {
        [self reconnectImmediately];
    }
    return YES;
}
- (void)reconnectImmediately {
    self.xmppReconnect.reconnectTimerInterval = 3.f;
    reconnectCount = 0;
    
    [self.xmppReconnect stop];
    [self.xmppReconnect manualStart];
}
ここで説明したいのですが、接続を失うとすぐに重連が起動します。前の5回は3秒ごとに重連して、後の5回は9秒ごとに重連して、後の5回は15秒の重さで連続しています。もしこの15回が失敗したら、この規則に従って重連をします。何回も失敗していません。サーバーに一定の圧力をかけます。自分で利害を考えることができます。よく考えてみてください。何度も失敗しました。もう連行する必要はないでしょう。10回接続しても失敗したら、もう重ならないようにできます。ユーザがアクティブにある操作をトリガする時に再接続を開始するか、またはアプリの前のバックグラウンドが切り替わる時に再接続を行います。これらはただ個人の考えです。