• MQTT遗愿(last will) paho.mqtt实现


    一、 MQTT遗嘱

    MQTT 可以设置遗嘱,客户端在连接Broker的时候将遗嘱内容(也是topic + payload形式,遗嘱也有一个主题)发送给Broker并保存在Broker中,当客户端因为非正常原因断开与Broker的连接时,Broker会将遗嘱信息发送给订阅了该主题(订阅遗嘱的主题)的客户端。

    客户端正常调用DISCONNECT断开连接时属于正常断开连接,Broker不会发送遗嘱,而且会将遗嘱从Broker中删除。

    遗嘱消息发布的条件,包括但不限于:

    • 服务端检测到了一个I/O错误或者网络故障。
    • 客户端在爆出连接(Keep Alive)的时间内未能通讯。
    • 客户端没有发送DISCONNECT保温直接关闭了网络连接。
    • 由于协议错误服务端关闭了网络连接。

    一旦被发布或者服务端收到了客户端发送的DISCONNECT报文,遗嘱消息就必须从存储的会
    话状态中移除。

    二、基于paho.mqtt.c实现遗嘱功能

    网上关于遗嘱的介绍不少,但是实际的例子却很少,按理说 paho.mqtt.c 这个库用的挺多的,但是也没找到相关的例子,自己写了一个,其实也挺简单的,代码如下:

    // mqtt-last-will.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
    //
    
    #include <iostream>
    #include <MQTTClient.h>
    
    
    #define ADDRESS     "tcp://127.0.0.1:1883"   // broker 地址
    #define CLIENTID    "mqtt_test_client"  // client id
    #define TOPIC       "MQTT Examples"     // 正常发布测试的主题
    #define PAYLOAD     "Hello World!"      //正常发布时的payload
    #define QOS         1
    #define TIMEOUT     10000L
    
    // last will topic and payload
    #define LAST_WILL_TOPIC "Iamdie"           // 遗嘱主题
    #define LAST_WILL_MSG "I am really die."   //遗嘱的内容
    
    
    int main()
    {
    	MQTTClient client;
    	MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
    	//MQTTClient_SSLOptions ssl_opts = MQTTClient_SSLOptions_initializer;  //不使用ssl加密
    	MQTTClient_willOptions will_opts = MQTTClient_willOptions_initializer;
    
    	int nRet = MQTTCLIENT_SUCCESS;
    	nRet = MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
    	if(nRet != MQTTCLIENT_SUCCESS)
    	{
             printf("Failed to create client, return code %d
    ", nRet);
    		 return -1;
        }
    	conn_opts.keepAliveInterval = 20;
    	conn_opts.cleansession = 1;
    	//conn_opts.ssl = &ssl_opts;    // ssl config   //不使用ssl加密
    
    	// last will config  遗嘱设置
    	//will_opts.retained = 1;  //retained = 1 时, broker会一直保留消息,这里不需要,使用默认的0就行
    	will_opts.topicName = LAST_WILL_TOPIC;
    	will_opts.message = LAST_WILL_MSG;
    	conn_opts.will = &will_opts;
    
    	// 连接broker
    	nRet = MQTTClient_connect(client, &conn_opts);
    	if (nRet != MQTTCLIENT_SUCCESS)
    	{
    		printf("Failed connect to broker, return code %d
    ", nRet);
    		return -1;
    	}
    
    	// 测试发布消息
    	MQTTClient_message PubMsg = MQTTClient_message_initializer;
    	MQTTClient_deliveryToken token;
    	PubMsg.payload = (void*)PAYLOAD;
    	PubMsg.payloadlen = (int)strlen(PAYLOAD);
    	PubMsg.qos = QOS;
    	PubMsg.retained = 0;
    	if ((nRet = MQTTClient_publishMessage(client, TOPIC, &PubMsg, &token)) != MQTTCLIENT_SUCCESS)
    	{
    		printf("Failed to publish message, return code %d
    ", nRet);
    		return -1;
    	}
    
    	nRet = MQTTClient_waitForCompletion(client, token, TIMEOUT);
    
    	// 这里正常执行 MQTTClient_disconnect 时是不发送遗嘱的,需要测试发送遗嘱的时候将disconnect 屏蔽掉,直接destroy就可以
    	if ((nRet = MQTTClient_disconnect(client, 10000)) != MQTTCLIENT_SUCCESS)
    	{
    		printf("Failed to disconnect, return code %d
    ", nRet);
    	}
    
    	MQTTClient_destroy(&client);
    	return 0;
    }
    
  • 相关阅读:
    iPhone开发指南应用程序核心
    id,SEL,Nil,nil,IMP,Method,Class类型
    需求驱动赢得创新
    Linux内核list&hlist解读
    转载:x86的cpu_relax解析
    hadoop开发者第三期
    Hadoop开发者入门专刊
    Hadoop源代码eclipse编译指南
    高效的使用stl::map和std::set
    配置VIM语法高亮及自动缩进
  • 原文地址:https://www.cnblogs.com/ay-a/p/13296392.html
Copyright © 2020-2023  润新知