Linux 下MQTT编程

你眼里的月亮沉了又沉,

好似不堪重负的过去,

在埋怨毁了堤的眼泪,

于是,秋风又起,

于是,这落了一山的破碎,

全都有罪。

首先说下什么是MQTT(Message Queuing Telemetry Transport),它是一种轻量级的开放式消息传输协议,专门设计用于在低带宽、不稳定的网络环境中进行设备间通信。MQTT 最初由IBM开发,现在是OASIS(Organization for the Advancement of Structured Information Standards)的一个开放标准。

MQTT多用于物联网和传感器网络中,它主要具有以下特点:

  • 轻量级: MQTT 是一种轻量级协议,对网络带宽和设备资源的要求较低。这使得它非常适用于资源受限的设备,如传感器和嵌入式系统。

  • 发布/订阅模型: MQTT 使用发布/订阅模型,其中消息发布者(发布者)将消息发布到特定的主题(Topic),而订阅者则通过订阅特定主题来接收相关消息。这种模型使得设备之间的通信更为灵活。

  • 可靠性: MQTT 具有一定的消息传递保证机制。它支持三种服务质量(QoS)级别,包括最多一次(At most once)、至少一次(At least once)和仅一次(Exactly once),允许根据应用程序的要求进行消息传递的可靠性配置。

  • 持久性会话: 客户端可以选择创建持久性会话,以确保在重新连接时接收未接收的消息。

  • 遗嘱消息: 客户端可以设置遗嘱消息,以便在其意外断开连接时通知其他订阅者。

  • 广泛应用: MQTT 在物联网、远程监测、传感器网络等领域得到广泛应用,支持跨平台的消息传递。

在Linux应用开发中,我们使用MQTT可以采用移植一个MQTT的库,源码地址如下,如果下载慢可以把这个地址映射到gittee上再下载GitHub - eclipse/paho.mqtt.c: An Eclipse Paho C client library for MQTT for Windows, Linux and MacOS. API documentation: https://eclipse.github.io/paho.mqtt.c/

移植后我们就可以进行MQTT应用开发了,看代码前我们先简单说下MQTT的主要应用框架,我们开发的时候主要采用客户端的形式,也就是说我们所有的通信都相当与客户端,我们通过向服务端去订阅和发布消息进行通信,服务端可以理解成代理,它会将所有消息分发给每个订阅的人。使用时我们可以去下载个免费使用的服务端去测试我们的程序。

//! 消息订阅的回调函数
int on_messrecv(void* context, char* topicName, int topicLen, MQTTAsync_message* message)
{
    printf("recv name:\ntopic:%s,payload:%s\n", topicName, (char*)message->payload);

	//!< 这里我们可以把收到的消息放入自己定义的消息处理队列,然后单开个线程去处理这些消息
    MQTTAsync_free(topicName);
    MQTTAsync_free(message);
    return 1;         
}

void on_subscribe(void* context, MQTTAsync_successData* response)
{
    //! 这个是订阅成功的回调函数
}

//! 连接 mqtt 服务器成功回调函数
void on_connect(void *context, MQTTAsync_successData* response)
{
    MQTTAsync client = (MQTTAsync)context;
    int ret;
    MQTTAsync_responseOptions response_opt = MQTTAsync_responseOptions_initializer;
	
    printf("Succeed in connecting to mqtt-server!\n");

	response_opt.onSuccess = on_subscribe;	
	
    ret = MQTTAsync_subscribe(client, "你要订阅的主题名1", 1, &response_opt); //!< 订阅/pub主题消息
    
    if(ret != MQTTASYNC_SUCCESS)
	{
        printf("Fail to sub operater !\n");
    }

    ret = MQTTAsync_subscribe(client, "你要订阅的主题名2", 1, &response_opt); //!< 订阅/pub主题消息
    
    if(ret != MQTTASYNC_SUCCESS)
	{
        printf("Fail to sub dev self test!\n");
    }

    g_handle.is_connected = CONNECTED;
}

//! 断开与 mqtt 服务器链接回调函数
void dis_connect(void *context, MQTTAsync_failureData* response)
{
    printf("Failed to connect  mqtt-server!\n");
}

//! 向服务器发送消息成功回调函数
void on_send(void* context, MQTTAsync_successData* response)
{
    printf("Send message to mqtt server success!\n");
}

//! mqtt 客户端初始化
int mqtt_client_init(void)
{
    int ret;
	
    MQTTAsync_connectOptions conn_opt = MQTTAsync_connectOptions_initializer;								//!< 初始化连接选项

	ret = MQTTAsync_create(&g_handle.client, "服务端的IP地址", "客户端ID", MQTTCLIENT_PERSISTENCE_NONE, NULL);
    if(ret != MQTTASYNC_SUCCESS)
    {
        printf("Cannot create mqtt client!\n");
        return -1;
    }
	
    ret = MQTTAsync_setCallbacks(g_handle.client, NULL, NULL, on_messrecv, NULL); 		//!< 初始化接收消息回调;
    if(ret != MQTTASYNC_SUCCESS)
	{
        printf("Cannnot set call back function!\n");
        return  -1;
    }
	
    conn_opt.onSuccess = on_connect;
    conn_opt.onFailure = dis_connect;
    conn_opt.automaticReconnect = 1;
    conn_opt.context = g_handle.client;
    conn_opt.cleansession = 0;

	conn_opt.username = "用户名";				
    conn_opt.password = "用户密码";
	
	ret = MQTTAsync_connect(g_handle.client, &conn_opt);
	
    //因为是异步的,当MQTTAsync_connect返回的时候只是代表底层代码对参数进行了检查
    //当正确返回时,表示底层代码接收了该connect连接命令
    if(ret != MQTTASYNC_SUCCESS)
    {
        printf("Cannot start a mqttt server connect!\n");
        return -1;
    }
	
	return 0;
}

//! 发送主题
int mqtt_send_info(char *sub, char *data, int data_len)
{
	MQTTAsync_message message = MQTTAsync_message_initializer;
	MQTTAsync_responseOptions res_option = MQTTAsync_responseOptions_initializer;
	
	message.payload = data;
	message.payloadlen = data_len;
	message.qos = 1;
	res_option.onSuccess = on_send;
	
    return MQTTAsync_sendMessage(g_handle.client, sub, &message, &res_option);	//!< 发布消息
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值