Skip to content

arduino/react-native-mqtt-client

Repository files navigation

react-native-mqtt-client

MQTT client for React Native application.

Features

  • Secure MQTT connection over TLS 1.2.
  • Authentication of both of server and client by X.509 certificates.
  • Certificates and a private key stored in a device specific key store.

Dependencies

This library wraps the following libraries,

Installation

npm install --save git+https://github.com/emoto-kc-ak/react-native-mqtt-client.git#v0.1.4

Usage

import MqttClient from 'react-native-mqtt-client';

Configuring an identity

You have to configure an identity before connecting to an MQTT broker. MqttClient.setIdentity configures an identity to communicate with an MQTT broker. Certificates and a private key are stored in a device specific key store.

MqttClient.setIdentity({
  caCertPem: IOT_CA_CERT, // PEM representation string of a root certificate
  certPem: IOT_CERT, // PEM representation string of a client certificate
  keyTag: IOT_KEY, // key tag of the private key in Keystore/Keychain
  keyStoreOptions, // options for a device specific key store. may be omitted
})
  .then(() => {
    /* handle success */
  })
  .catch(({ code, message }) => {
    /* handle error */
  });

keyStoreOptions is an optional object that may have the following fields,

  • caCertAlias: (string) Alias associated with a root certificate (Android only). See KeyStore.setCertificateEntry
  • keyAlias: (string) Alias associated with a private key (Android only). See KeyStore.setKeyEntry
  • caCertLabel: (string) Label associated with a root certificate (iOS only). See kSecAttrLabel
  • certLabel: (string) Label associated with a client certificate (iOS only). See kSecAttrLabel
  • keyApplicationTag: (string) Tag associated with a private key (iOS only). See kSecAttrApplicationTag

Connecting to an MQTT broker

MqttClient.connect connects to an MQTT broker.

MqttClient.connect({
  host: IOT_ENDPOINT, // (string) Host name of an MQTT broker to connect.
  port: IOT_PORT, // (number) Port to connect.
  clientId: IOT_DEVICE_ID, // (string) Client ID of a device connecting.
})
  .then(() => {
    /* handle success */
  })
  .catch(({ code, message }) => {
    /* handle error */
  });

It attempts to connect to ssl://$IOT_ENDPOINT:$IOT_PORT.

Publishing a message

MqttClient.publish publishes a message to an MQTT broker.

MqttClient.publish(topic, payload)
  .then(() => {
    /* handle success */
  })
  .catch(({ code, message }) => {
    /* handle error */
  });

Where,

  • topic: (string) Topic where payload is to be published.
  • payload: (string) Payload to be published. Usually a stringified JSON object.

Subscribing a topic

MqttClient.subscribe subscribes a topic of an MQTT broker.

MqttClient.subscribe(topic)
  .then(() => {
    /* handle success */
  })
  .catch(({ code, message }) => {
    /* handle error */
  });

Where,

  • topic: (string) Topic to subscribe.

To handle messages in the subscribed topic, you have to handle a receive-message event.

Disconnecting from an MQTT broker

MqttClient.disconnect disconnects from an MQTT broker.

MqttClient.disconnect();

Check if client is connected to an MQTT Broker

MqttClient.isConnected checks if client is connected to an MQTT Broker.

MqttClient.isConnected();

Loading an identity

An identity stored in a device specific key store by MqttClient.setIdentity may be loaded by MqttClient.loadIdentity.

MqttClient.loadIdentity(keyStoreOptions)
  .then(() => {
    /* handle success */
  })
  .catch(({ code, message }) => {
    /* handle error */
  });

Please refer to Configuring an identity for details of keyStoreOptions.

Clearing an identity

An identity stored in a device specific key store by MqttClient.setIdentity may be cleared by MqttClient.resetIdentity.

MqttClient.resetIdentity(keyStoreOptions)
  .then(() => {
    /* handle success */
  })
  .catch(({ code, message }) => {
    /* handle error */
  });

Please refer to Configuring an identity for details of keyStoreOptions.

Testing if an identity is stored in a key store

MqttClient.isIdentityStored tests if an identity is stored in a device-specific key store.

MqttClient.isIdentityStored(keyStoreOptions)
  .then((isStored) => {
    /* handle success */
  })
  .catch(({ code, message }) => {
    /* handle error */
  });

Where,

  • isStored: (boolean) Whether an identity is stored in a device-specific key store.

Please refer to Configuring an identity for details of keyStoreOptions.

Handling events

MqttClient emits events when its state is changed, a message is arrived, and an error has occurred.

connected

A connected event is notified when connection to an MQTT broker is established.

MqttClient.addListener('connected', () => {
  /* handle connection */
});

disconnected

A disconnected event is notified when connection to an MQTT broker is disconnected.

MqttClient.addListener('disconnected', () => {
  /* handle disconnection */
});

received-message

A received-message event is notified when a message is arrived from an MQTT broker.

MqttClient.addListener('received-message', ({ topic, payload }) => {
  /* handle message */
});

Where,

  • topic: (string) Topic where a message has been published.
  • payload: (string) Payload of a message. Usually a stringified JSON object.

got-error

A got-error event is notified when an error has occurred.

MqttClient.addListener('got-error', (err) => {
  /* handle error */
});

iOS Tips

Solving pod install error

You may face an error similar to the following, when you run pod install.

[!] The following Swift pods cannot yet be integrated as static libraries:

The Swift pod `CocoaMQTT` depends upon `CocoaAsyncSocket`, which does not define modules. To opt into those targets generating module maps (which is necessary to import them from Swift when building as static libraries), you may set `use_modular_headers!` globally in your Podfile, or specify `:modular_headers => true` for particular dependencies.

In my case (React Native v0.63.3, CocoaPod v1.9.3), this error was solved by adding the following line to the Podfile of my application.

pod 'CocoaAsyncSocket', :modular_headers => true

Developing

Packaging

To package this library, please run the following command.

npm run prepare

Artifacts will be updated in the following directories,

  • lib/commonjs
  • lib/module
  • lib/typescript

Example

Sorry, the example directory is not maintained so far.

License

MIT

Acknowlegement

This project is bootstrapped with callstack/react-native-builder-bob.