美文网首页xmppframeWork
XMPPFramework心跳包类、断线重连类

XMPPFramework心跳包类、断线重连类

作者: 路漫漫其修远兮Wzt | 来源:发表于2017-02-15 16:25 被阅读1594次

    1.XMPPStream: xmpp基础服务类;
    2.XMPPAutoPing 和 XMPPPing两个类: 心跳监听类;
    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,我这边的做法是:客户端每隔20s发送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次连接都失败了,那就不再重连。等到用户主动触发某操作的时候再启动重连,或者App前后台切换的时候做重连。这些只是个人想法。

    相关文章

      网友评论

        本文标题:XMPPFramework心跳包类、断线重连类

        本文链接:https://www.haomeiwen.com/subject/ywmqwttx.html