MQTT客户端代码(C语言)

  1. 创建 mqtt 客户端对象
  2. 设置回调函数
  3. 连接 MQTT 服务器 
  4. 发布上线消息 
  5. 订阅主题 
  6. 发布芯片温度信息 
/***************************************************************
 Copyright © ALIENTEK Co., Ltd. 1998-2021. All rights reserved.
 文件名 : mqttClient.c
 作者 : 邓涛
 版本 : V1.0
 描述 : 开发板上的MQTT客户端应用程序示例代码
 其他 : 无
 论坛 : www.openedv.com
 日志 : 初版 V1.0 2021/7/20 邓涛创建
 ***************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "MQTTClient.h"		//包含MQTT客户端库头文件

/* ########################宏定义##################### */
#define BROKER_ADDRESS	"tcp://iot.ranye-iot.net:1883"	//然也物联平台社区版MQTT服务器地址

/* 客户端id、用户名、密码 *
 * 当您成功申请到然也物联平台的社区版MQTT服务后
 * 然也物联工作人员会给你发送8组用于连接社区版MQTT服务器
 * 的客户端连接认证信息:也就是客户端id、用户名和密码
 * 注意一共有8组,您选择其中一组覆盖下面的示例值
 * 后续我们使用MQTT.fx或MQTTool的时候 也需要使用一组连接认证信息
 * 去连接社区版MQTT服务器!
 * 由于这是属于个人隐私 笔者不可能将自己的信息写到下面 */
#define CLIENTID		"您的客户端ID"		//客户端id
#define USERNAME		"您的用户名"		//用户名
#define PASSWORD		"您的密码"			//密码

/* 然也物联社区版MQTT服务为每个申请成功的用户
 * 提供了个人专属主题级别,在官方发给您的微信信息中
 * 提到了
 * 以下 dt_mqtt/ 便是笔者的个人主题级别
 * dt_mqtt其实就是笔者申请社区版MQTT服务时注册的用户名
 * 大家也是一样,所以你们需要替换下面的dt_mqtt前缀
 * 换成你们的个人专属主题级别(也就是您申请时的用户名)
 */
#define WILL_TOPIC		"dt_mqtt/will"		//遗嘱主题
#define LED_TOPIC		"dt_mqtt/led"		//LED主题
#define TEMP_TOPIC		"dt_mqtt/temperature"	//温度主题
/* ################################################# */
//接收消息的回调函数;
static int msgarrvd(void *context, char *topicName, int topicLen,
			MQTTClient_message *message)
{
	if (!strcmp(topicName, LED_TOPIC)) {//校验消息的主题
		if (!strcmp("2", message->payload))	//如果接收到的消息是"2"则设置LED为呼吸灯模式
			system("echo heartbeat > /sys/class/leds/sys-led/trigger");
		if (!strcmp("1", message->payload)) {//如果是"1"则LED常量
			system("echo none > /sys/class/leds/sys-led/trigger");
			system("echo 1 > /sys/class/leds/sys-led/brightness");
		}
		else if (!strcmp("0", message->payload)) {//如果是"0"则LED熄灭
			system("echo none > /sys/class/leds/sys-led/trigger");
			system("echo 0 > /sys/class/leds/sys-led/brightness");
		}
		// 接收到其它数据 不做处理
	}

	/* 释放占用的内存空间 */
	MQTTClient_freeMessage(&message);
	MQTTClient_free(topicName);

	/* 退出 */
	return 1;
}

static void connlost(void *context, char *cause)
{
	printf("\nConnection lost\n");
	printf("    cause: %s\n", cause);
}

