Я пытаюсь заставить Azure IOT Hub вести себя (более или менее) как брокер MQTT.
Я хочу опубликовать sh сообщение на устройствах / {deviceid} / messages / events / и затем получить его на устройствах / {deviceid} / messages / devicebound / #.
Я использую библиотеку M2MQTT, и до сих пор я могу подключиться к концентратору IOT и опубликовать sh сообщение для событий topi c. Используя DeviceExplorer, я вижу сообщение, поступающее на концентратор.
По какой-то причине сообщение не передается на topi c, привязанную к устройству, и MqttClient_MqttMsgPublishReceived никогда не запускается. Событие запускается при использовании DeviceExplorer и отправке оттуда сообщения.
Итак ... Я думаю, что мне чего-то не хватает ни в коде, ни в конфигурации IOT Hub.
Кто-нибудь знает, что я делаю не так?
Это мой код:
using Microsoft.Azure.Devices.Common.Security;
using Newtonsoft.Json;
using System;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Windows.Forms;
using uPLibrary.Networking.M2Mqtt;
using uPLibrary.Networking.M2Mqtt.Messages;
namespace DemoM2MqttAzure
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private const string IOTHubURI = "TESTIOTHUB.azure-devices.net";
private const string IOTDeviceID = "IOTDevice";
private string IOTDeviceUsername = string.Format("{0}/{1}/?api-version=2018-06-30", IOTHubURI, IOTDeviceID);
private const string IOTDevicePrimaryKey = "xxx";
private string IOTSubscribeDeviceTopic = string.Format("devices/{0}/messages/devicebound/#", IOTDeviceID);
private string IOTPublishDeviceTopic = string.Format("devices/{0}/messages/events/", IOTDeviceID);
//M2MQTT client.
MqttClient mqttClient;
private void buttonStartMQTT_Click(object sender, EventArgs e)
{
mqttClient = new MqttClient(IOTHubURI, 8883, true, MqttSslProtocols.TLSv1_0, UserCertificateSelectionCallback, null);
mqttClient.ProtocolVersion = MqttProtocolVersion.Version_3_1_1;
mqttClient.MqttMsgPublishReceived += MqttClient_MqttMsgPublishReceived;
mqttClient.MqttMsgPublished += MqttClient_MqttMsgPublished;
mqttClient.MqttMsgSubscribed += MqttClient_MqttMsgSubscribed;
string IOTDevicePassword = CreateSharedAccessSignature();
mqttClient.Connect(IOTDeviceID, IOTDeviceUsername, IOTDevicePassword);
if(mqttClient.IsConnected)
{
MessageBox.Show("Connected!");
}
else
{
MessageBox.Show("Connection failed.");
}
}
private void MqttClient_MqttMsgSubscribed(object sender, MqttMsgSubscribedEventArgs e)
{
byte[] qosLevels = e.GrantedQoSLevels;
ushort msgId = e.MessageId;
MessageBox.Show("Event subscribed");
}
private string CreateSharedAccessSignature()
{
string target = string.Format("{0}/devices/{1}", IOTHubURI, IOTDeviceID);
return new SharedAccessSignatureBuilder
{
Key = IOTDevicePrimaryKey,
Target = target,
KeyName = null,
TimeToLive = TimeSpan.FromDays(360)
}.ToSignature();
}
private void buttonSubscribe_Click(object sender, EventArgs e)
{
if(mqttClient.IsConnected)
{
mqttClient.Subscribe(new string[] { IOTSubscribeDeviceTopic }, new byte[] { MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE });
}
else
{
MessageBox.Show("Not connected.");
}
}
private void buttonPublish_Click(object sender, EventArgs e)
{
if (mqttClient.IsConnected)
{
var telemetryDataPoint = new
{
deviceId = IOTDeviceID,
value = 123.456,
text = "abc"
};
var json = JsonConvert.SerializeObject(telemetryDataPoint);
ushort result = mqttClient.Publish(IOTPublishDeviceTopic, Encoding.UTF8.GetBytes(json), MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE, true);
}
else
{
MessageBox.Show("Not connected.");
}
}
private void MqttClient_MqttMsgPublished(object sender, MqttMsgPublishedEventArgs e)
{
if (e.IsPublished)
{
MessageBox.Show("Event message published.");
}
else
{
MessageBox.Show("Message was not published...");
}
}
private void MqttClient_MqttMsgPublishReceived(object sender, uPLibrary.Networking.M2Mqtt.Messages.MqttMsgPublishEventArgs e)
{
MessageBox.Show("Event message publish received.");
}
private bool UserCertificateSelectionCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if(mqttClient.IsConnected)
{
mqttClient.Disconnect();
}
}
}
}