MQTT发布和订阅初学指南

在MQTT中,发送消息的过程称为发布,而要接收消息,MQTT客户端必须订阅MQTT主题。

MQTT发布基础

客户可以自由选择发布任何主题。 当前没有保留的主题。 但是,服务器(broker)可以限制对主题的访问。

客户无法直接将消息发布给另一位客户,也不知道是否有任何客户收到该消息。

客户只能将消息发布到单个主题,而不能发布到一组主题。

但是,如果一组客户端订阅同一主题,则所有订阅了该消息的客户都可以接收到该消息。

 

发布消息的消息流和QOS


MQTT支持3个QOS级别0,1,2:

  • QOS-0 – 默认,不保证消息的传递。
  • QOS-1 – 保证消息传递,但可能会重复。
  • QOS-2 – 保证消息传递没有重复。

发布消息时使用这些级别之一,其中QOS级别0为默认级别。

如果您要尝试确保即使订者可能不在线也能收到该消息,则您需要以1或2的服务质量进行发布。

下面的示意图显示了QOS为0、1和2的消息在客户端和服务器(broker)之间的消息流。

mqtt-publish-message-flow

服务器确认使用QOS为1和2发布的消息。

这将导致发送多个消息。

QOS为0发布的消息仅需要1条消息,并且服务器不确认。

以QOS为1或2发布的消息还具有消息ID号(Message ID),可用于跟踪消息。

发布消息和保留标志


当客户端向代理发布消息时,它需要发送:

  • 消息主题
  • 消息QOS
  • 是否保留消息-保留标志

保留标志通常设置为False,这意味着服务器(broker)不会保留该消息。

如果将保留标志设置为True,则服务器(broker)将保留在该主题上设置了保留标志的最后一条消息。

已发布消息的QOS对保留的消息没有影响。

此功能主要用于传感器变化不大且不经常发布其状态的传感器。

例如,如果您有门磁,那么几乎总是一样的话,每秒发布一次状态就没有多大意义。

但是,如果仅在发布时更改其状态,则当订户订阅传感器时会发生什么。

在这种情况下,如果发布的最后一个状态没有设置保留标志,则订阅者将不会知道传感器的状态,直到传感器再次发布为止。

发布的消息会发生什么?


问题–
1.订阅者收到发布的消息后会发生什么?

2.如果没有订阅者,发布的消息将如何处理?

要回答这些问题,只需考虑电视或广播。

如果您没有调到对应的广播频道,那就错过了!

因此,对于问题1和问题2,答案是-该消息已从服务器(broker)中删除。

说明

当客户端发布有关主题的消息时,broker 将该消息分发给已订阅该主题的所有已连接客户端。

消息发送到这些客户端后,将从broker中将其删除(请参阅下面的注释)。

如果没有客户订阅该主题,或者当前没有与他们建立联系,则该消息将从broker中删除。 (看注释)

通常,broker不会存储消息。

注意:保留的消息,持久的连接和QOS级别可能导致消息临时存储在broker/服务器上。

订阅主题

要接收有关某个主题的消息,您需要订阅一个或多个主题。

订阅主题时,还需要设置主题订阅的QOS。

QOS级别及其含义与发布的消息的级别相同。

当您订阅一个或多个主题时,您实际上是在告诉broker向您发送有关该主题的消息。

为了向客户端发送消息,broker使用与客户端相同的发布机制。

