Как использовать MQTT в Dart

Dart — это оптимизированный для клиента язык для разработки быстрых приложений на любой платформе. Его цель — предложить наиболее продуктивный язык программирования для многоплатформенной разработки в сочетании с гибкой платформой выполнения для фреймворков приложений.

MQTT — это облегченный протокол обмена сообщениями IoT на основе модели публикации/подписки, которая может предоставлять надежные службы обмена сообщениями в режиме реального времени для подключенных устройств с минимальным кодом и пропускной способностью. Он широко используется в таких отраслях, как IoT, мобильный Интернет, интеллектуальное оборудование, Интернет транспортных средства также мощность и энергия.

Эта статья в основном знакомит с тем, как использовать mqtt_client библиотека в проекте Dart для реализации соединения, подписки, отправки и получения сообщений между клиентом и MQTT-брокер.

Подготовка

Примеры в этой статье основаны на среде macOS.

Получить SDK

Пожалуйста, обратитесь к:Получить SDK

$ brew tap dart-lang/dart
$ brew install dart
$ dart --version
Dart SDK version: 2.13.0 (stable) (Wed May 12 12:45:49 2021 +0200) on "macos_x64"

Инициализация проекта

$ dart create -t console-full mqtt_demo
$ cd mqtt_demo

Структура каталогов следующая.

├── CHANGELOG.md
├── README.md
├── analysis_options.yaml
├── bin
│   └── mqtt_demo.dart
├── pubspec.lock
└── pubspec.yaml

Установка зависимостей

В этой статье мы используем mqtt_client в качестве клиентская библиотека MQTT и установите его, выполнив следующую команду.

$ dart pub add mqtt_client

Это добавит подобную строку в проект pubspec.yaml файл:

dependencies:
  mqtt_client: ^9.6.2

Использование MQTT

Мы будем использовать бесплатный публичный MQTT-брокер предоставлено EMQ. Информация о доступе к серверу выглядит следующим образом:

  • Маклер: Broker.emqx.io
  • TCP-порт: 1883 г.
  • Порт веб-сокета: 8083

Подключение к MQTT-серверу

Редактировать bin/mqtt_demo.dart файл.

import 'dart:async';
import 'dart:io';
import 'package:mqtt_client/mqtt_client.dart';
import 'package:mqtt_client/mqtt_server_client.dart';

final client = MqttServerClient('broker-cn.emqx.io', '1883');

Future<int> main() async {
  client.logging(on: true);
  client.keepAlivePeriod = 60;
  client.onDisconnected = onDisconnected;
  client.onConnected = onConnected;
  client.pongCallback = pong;

  final connMess = MqttConnectMessage()
      .withClientIdentifier('dart_client')
      .withWillTopic('willtopic') 
      .withWillMessage('My Will message')
      .startClean() 
      .withWillQos(MqttQos.atLeastOnce);
  print('client connecting....');
  client.connectionMessage = connMess;

  try {
    await client.connect();
  } on NoConnectionException catch (e) {
    print('client exception - $e');
    client.disconnect();
  } on SocketException catch (e) {
    print('socket exception - $e');
    client.disconnect();
  }

  if (client.connectionStatus!.state == MqttConnectionState.connected) {
    print('client connected');
  } else {
    print('client connection failed - disconnecting, status is ${client.connectionStatus}');
    client.disconnect();
    exit(-1);
  }
  return 0;
}


/// The unsolicited disconnect callback
void onDisconnected() {
  print('OnDisconnected client callback - Client disconnection');
  if (client.connectionStatus!.disconnectionOrigin ==
      MqttDisconnectionOrigin.solicited) {
    print('OnDisconnected callback is solicited, this is correct');
  }
  exit(-1);
}

/// The successful connect callback
void onConnected() {
  print('OnConnected client callback - Client connection was sucessful');
}

/// Pong callback
void pong() {
  print('Ping response client callback invoked');
}

Затем выполните

$ dart run bin/mqtt_demo.dart

Мы увидим, что клиент успешно подключился к брокеру MQTT.

Подключиться к MQTT-брокеру

инструкции

MqttConnectMessage: установка параметров подключения, включая настройки тайм-аута, аутентификацию и сообщения о последних пожеланиях.

Пример подключения сертификата

/// Security context
SecurityContext context = new SecurityContext()
  ..useCertificateChain('path/to/my_cert.pem')
  ..usePrivateKey('path/to/my_key.pem', password: 'key_password')
  ..setClientAuthorities('path/to/client.crt', password: 'password');
client.secure = true;
client.securityContext = context;

Подписаться

Добавьте следующий код.

client.onSubscribed = onSubscribed;

const topic="topic/test";
print('Subscribing to the $topic topic');
client.subscribe(topic, MqttQos.atMostOnce);
client.updates!.listen((List<MqttReceivedMessage<MqttMessage?>>? c) {
  final recMess = c![0].payload as MqttPublishMessage;
  final pt = MqttPublishPayload.bytesToStringAsString(recMess.payload.message);
  print('Received message: topic is ${c[0].topic}, payload is $pt');
});

