MQTT v Ember.js

Před méně než 2 lety jsem se společností, pro kterou pracuji, zahájil nový projekt, který vyžaduje aplikaci Ember Octane k ovládání několika připojených zařízení IoT po celém světě. Zvolili jsme síťový protokol pro publikování/odběr MQTT pro interakci s našimi zařízeními v terénu pro jeho lehkou strukturu zpráv a omezené požadavky na šířku pásma sítě.

Po googlování javascriptové knihovny MQTT jsem našel klienta MQTT.js. V okamžiku mého hledání nebyla asynchronní verze ještě vydána, takže jsem musel zabalit klienta založeného na událostech do služby Ember a transformovat ho na klienta založeného na Promise.

Toto je povinný požadavek, protože před přihlášením k odběru tématu potřebuji připojení zprostředkovatele nebo před publikováním tématu potřebuji předplatné tématu. Někdy jste si ponechali zprávy na téma pro příjem poslední publikované hodnoty po předplatném. Jindy potřebujete publikovat prázdnou hodnotu v tématu, abyste mohli požádat o stav daného zařízení. Před odesláním zprávy tedy potřebujete pracovní předplatné na dané téma. To znamená, že javascript Promises jsou jediným způsobem, jak tyto úkoly splnit.

Když jsem psal tuto službu, nenašel jsem doplněk Ember připravený k tomu. Proto jsem se rozhodl ponořit do dokumentů a naučit se, jak vytvořit addon. Doplněk ember-mqttjs je můj první doplněk Ember!

Kód

Tato služba rozšiřuje objekt Evented Ember o vyvolávání událostí na nových zprávách, stejně jako události připojení, odpojení a mnoho dalších, které najdete v jejím readme. Kromě vyvolání těchto událostí vrací příslib pro metody připojení, přihlášení, odhlášení a publikování.

Toto je příklad jiné služby, která používá službu ember-mqttjs:

import Service, { inject as service } from '@ember/service';
import { bind } from '@ember/runloop';

export default class YourService extends Service {
  @service mqtt;
  constructor() {
    super(...arguments);
    //...
    let _fOnMessage = bind(this, this._onMessage);
    this.mqtt.on('mqtt-message', _fOnMessage); 
  }

  _onMessage(sTopic, sMessage) {
    //code to manage messages received on a certain topic
  }

  async subscribeAndPublish(sTopic, sMessage) {
    try {
      await this.mqtt.connect(HOST, USERNAME, PASSWORD)
    } catch (oError) {
      //code on connection error
    }
    try {
      await this.mqtt.subscribe(sTopic);
    } catch (oError) {
      //code for subscription error
    }
    try {
      await this.mqtt.publish(sTopic, sMessage);
    } catch (oError) {
      //code for message publish error
    }
    return Promise.resolve();
  }
//...
}

Právě jsem refaktoroval kód addonu tak, aby používal funkce async/await a přesunul jsem CI z travis na akci github (díky tomuto repo Jeldrika Haschkeho).

V budoucnu lze provést mnoho vylepšení, počínaje napsáním více testů pro pokrytí jiných případů.

Pokud máte nějaké návrhy nebo návrhy na vylepšení kódu a testů, jste vítáni!

Kontaktujte mě nebo začněte přispívat na repo projektu GitHub!