Loading

IOS:记录一次MQTT的简单基本使用以及断线重连

关于MQTT的一些理论的东西就不说了,作用简单的说就是订阅者实时收听主题的消息,发送者对主题发送消息,订阅者可以收到

 

 

-(void)initBaseInfo{

    tranpost=[[MQTTCFSocketTransport alloc]init];
    tranpost.host=@"";//MQTT服务器地址
    tranpost.port=;//服务器端口

    mqttSess=[[MQTTSession alloc]init];
    mqttSess.transport=tranpost;
    mqttSess.delegate=self;
    NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
    NSString *strClid=[defaults objectForKey:YYBNAME];
    mqttSess.clientId=strClid;
    [mqttSess setUserName:@""];//mqtt账号密码
    [mqttSess setPassword:@""];
    [mqttSess connectAndWaitTimeout:1];//会话链接并设置超时时间
//    [mqttSess connect];
    [mqttSess connectWithConnectHandler:^(NSError *error) {//连接后即可进行订阅
        if(error)
            NSLog(@"error===%@",error);
        else
        {  NSLog(@"connectwithconnect方法运行成功");

            [mqttSess subscribeToTopic:@"XXXX" atLevel:MQTTQosLevelAtMostOnce subscribeHandler:^(NSError *error, NSArray<NSNumber *> *gQoss) {
                   if(error)
                       NSLog(@"mqtt 订阅失败-%@",error.localizedDescription);
                   else
                       NSLog(@"mqtt 订阅成功-%@",gQoss);
               }];



        }
    }];
}
- (void)newMessage:(MQTTSession *)session data:(NSData *)data onTopic:(NSString *)topic qos:(MQTTQosLevel)qos retained:(BOOL)retained mid:(unsigned int)mid
{
    if(data)
    {
        NSLog(@"data不为空");
        
        //发布的命令是字符串
        NSString *str=[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"收到的data是%@",str);
        
      
        
        
    }
    else{
        NSLog(@"回调为空");
    }

    
}

上面这个是收听的方法,整体来说就是些基本的设置,然后是连接,订阅,收听

关于断线重连,我使用的是代理方法,这里判断状态,如果没连上,会一直连接,如果判断event的话,只会执行一次

- (void)handleEvent:(MQTTSession *)session event:(MQTTSessionEvent)eventCode error:(NSError *)error
{
    NSLog(@"执行了MQTThandleEVent方法");
    if(session.status==4)
    {
        NSLog(@"执行了MQTTconnect方法");
        [mqttSess connect];
    }
    
}

另外还有添加监听,或者计时器的方式,使用监听或者计时器,记住离开页面时移除监听,销毁定时器

[mqttSess addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionOld context:nil];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
    if(mqttSess.status==4)
    {
        NSLog(@"执行了MQTT断线重连方法");
        [mqttSess connect];
    }
}

 上面这个只是重新连接好像收不到消息,网上有种说法是多加个属性设置setCleanSessionFlag:false

最后我采用的是下面的方式,用的相关的代理方法,判断事件来进行对应的操作。经测试,第一次验证会触发订阅,随后主动断开wifi,然后过几秒再连上wifi,会自动连接触发订阅。

- (void)handleEvent:(MQTTSession *)session event:(MQTTSessionEvent)eventCode error:(NSError *)error
{
    NSLog(@"执行了MQTThandleEVent方法");
    if(eventCode == MQTTSessionEventConnected)
    {
        NSLog(@"连接成功订阅");
        dispatch_async(dispatch_get_main_queue(),^{
            [mqttSess subscribeToTopic:@"THE9" atLevel:MQTTQosLevelExactlyOnce subscribeHandler:^(NSError *error, NSArray<NSNumber *> *gQoss) {
                if(error)
                    NSLog(@"mqtt 订阅失败-%@",error.localizedDescription);
                else
                    NSLog(@"mqtt 订阅成功-%@",gQoss);
            }];
            
        });
    }
    else if(eventCode==MQTTSessionEventConnectionClosed)
    {
        [mqttSess connect];
    }
}

 

还有个方法是发送,可以测试连通性,这儿我就没写出来,,在官方的GitHub介绍处有展示

有一些问题是需要考虑的东西,例如断线重连,进入后台,流量下的使用,这些都是要去测试考虑的地方

posted @ 2021-01-27 15:47  DDD-SagerKing  阅读(829)  评论(0编辑  收藏  举报