int main(int argc, char *argv[])
{
	MQTTClient client;
	//用宏初始化连接信息结构体;
	MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
	//用宏初始化遗嘱结构体
	MQTTClient_willOptions will_opts = MQTTClient_willOptions_initializer;
	//用宏初始化发布消息结构体;
	MQTTClient_message pubmsg = MQTTClient_message_initializer;
	int rc;

	/* 创建mqtt客户端对象 */
	if (MQTTCLIENT_SUCCESS !=
			(rc = MQTTClient_create(&client, BROKER_ADDRESS, CLIENTID,
			MQTTCLIENT_PERSISTENCE_NONE, NULL))) {
		printf("Failed to create client, return code %d\n", rc);
		rc = EXIT_FAILURE;
		goto exit;
	}

	/* 设置回调 */
	//connlost,msgarrvd;最后一个是发布已确认的回调函数,设为NULL表示不检查是否发送成功;
	if (MQTTCLIENT_SUCCESS !=
			(rc = MQTTClient_setCallbacks(client, NULL, connlost,
			msgarrvd, NULL))) {
		printf("Failed to set callbacks, return code %d\n", rc);
		rc = EXIT_FAILURE;
		goto destroy_exit;
	}

	/* 连接MQTT服务器 */
	//在初始化的基础上,配置遗嘱结构体
	will_opts.topicName = WILL_TOPIC;	//遗嘱主题
	will_opts.message = "Unexpected disconnection";//遗嘱消息
	will_opts.retained = 1;	//保留消息
	will_opts.qos = 0;		//QoS0
	//在初始化后的基础上,配置连接信息的结构体;
	conn_opts.will = &will_opts;
	conn_opts.keepAliveInterval = 30;	//心跳包间隔时间
	conn_opts.cleansession = 0;			//cleanSession标志
	conn_opts.username = USERNAME;		//用户名
	conn_opts.password = PASSWORD;		//密码
	if (MQTTCLIENT_SUCCESS !=
			(rc = MQTTClient_connect(client, &conn_opts))) {
		printf("Failed to connect, return code %d\n", rc);
		rc = EXIT_FAILURE;
		goto destroy_exit;
	}
	printf("MQTT服务器连接成功!\n");

	/* 发布上线消息 */
	pubmsg.payload = "Online";	//消息的内容
	pubmsg.payloadlen = 6;		//内容的长度
	pubmsg.qos = 0;				//QoS等级
	pubmsg.retained = 1;		//保留消息
	if (MQTTCLIENT_SUCCESS !=
		(rc = MQTTClient_publishMessage(client, WILL_TOPIC, &pubmsg, NULL))) {
		printf("Failed to publish message, return code %d\n", rc);
		rc = EXIT_FAILURE;
		goto disconnect_exit;
	}

	/* 订阅主题 dt_mqtt/led */
	if (MQTTCLIENT_SUCCESS !=
			(rc = MQTTClient_subscribe(client, LED_TOPIC, 0))) {
		printf("Failed to subscribe, return code %d\n", rc);
		rc = EXIT_FAILURE;
		goto disconnect_exit;
	}

	/* 向服务端发布芯片温度信息 */
	for ( ; ; ) {

		MQTTClient_message tempmsg = MQTTClient_message_initializer;
		char temp_str[10] = {0};
		int fd;

		/* 读取温度值 */
		fd = open("/sys/class/thermal/thermal_zone0/temp", O_RDONLY);
		read(fd, temp_str, sizeof(temp_str));//读取temp属性文件即可获取温度
		close(fd);

		/* 发布温度信息 */
		tempmsg.payload = temp_str;	//消息的内容
		tempmsg.payloadlen = strlen(temp_str);		//内容的长度
		tempmsg.qos = 0;				//QoS等级
		tempmsg.retained = 1;		//保留消息
		if (MQTTCLIENT_SUCCESS !=
			(rc = MQTTClient_publishMessage(client, TEMP_TOPIC, &tempmsg, NULL))) {
			printf("Failed to publish message, return code %d\n", rc);
			rc = EXIT_FAILURE;
			goto unsubscribe_exit;
		}

		sleep(30);		//每隔30秒 更新一次数据
	}

unsubscribe_exit:
	if (MQTTCLIENT_SUCCESS !=
		(rc = MQTTClient_unsubscribe(client, LED_TOPIC))) {
		printf("Failed to unsubscribe, return code %d\n", rc);
		rc = EXIT_FAILURE;
	}
disconnect_exit:
	if (MQTTCLIENT_SUCCESS !=
		(rc = MQTTClient_disconnect(client, 10000))) {
		printf("Failed to disconnect, return code %d\n", rc);
		rc = EXIT_FAILURE;
	}
destroy_exit:
	MQTTClient_destroy(&client);
exit:
	return rc;
}

  • 1
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值