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

本記事では、Node.js プロジェクトで [MQTT](https://www.emqx.com/en/mqtt) を利用し、クライアントと MQTT ブローカー間の接続、サブスクライブ、サブスクライブ解除、メッセージの送受信を実現する方法を紹介します。

## 事前準備

本プロジェクトは Node.js v16.19.1 を使用して開発およびテストを行っています。Node.js のバージョンは以下のコマンドで確認可能です。

```shell
node --version

v16.19.1
```

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

- EMQX が提供する [無料のパブリック MQTT ブローカー](https://www.emqx.com/en/mqtt/public-mqtt5-broker) を利用できます。このサービスは [EMQX プラットフォーム](https://www.emqx.com/en) をベースに構築されています。ブローカーのアクセス情報は以下の通りです：
  - アドレス：**broker.emqx.io**
  - TCP ポート：**1883**
  - SSL/TLS ポート：**8883**
  - WebSocket ポート：**8083**
  - WebSocket over TLS/SSL ポート：**8084**
- また、[独自の MQTT ブローカーを作成](../create/overview.md)することも可能です。デプロイメントが稼働状態になったら、デプロイメント概要ページで接続情報を確認できます。後のクライアント接続段階で必要となるユーザー名とパスワードは、**アクセス制御** -> **[認証](../deployments/default_auth.md)** から設定可能です。

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

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

MQTT.js は NPM または Yarn でインストール可能で、CDN や相対パスからのインポートも可能です。本例では Yarn コマンドでインストールします。

- NPM または Yarn を使用：

  MQTT.js をインストール

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

## TCP ポートで接続する

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

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

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

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

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

TLS/SSL 暗号化が有効な場合、接続の[パラメーターオプション](https://github.com/mqttjs/MQTT.js#mqttclientstreambuilder-options)は TCP ポート接続時と同様です。プロトコルを `mqtts` に変更し、正しいポート番号を指定する点に注意してください。

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

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

## WebSocket ポートで接続する

MQTT の WebSocket 接続では、接続パスとして `/path` を指定する必要があり、EMQX ブローカーでは `/mqtt` がパスとして使われます。

そのため、WebSocket 接続時はポート番号を変更し、プロトコルを `ws` に切り替えるだけでなく、`/mqtt` パスを追加する必要があります。

以下のコードでクライアントと 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/zh/blog/introduction-to-mqtt-qos)を指定します。

```javascript
const topic = '/nodejs/mqtt'
const qos = 0

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

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

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

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

### メッセージをパブリッシュする

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

```javascript
const topic = '/nodejs/mqtt'
const payload = 'nodejs mqtt test'
const qos = 0

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

### メッセージを受信する

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

```javascript
client.on('message', (topic, payload) => {
  console.log('受信したメッセージ:', topic, payload.toString())
})
```

### MQTT ブローカーから切断する

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

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

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

## 接続のテスト

package.json ファイルの scripts フィールドに起動スクリプトを追加します。

```json
"scripts": {
  "start": "node index.js"
}
```

これで `npm start` コマンドで簡単にプロジェクトを実行できます。

```shell
npm start
```

実行後、コンソールに以下のような出力が表示されます。

![NodeJS MQTT Start](https://assets.emqx.com/images/9897e6cd56163dfe7139cf6d84361e63.png)

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

![MQTT 5.0 Client Tool - MQTTX](https://assets.emqx.com/images/5c841598f78eed0b186572165832f861.png)

MQTTX から送信されたメッセージがコンソールに表示されているのがわかります。

![MQTT messages](https://assets.emqx.com/images/02d8a35312ca1309f18a628dacca8910.png)

## まとめ

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