您可以使用两个通配符(+和#)订阅多个主题,如理解MQTT主题教程中所述。

broker使用订阅确认消息确认所有订阅,订阅确认消息包括可用于验证订阅成功的数据包标识符。

发布和订阅问题与解答

Q:我可以发布和订阅同一主题吗?
A :是的。 在MQTT版本5中,可以防止接收到客户端发布的消息(无本地订阅)。
Q:MQTT broker可以订阅MQTT客户端吗?
A:不行
Q:将要收到的消息具有与订阅的QOS相同的QOS。
A:不一定,因为它取决于发布消息的QOS。
Q:我可以订阅来自特定客户端的消息吗?
A:不行,您只能订阅主题。

http://www.steves-internet-guide.com/mqtt-publish-subscribe/

MQTT是一种轻量级的发布/订阅协议,让我们来看看如何使用C语言实现MQTT发布订阅接口。 首先,需要使用MQTT客户端库,例如Eclipse Paho,这是一款流行的跨平台MQTT客户端库,支持C语言。可以通过以下代码行安装Eclipse Paho: ``` git clone https://github.com/eclipse/paho.mqtt.c.git cd paho.mqtt.c make ``` 接下来,让我们看看如何实现MQTT发布订阅接口: ### MQTT发布接口 ``` #include "stdio.h" #include "stdlib.h" #include "string.h" #include "MQTTClient.h" #define ADDRESS "tcp://localhost:1883" #define CLIENTID "ExampleClientPub" #define TOPIC "MQTT Examples" #define PAYLOAD "Hello World!" #define QOS 1 #define TIMEOUT 10000L int main(int argc, char* argv[]) { MQTTClient client; MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; MQTTClient_message pubmsg = MQTTClient_message_initializer; MQTTClient_deliveryToken token; int rc; MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL); conn_opts.keepAliveInterval = 20; conn_opts.cleansession = 1; if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) { printf("Failed to connect, return code %d\n", rc); exit(EXIT_FAILURE); } pubmsg.payload = PAYLOAD; pubmsg.payloadlen = strlen(PAYLOAD); pubmsg.qos = QOS; pubmsg.retained = 0; MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token); rc = MQTTClient_waitForCompletion(client, token, TIMEOUT); printf("Message with delivery token %d delivered\n", token); MQTTClient_disconnect(client, 10000); MQTTClient_destroy(&client); return rc; } ``` 这段代码使用Eclipse Paho库实现了MQTT发布接口。首先,通过MQTTClient_create函数创建MQTT客户端,然后使用MQTTClient_connect函数连接到MQTT代理。接下来,设置MQTT消息的主题、负载、QoS和保留。最后,使用MQTTClient_publishMessage函数将消息发布MQTT代理,使用MQTTClient_waitForCompletion函数等待发布完成,并使用MQTTClient_disconnect函数断开连接。 ### MQTT订阅接口 ``` #include "stdio.h" #include "stdlib.h" #include "string.h" #include "MQTTClient.h" #define ADDRESS "tcp://localhost:1883" #define CLIENTID "ExampleClientSub" #define TOPIC "MQTT Examples" #define QOS 1 #define TIMEOUT 10000L volatile MQTTClient_deliveryToken deliveredtoken; void delivered(void *context, MQTTClient_deliveryToken dt) { printf("Message with token value %d delivery confirmed\n", dt); deliveredtoken = dt; } int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message) { printf("Message arrived\n"); printf(" topic: %s\n", topicName); printf(" message: %.*s\n", message->payloadlen, (char*)message->payload); MQTTClient_freeMessage(&message); MQTTClient_free(topicName); return 1; } 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_message pubmsg = MQTTClient_message_initializer; MQTTClient_token token; int rc; MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL); conn_opts.keepAliveInterval = 20; conn_opts.cleansession = 1; if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) { printf("Failed to connect, return code %d\n", rc); exit(EXIT_FAILURE); } MQTTClient_subscribe(client, TOPIC, QOS); MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered); while (1) { // do something } MQTTClient_disconnect(client, 10000); MQTTClient_destroy(&client); return rc; } ``` 这段代码使用Eclipse Paho库实现了MQTT订阅接口。首先,通过MQTTClient_create函数创建MQTT客户端,然后使用MQTTClient_connect函数连接到MQTT代理。接下来,使用MQTTClient_subscribe函数订阅MQTT消息,并设置MQTTClient_setCallbacks回调函数处理MQTT消息。最后,使用while循环等待MQTT消息的到来。 以上就是使用C语言实现MQTT发布订阅接口的方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值