Azure узел IOT SDK, как настроить обратные вызовы для исключений MQTT

Я использовал пакет SDK Azure IOT для C в нескольких проектах. Там довольно хорошая документация, и понятно, как зарегистрировать обратный вызов, чтобы получать уведомления, если сообщение не может быть отправлено или если соединение MQTT обрывается. Просматривая SDK javascript для узла, я не могу понять, как регистрировать подобные обратные вызовы. Например, после создания клиента я могу вызвать client.open(onConnect), а метод onConnect вызывается при установлении соединения. Я также могу позвонить client.sendEvent(message,...), чтобы отправить сообщение, и в случае успеха получаю уведомление о том, что сообщение поставлено в очередь. Однако:

  • Как зарегистрировать обратный вызов, чтобы получать уведомления, если соединение mqtt прервано?
  • Как зарегистрировать обратный вызов, чтобы сообщить, успешно ли получен пакет (QOS 1 или 2) или не удалось отправить?
  • Как указать желаемый уровень QOS?

Спасибо


person farhadf    schedule 12.11.2020    source источник
comment
ответы на некоторые вопросы см. на docs.microsoft.com/en-us/azure/iot-hub/iot-hub-mqtt-support   -  person Roman Kiss    schedule 12.11.2020


Ответы (1)


Во-первых, несколько замечаний относительно поддержки MQTT QoS в IoT-хабе:

  • Центр Интернета вещей не поддерживает сообщения QoS 2. Если приложение устройства публикует сообщение с QoS 2, Центр Интернета вещей закрывает сетевое подключение. Когда приложение устройства подписывается на тему с QoS 2, Центр Интернета вещей предоставляет максимальный уровень QoS 1 в пакете SUBACK. После этого Центр Интернета вещей доставляет сообщения на устройство с использованием QoS 1.
  • По умолчанию пакеты SDK для устройств подключаются к центру Интернета вещей с QoS 1 для обмена сообщениями с центром Интернета вещей.

Дополнительные сведения см. в разделе Общение с центром Интернета вещей с помощью протокола MQTT< /а>.

Теперь, перейдя к вопросу, у вас есть 2 варианта:

Использование пакета SDK для Интернета вещей Azure:

Если вы хотите использовать SDK устройства Центра Интернета вещей, ниже приведен один справочник из < href="https://github.com/Azure/azure-iot-sdk-node/blob/master/device/samples/simple_sample_device.js" rel="nofollow noreferrer">официальный образец, который обрабатывает отключение сценарий. Что касается обмена, связанного с QoS 1 (например, подтверждение PUBACK), он не разрешается на более низком уровне, а обрабатывается внутри, чтобы гарантировать гарантированную доставку сообщения. Для непосредственного использования MQTT обратитесь к следующей части моего ответа.

// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

'use strict';

const Protocol = require('azure-iot-device-mqtt').Mqtt;
// Uncomment one of these transports and then change it in fromConnectionString to test other transports
// const Protocol = require('azure-iot-device-amqp').AmqpWs;
// const Protocol = require('azure-iot-device-http').Http;
// const Protocol = require('azure-iot-device-amqp').Amqp;
// const Protocol = require('azure-iot-device-mqtt').MqttWs;
const Client = require('azure-iot-device').Client;
const Message = require('azure-iot-device').Message;

// String containing Hostname, Device Id & Device Key in the following formats:
//  "HostName=<iothub_host_name>;DeviceId=<device_id>;SharedAccessKey=<device_key>"
const deviceConnectionString = process.env.DEVICE_CONNECTION_STRING;
let sendInterval;

function disconnectHandler () {
  clearInterval(sendInterval);
  client.open().catch((err) => {
    console.error(err.message);
  });
}

