ARMmbed / mbed-mqtt

Mbed-os MQTT and MQTT-SN library, based on Eclipse Paho project.
Other
47 stars 26 forks source link

The device can only receive the first message. #32

Closed IveanEx closed 3 years ago

IveanEx commented 3 years ago

I encountered exactly the same problem listed in this link. I am using NUCLEO H743ZI2 and Mbed OS 6.6. I subscribed a title on the device and tried to send JSONS from my computer to the device. However, the device can only receive first message at the time when calling function mqttyield in another thread. (In another word, for the first message, if I do not call mqttyield manually, my device can not jump into message handler; after that, I cannot receive any messages even I call mqttyield).

IveanEx commented 3 years ago

The message sending from my computer to the device is:

{
"MAC":  "00:80:e1:32:00:31",
"HS1": 1000,
"HS2": 1000
}

And some part of the codes are listed as follows:

  void mqttyield(MQTTClient *uploadclient) {
  printf("MQTT Client is Yielding...\n");
  uploadclient->yield();
}
  void messageArrived(MQTT::MessageData &md) ;

int main(){
  uploadsocket.open(&eth);
  satemp.set_ip_address("192.168.2.2"); // For Debug
  satemp.set_port(1883);
  status = uploadsocket.connect(satemp);
  if (status == NSAPI_ERROR_OK) {
    printf("Socket Connection to the Host had been established. \n");
  }

  MQTTPacket_connectData MQTToption = MQTTPacket_connectData_initializer;
  MQTToption.MQTTVersion = 3;
  MQTToption.keepAliveInterval = MQTT_KEEP_ALIVE;
  MQTToption.clientID.cstring = (char *)eth.get_mac_address();
  status = uploadclient.connect(MQTToption);
  if (status == NSAPI_ERROR_OK) {
    printf("MQTT Connection to the Host had been established. \n");
  }
  status = uploadclient.subscribe("TASK_ASSIGN", MQTT::QOS0, messageArrived);
  uploadthread.start(callback(&uploadqueue, &EventQueue::dispatch_forever));
  uploadqueue.call_every(MQTT_KEEP_ALIVE * 1000, mqttyield, &uploadclient);
while(1);
}

void messageArrived(MQTT::MessageData &md) {
  printf("Message Arrived. \n");
  cJSON *message = cJSON_Parse((const char *)md.message.payload);
  // Do something magic (ls)
  cJSON_Delete(message);
}
IveanEx commented 3 years ago

I solved the problems by myself. I called printf in Arrived Message Handler, which is not ISR safe. I solved it by sending the task to EventQueue.