问题描述
Azure Web CLI (bash) 中的 C2D 消息传递
az iot device c2d-message send -d MY-DEVICE-NAME -n MY-IOT-HUB-NAME --data "It works"
这是有效的 - C2D 消息被发送到设备。该消息通过串行方式打印出来,并显示在 TFT 上。
当我提交 HTTP 请求时,目标设备上没有收到任何消息。我会在最底部包含相关的设备代码。
使用 az iot device c2d-message send
的 C2D 消息和使用下面的 HTTP 请求有区别吗?
HTTP 请求
curl -i https://MY-IOT-HUB-NAME.azure-devices.net/devices/MY-DEVICE-NAME/messages/events?api-version=2016-11-14 -H "Authorization: SharedAccessSignature sr=MY-IOT-HUB-NAME.azure-devices.net&sig=MY-SAS-SIG&se=1613476202&skn=MY-SKN" -H "Content-Type: application/json" -d'{"deviceid":"MY-DEVICE-NAME","temperature":70}'
这个 HTTP 请求正在工作,我得到一个 204,这表明 HTTP 请求格式正确并且授权正在工作。回复如下。
HTTP/1.1 204 No Content
Content-Length: 0
Server: Microsoft-HTTPAPI/2.0
x-ms-request-id: 7d78e812-9659-4b70-aed2-becd81410192
Date: Tue,16 Feb 2021 11:20:43 GMT
设备代码
为我草率的代码道歉,我是 C++ 新手。
#include <AzureIoTHub.h>
#include "AzureIoTProtocol_MQTT.h"
#include "Esp.h"
#include "Free_Fonts.h"
#include <iothub_client_ll.h>
#include "iot_configs.h"
#include "iothubtransportmqtt.h"
#include "sample_init.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "SPI.h"
#include "TFT_eSPI.h"
#include <Wire.h>
static const char ssid[] = IOT_CONfig_WIFI_SSID;
static const char pass[] = IOT_CONfig_WIFI_PASSWORD;
static const char* connectionString = DEVICE_CONNECTION_STRING;
static bool g_continueRunning = true;
static size_t g_message_count_send_confirmations = 0;
IOTHUB_MESSAGE_HANDLE message_handle;
IOTHUB_CLIENT_STATUS status;
size_t messages_sent = 0;
int message_frequency = 10000;
TFT_eSPI tft = TFT_eSPI();
unsigned long drawTime = 0;
int row = 0;
int rows = 15;
int linespace = 16;
int padding = 2;
int counter = 0;
int chars = 29;
int result = 0;
IOTHUB_DEVICE_CLIENT_LL_HANDLE device_ll_handle;
static int callbackCounter;
int receiveContext = 0;
void setup() {
Serial.begin(115200);
tft.begin();
tft.setRotation(1);
tft.fillScreen(TFT_BLACK);
logger("Connecting to WiFi...","ALERT",true,true);
logger(IOT_CONfig_WIFI_SSID,true);
sample_init(ssid,pass);
logger("Connected to WiFi",true);
IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol = MQTT_Protocol;
logger("Connecting to IoT Hub...",true);
(void)IoTHub_Init();
logger("Connected to IoT Hub",true);
device_ll_handle = IoTHubDeviceClient_LL_CreateFromConnectionString(connectionString,protocol);
logger("Creating device handle...",true);
IoTHubClient_LL_SetMessageCallback(device_ll_handle,ReceiveMessageCallback,NULL);
logger("Created device handle",true);
logger("Ready to receive C2D msgs",true);
logger("",true);
do
{
IoTHubClient_LL_DoWork(device_ll_handle);
ThreadAPI_Sleep(1);
} while (1);
IoTHubClient_LL_Destroy(device_ll_handle);
IoTHub_Deinit();
}
static IOTHUBMESSAGE_disPOSITION_RESULT ReceiveMessageCallback(IOTHUB_MESSAGE_HANDLE message,void* userContextCallback)
{
const unsigned char* buffer = NULL;
size_t size = 0;
char m_buffer[1000]; // need to work out my max buffer size and deal with this - if I send a longer message it will break!
int m = sprintf(m_buffer,"msg: %d",counter);
char niceBuffer[30] = {
0
};
(void)userContextCallback;
IoTHubMessage_GetByteArray(message,&buffer,&size);
printf("Received Message: %.*s & Size=%d\r\n",(int)size,buffer,(int)size);
if (size > chars) {
size = chars;
}
for (int i = 0; i < size; i++) {
niceBuffer[i] = buffer[i];
}
niceBuffer[chars] = '\0';
logger(niceBuffer,true);
delay(1000);
counter++;
return IOTHUBMESSAGE_ACCEPTED;
}
void logger(const char * message,const char * type,bool print_to_serial,bool print_to_display) {
if (print_to_serial) {
Serial.println(message);
} else {
}
if (print_to_display) {
// Todo 2D data for the screen
if (row == rows) {
tft.fillScreen(TFT_BLACK);
row = 0;
}
tft.setTextDatum(TL_DATUM);
tft.setTextColor(TFT_WHITE,TFT_BLACK);
tft.setFreeFont(FF1);
tft.drawString(message,padding,(padding + (linespace * row)),GFXFF);
row++;
} else {
}
}
void loop() {
//loop
}
#ifndef LOAD_GLCD
//ERROR_Please_enable_LOAD_GLCD_in_User_Setup
#endif
#ifndef LOAD_GFXFF
ERROR_Please_enable_LOAD_GFXFF_in_User_Setup!
#endif
解决方法
无法通过 HTTP 将 C2D 发送到设备。此功能需要使用 AMQP 启动,这是 Azure CLI 应用程序使用的。我不知道为什么你的 curl 请求返回 204 而不是更有意义的东西。