MQTT 订阅未收到消息 C++

时间:2021-04-20 07:39:54

标签: c++ mqtt publisher subscriber

我正在尝试为我的 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 集合中

Node-red config

有什么想法吗?

0 个答案:

没有答案