我正在尝试为我的 C++ 应用程序实施 MQTT 订阅和发布者。发布工作正常,但订阅者似乎根本没有收到任何消息。
#include "MbedJSONValue.h"
#include "OLEDDisplay.h"
#include "http_request.h"
#include "mbed.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <MQTTClient.h>
#include <MQTTClientMbedOs.h>
#include <MQTTNetwork.h>
#include <MQTTmbed.h>
// UI
OLEDDisplay oled(MBED_CONF_IOTKIT_OLED_RST, MBED_CONF_IOTKIT_OLED_SDA,
MBED_CONF_IOTKIT_OLED_SCL);
SPI spi(MBED_CONF_IOTKIT_LED_SPI_MOSI, NC, MBED_CONF_IOTKIT_LED_SPI_SCLK);
DigitalOut myled(MBED_CONF_IOTKIT_LED1);
DigitalIn userbutton(MBED_CONF_IOTKIT_BUTTON1);
// Topic's publish
char *topicLightsOn = (char *)"iotkit/pub_lights";
// Topic's subscribe
char *topicLights = (char *)"iotkit/sub_lights/#";
// MQTT Brocker
char *hostname = (char *)"192.168.1.1";
int port = 1883;
// MQTT Message
MQTT::Message message;
// I/O Buffer
char *buf = "0";
// LED strip
unsigned int strip[9];
//function to turn lights on
void writeLED() {
for (int p = 0; p < 9; p++)
spi.write(strip[p]);
}
//function to turn lights off
void clearLED() {
for (int p = 0; p < 9; p++) {
strip[p] = 0;
spi.write(strip[p]);
}
}
//callback on message arrived
void messageArrived(MQTT::MessageData &md) {
printf("message arrived");
int value;
MQTT::Message &message = md.message;
printf("Message arrived: qos %d, retained %d, dup %d, packetid %d\n",
message.qos, message.retained, message.dup, message.id);
printf("Topic %.*s, ", md.topicName.lenstring.len,
(char *)md.topicName.lenstring.data);
printf("Payload %.*s\n", message.payloadlen, (char *)message.payload);
sscanf((char *)message.payload, "%i", &value);
// TODO: Turn lights off/on
if (value == 1) {
// LED 1
strip[0] = 1;
strip[1] = 0;
strip[2] = 0;
writeLED();
// LED 2
strip[3] = 1;
strip[4] = 0;
strip[5] = 0;
writeLED();
// LED 3
strip[6] = 1;
strip[7] = 0;
strip[8] = 0;
writeLED();
// setting the buf to the new value
buf = (char *)message.payload;
} else {
clearLED();
}
}
// function to publish to topic
void publish(MQTTNetwork &mqttNetwork,
MQTT::Client<MQTTNetwork, Countdown> &client, char *topic) {
MQTT::Message message;
message.qos = MQTT::QOS0;
message.retained = false;
message.dup = false;
message.payload = (void *)buf;
message.payloadlen = strlen(buf) + 1;
client.publish(topic, message);
}
/* char message[1024]; */
int main() {
oled.clear();
clearLED();
WiFiInterface *network = WiFiInterface::get_default_instance();
if (!network) {
printf("ERROR: No WiFiInterface found.\n");
return -1;
}
printf("\nConnecting to %s...\n", MBED_CONF_APP_WIFI_SSID);
int ret =
network->connect(MBED_CONF_APP_WIFI_SSID, MBED_CONF_APP_WIFI_PASSWORD,
NSAPI_SECURITY_WPA_WPA2);
if (ret != 0) {
printf("\nConnection error: %d\n", ret);
return -1;
}
MQTTNetwork mqttNetwork(network);
MQTT::Client<MQTTNetwork, Countdown> client(mqttNetwork);
printf("Connecting to %s:%d\r\n", hostname, port);
int rc = mqttNetwork.connect(hostname, port);
if (rc != 0)
printf("rc from TCP connect is %d\r\n", rc);
// Zugangsdaten - der Mosquitto Broker ignoriert diese
MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
data.MQTTVersion = 3;
data.clientID.cstring =
(char *)network->get_mac_address();
data.username.cstring =
(char *)network->get_mac_address();
data.password.cstring = (char *)"password";
if ((rc = client.connect(data)) != 0) {
printf("rc from MQTT connect is %d\r\n", rc);
}
// MQTT Subscribe!
client.subscribe(topicLights, MQTT::QOS0, messageArrived);
printf("MQTT subscribe %s\n", topicLights);
printf("Success\n\n");
printf("MAC: %s\n", network->get_mac_address());
SocketAddress a;
network->get_ip_address(&a);
printf("IP: %s\n", a.get_ip_address());
while (1) {
publish(mqttNetwork, client, topicLightsOn);
thread_sleep_for(10000);
/* client.subscribe(topicLights, MQTT::QOS0, messageArrived); */
printf("\nlight status: %s\n", buf);
}
}
如果 client.subscribe(topicLights, MQTT::QOS0, messageArrived);
处于活动状态,订阅将触发到达的消息,即使它们是旧消息。
我正在使用 Mosquitto 代理并将其全部放入 node-red 的上下文中。来自发布者的消息也保存到 MongoDB 集合中
有什么想法吗?