// The AMQP and HTTP transports have the notion of completing, rejecting or abandoning the message.
// For example, this is only functional in AMQP and HTTP:
// client.complete(msg, printResultFor('completed'));
// If using MQTT calls to complete, reject, or abandon are no-ops.
// When completing a message, the service that sent the C2D message is notified that the message has been processed.
// When rejecting a message, the service that sent the C2D message is notified that the message won't be processed by the device. the method to use is client.reject(msg, callback).
// When abandoning the message, IoT Hub will immediately try to resend it. The method to use is client.abandon(msg, callback).
// MQTT is simpler: it accepts the message by default, and doesn't support rejecting or abandoning a message.
function messageHandler (msg) {
  console.log('Id: ' + msg.messageId + ' Body: ' + msg.data);
  client.complete(msg, printResultFor('completed'));
}

function generateMessage () {
  const windSpeed = 10 + (Math.random() * 4); // range: [10, 14]
  const temperature = 20 + (Math.random() * 10); // range: [20, 30]
  const humidity = 60 + (Math.random() * 20); // range: [60, 80]
  const data = JSON.stringify({ deviceId: 'myFirstDevice', windSpeed: windSpeed, temperature: temperature, humidity: humidity });
  const message = new Message(data);
  message.properties.add('temperatureAlert', (temperature > 28) ? 'true' : 'false');
  return message;
}

function errorCallback (err) {
  console.error(err.message);
}

function connectCallback () {
  console.log('Client connected');
  // Create a message and send it to the IoT Hub every two seconds
  sendInterval = setInterval(() => {
    const message = generateMessage();
    console.log('Sending message: ' + message.getData());
    client.sendEvent(message, printResultFor('send'));
  }, 2000);

}

// fromConnectionString must specify a transport constructor, coming from any transport package.
let client = Client.fromConnectionString(deviceConnectionString, Protocol);

client.on('connect', connectCallback);
client.on('error', errorCallback);
client.on('disconnect', disconnectHandler);
client.on('message', messageHandler);

client.open()
.catch(err => {
  console.error('Could not connect: ' + err.message);
});

// Helper function to print results in the console
function printResultFor(op) {
  return function printResult(err, res) {
    if (err) console.log(op + ' error: ' + err.toString());
    if (res) console.log(op + ' status: ' + res.constructor.name);
  };
}

Использование MQTT напрямую:

Как указано в Используя протокол MQTT напрямую (как устройство), вы также можете подключаться к конечным точкам общедоступных устройств, используя протокол MQTT на порту 8883. Для этого вы можете использовать любую доступную стандартную библиотеку MQTT (например, https://www.npmjs.com/package/mqtt). Тем не менее, обратите внимание на следующее для некоторых специальных соображений:

В пакете CONNECT устройство должно использовать следующие значения:

  • Для поля ClientId используйте deviceId.
  • В поле Имя пользователя используйте {iothubhostname}/{device_id}/?api-version=2018-06-30, где {iothubhostname} — это полное CName центра Интернета вещей. Например, если имя вашего центра Интернета вещей — contoso.azure-devices.net, а имя вашего устройства — MyDevice01, полное поле имени пользователя должно содержать: contoso.azure-devices.net/MyDevice01/?api-version=2018-06-30
  • В поле «Пароль» используйте токен SAS. Формат токена SAS такой же, как и для протоколов HTTPS и AMQP: SharedAccessSignature sig={signature-string}&se={expiry}&sr={URL-encoded-resourceURI}

Примечание

Если вы используете аутентификацию по сертификату X.509, пароли маркеров SAS не требуются. Дополнительные сведения см. в разделе Настройка X.509. безопасности в Azure IoT Hub и следуйте инструкциям кода в раздел конфигурации TLS/SSL.

Дополнительные сведения о создании токенов SAS см. в разделе об устройствах Использование токенов безопасности Центра Интернета вещей.

person krishg    schedule 12.11.2020
comment
Благодарю вас! При отправке сообщения, если обратный вызов получает успех, подразумевает ли это получение QOS 1, то есть концентратор IOT подтверждает получение сообщения? (в отличие от SDK, подтверждающего получение сообщения и помещающего его в свою очередь отправки, как это происходит с C SDK). - person farhadf; 12.11.2020
comment
Да. Если обратный вызов в client.sendEvent получает успешный результат, это будет означать, что концентратор IoT получил его (но не обязательно, что кто-то еще на стороне получателя концентратора IoT получил его еще от концентратора IoT). - person krishg; 12.11.2020