/// The subscribed callback
void onSubscribed(String topic) {
  print('Subscription confirmed for topic $topic');
}

Затем выполните

$ dart run bin/mqtt_demo.dart

Мы видим, что мы успешно подписались на Тема MQTT.

Подпишитесь на тему MQTT

Опубликовать сообщение

client.published!.listen((MqttPublishMessage message) {
  print('Published topic: topic is ${message.variableHeader!.topicName}, with Qos ${message.header!.qos}');
});

const pubTopic="test/topic";
final builder = MqttClientPayloadBuilder();
builder.addString('Hello from mqtt_client');

print('Subscribing to the $pubTopic topic');
client.subscribe(pubTopic, MqttQos.exactlyOnce);

print('Publishing our topic');
client.publishMessage(pubTopic, MqttQos.exactlyOnce, builder.payload!);

Видим, что сообщение успешно опубликовано и получаем его.

Публикация сообщений MQTT

Полный тест

Мы используем следующий код для полного теста.

import 'dart:async';
import 'dart:io';
import 'package:mqtt_client/mqtt_client.dart';
import 'package:mqtt_client/mqtt_server_client.dart';

final client = MqttServerClient('broker-cn.emqx.io', '1883');

Future<int> main() async {
  client.logging(on: false);
  client.keepAlivePeriod = 60;
  client.onDisconnected = onDisconnected;
  client.onConnected = onConnected;
  client.onSubscribed = onSubscribed;
  client.pongCallback = pong;

  final connMess = MqttConnectMessage()
      .withClientIdentifier('dart_client')
      .withWillTopic('willtopic') 
      .withWillMessage('My Will message')
      .startClean() 
      .withWillQos(MqttQos.atLeastOnce);
  print('Client connecting....');
  client.connectionMessage = connMess;

  try {
    await client.connect();
  } on NoConnectionException catch (e) {
    print('Client exception: $e');
    client.disconnect();
  } on SocketException catch (e) {
    print('Socket exception: $e');
    client.disconnect();
  }

  if (client.connectionStatus!.state == MqttConnectionState.connected) {
    print('Client connected');
  } else {
    print('Client connection failed - disconnecting, status is ${client.connectionStatus}');
    client.disconnect();
    exit(-1);
  }

  const subTopic="topic/sub_test";
  print('Subscribing to the $subTopic topic');
  client.subscribe(subTopic, MqttQos.atMostOnce);
  client.updates!.listen((List<MqttReceivedMessage<MqttMessage?>>? c) {
    final recMess = c![0].payload as MqttPublishMessage;
    final pt = MqttPublishPayload.bytesToStringAsString(recMess.payload.message);
    print('Received message: topic is ${c[0].topic}, payload is $pt');
  });

  client.published!.listen((MqttPublishMessage message) {
    print('Published topic: topic is ${message.variableHeader!.topicName}, with Qos ${message.header!.qos}');
  });

  const pubTopic="topic/pub_test";
  final builder = MqttClientPayloadBuilder();
  builder.addString('Hello from mqtt_client');

  print('Subscribing to the $pubTopic topic');
  client.subscribe(pubTopic, MqttQos.exactlyOnce);

  print('Publishing our topic');
  client.publishMessage(pubTopic, MqttQos.exactlyOnce, builder.payload!);

  print('Sleeping....');
  await MqttUtilities.asyncSleep(80);

  print('Unsubscribing');
  client.unsubscribe(subTopic);
  client.unsubscribe(pubTopic);

  await MqttUtilities.asyncSleep(2);
  print('Disconnecting');
  client.disconnect();

  return 0;
}

/// The subscribed callback
void onSubscribed(String topic) {
  print('Subscription confirmed for topic $topic');
}

/// The unsolicited disconnect callback
void onDisconnected() {
  print('OnDisconnected client callback - Client disconnection');
  if (client.connectionStatus!.disconnectionOrigin ==
      MqttDisconnectionOrigin.solicited) {
    print('OnDisconnected callback is solicited, this is correct');
  }
  exit(-1);
}

/// The successful connect callback
void onConnected() {
  print('OnConnected client callback - Client connection was sucessful');
}

/// Pong callback
void pong() {
  print('Ping response client callback invoked');
}

Выход консоли.

Тест Dart MQTT

Резюме

На этом мы закончили подключение к публичный MQTT-сервер используя библиотеку mqtt_client в Dart, и реализовал соединение, публикацию сообщений, подписку и тестирование между клиентом и сервером MQTT.

Далее читатели могут проверить Простое для понимания руководство по протоколу MQTT серия статей, предоставленных EMQ, чтобы узнать о функциях протокола MQTT, изучить более сложные приложения MQTT и начать разработку приложений и служб MQTT.

Первоначально опубликовано на https://www.emqx.com.

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *