# JavaScriptでMQTT.js SDKを使ってデプロイメントに接続する方法

本記事では、JavaScriptの`MQTT.js`を使用して、クライアントとMQTTブローカー間の接続、サブスクライブ、メッセージ送受信、サブスクライブ解除などの機能を実装する方法を紹介します。

## 前提条件

### MQTTブローカーのデプロイ

- EMQXが提供する[無料のパブリックMQTTブローカー](https://www.emqx.com/en/mqtt/public-mqtt5-broker)を利用できます。このサービスは[EMQXプラットフォーム](https://www.emqx.com/en)を基に構築されています。ブローカーへのアクセス情報は以下の通りです。

  - アドレス：**broker.emqx.io**
  - WebSocketポート：**8083**
  - TLS/SSL対応WebSocketポート：**8084**

- また、[独自のMQTTブローカーを作成することも可能です](../create/overview.md)。デプロイメントが稼働状態になったら、デプロイメント概要ページで接続情報を確認できます。後のクライアント接続段階で必要となるユーザー名とパスワードは、[認証](../deployments/auth_overview.md)を参照し、**アクセス制御** -> **認証**で設定してください。

## 依存関係のインストール

[MQTT.js](https://github.com/mqttjs/MQTT.js)はJavaScriptで書かれたMQTTプロトコルの完全オープンソースクライアントライブラリで、Node.jsやブラウザで利用可能です。`MQTT.js`の詳細や使い方は[MQTT.js GitHub](https://github.com/mqttjs/MQTT.js#table-of-contents)を参照してください。

MQTT.jsはNPMやYarnでインストールできるほか、CDNや相対パスからインポートも可能です。本例ではCDN経由でMQTT.jsをインポートします。

- NPMまたはYarnを使う場合：

  MQTT.jsをインストールします。

  ```shell
  # NPM
  npm install mqtt
  # または Yarn
  yarn add mqtt
  ```

  インストール後、MQTT.jsをインポートする必要があります。

  ```js
  import * as mqtt from 'mqtt/dist/mqtt.min'
  ```

- CDNからMQTT.jsを利用する場合：

  ```html
  <script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
  ```

- プロジェクトにダウンロードして配置し、相対パスでインポートする場合：

  ```html
  <script src="/your/path/to/mqtt.min.js"></script>
  ```

## WebSocketポートで接続する

MQTT-WebSocketは接続パスに`/path`を指定する必要があり、EMQXブローカーは`/mqtt`を使用しています。

クライアントID、ユーザー名、パスワードは以下のように設定できます。クライアントIDは一意である必要があります。

```js
const clientId = 'emqx_test_' + Math.random().toString(16).substring(2, 8)
const username = 'emqx_test'
const password = 'emqx_test'
```

以下のコードでクライアントとMQTTブローカー間の接続を確立できます。

```js
const client = mqtt.connect('ws://broker.emqx.io:8083/mqtt', {
  clientId,
  username,
  password,
  // ...その他のオプション
})
```

## WebSocketセキュアポートで接続する

TLS/SSL暗号化が有効な場合、接続の[パラメーターオプション](https://github.com/mqttjs/MQTT.js#mqttclientstreambuilder-options)はWebSocketポート接続時と同じですが、プロトコルを`wss`に変更し、ポート番号を正しく指定する必要があります。

以下のコードでクライアントとMQTTブローカー間の接続を確立できます。

```js
const client = mqtt.connect('wss://broker.emqx.io:8084/mqtt', {
  clientId,
  username,
  password,
  // ...その他のオプション
})
```

## サブスクライブとパブリッシュ

### トピックのサブスクライブ

サブスクライブするトピックと対応する[QoSレベル](https://www.emqx.com/en/blog/introduction-to-mqtt-qos)を指定します。

```js
const topic = '/WebSocket/mqtt'
const qos = 0

client.subscribe(topic, { qos }, (error) => {
  if (error) {
    console.log('subscribe error:', error)
    return
  }
  console.log(`トピック '${topic}' をサブスクライブしました`)
})
```

### トピックのサブスクライブ解除

以下のコードでトピックと対応するQoSレベルを指定してサブスクライブ解除できます。

```js
const topic = '/WebSocket/mqtt'
const qos = 0
client.unsubscribe(topic, { qos }, (error) => {
  if (error) {
    console.log('unsubscribe error:', error)
    return
  }
  console.log(`トピック '${topic}' のサブスクライブを解除しました`)
})
```

### メッセージのパブリッシュ

メッセージをパブリッシュする際は、MQTTブローカーに対象のトピックとメッセージ内容を指定する必要があります。

```js
// パブリッシュするトピック、メッセージ、QoSを設定
const topic = '/WebSocket/mqtt'
const payload = 'WebSocket mqtt test'
const qos = 0

client.publish(topic, payload, { qos }, (error) => {
  if (error) {
    console.error(error)
  }
})
```

### メッセージの受信

以下のコードはメッセージイベントを監視し、メッセージ受信時に受信したメッセージとトピックをコンソールに出力します。

```js
client.on('message', (topic, payload) => {
  console.log(
    '受信メッセージ: ' + payload.toString() + '\nトピック: ' + topic
  )
})
```

### MQTTブローカーからの切断

クライアントをブローカーから切断するには、以下のコードを使用します。

```js
if (client.connected) {
  try {
    client.end(false, () => {
      console.log('正常に切断されました')
    })
  } catch (error) {
    console.log('切断エラー:', error)
  }
}
```

上記は主要なコードスニペットのみを示しています。完全なプロジェクトコードは[MQTT-Client-WebSocket](https://github.com/emqx/MQTT-Client-Examples/tree/master/mqtt-client-WebSocket)を参照してください。ダウンロードして実際に試すことができます。

## 接続テスト

デモ結果を確認するには、HTMLファイルをブラウザで開き、コンソールを以下のように確認してください。

![js_connection.png](./_assets/js_connection.png)

クライアントが正常に[MQTTブローカー](https://www.emqx.io)に接続し、トピックをサブスクライブし、メッセージの受信とパブリッシュが成功していることがわかります。ここで、別のクライアントとして[MQTT 5.0クライアントツール - MQTTX](https://mqttx.app)を使い、メッセージの送受信テストを行います。

![mqttx_pub.png](./_assets/js_mqttx_pub.png)

MQTTXから送信されたメッセージがコンソールに表示されていることが確認できます。

![js_receive.png](./_assets/js_receive.png)

## FAQ

1. 自己署名証明書の使い方は？双方向TLS/SSL認証はどうやって使うの？

   ブラウザの制限により、現時点ではサポートされていません。詳細はMQTT.jsのIssueをご参照ください：[ブラウザでTLS/SSL双方向認証接続を使うには？](https://github.com/mqttjs/MQTT.js/issues/1515) および [Node.jsでは双方向認証可能だがブラウザでは非対応](https://github.com/mqttjs/mqtt.js/issues/741)。

## まとめ

以上で、JavaScriptでMQTT接続を作成し、クライアントとMQTTサーバー間でのサブスクライブ、メッセージパブリッシュ、サブスクライブ解除、切断のシナリオをシミュレートしました。完全なサンプルコードは[MQTT-Client-WebSocketページ](https://github.com/emqx/MQTT-Client-Examples/tree/master/mqtt-client-WebSocket)からダウンロード可能です。また、[MQTTクライアントの例ページ](https://github.com/emqx/MQTT-Client-Examples)では他の言語のデモ例も多数公開していますので、ぜひご覧ください。
