Подписка не работает на Azure IOT Hub с M2MQTT - PullRequest
0 голосов
/ 29 февраля 2020

Я пытаюсь заставить 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();
            }
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 01 марта 2020

Итак, что вы действительно хотите сделать, это:

Устройство A -> отправляет сообщение -> IoT Hub получает его -> отправляет сообщение на устройство B -> Устройство B получает его

Вы можете создать это довольно легко, однако, не только с IoT Hub. Я бы предложил использовать простую Azure функцию посередине:

  • Устройство A отправляет сообщения в IoT Hub.
  • Функция Azure получает все D2 C (устройство-2-облако) сообщение от концентратора IoT
  • Функция использует служебный SDK IoT-концентратора для отправки сообщений C2D (устройство-облако) на Устройство B через концентратор IoT
  • Устройство B прослушивает сообщения на ../devicebound и получит сообщение там.
0 голосов
/ 29 февраля 2020

Я думаю, что MqttClient.MqttMsgPublishReceived, вероятно, сработает, когда один клиент получит опубликованное вами сообщение. Был ли запущен MqttClient_MqttMsgSubscribeed? Хотите попробовать? enter image description here См. MQTT Publi sh, подписка и отмена подписки - MQTT Essentials: часть 4

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...