# NATS ゲートウェイ

EMQX Cloud は [NATS プロトコル](https://docs.nats.io/reference/reference-protocols/nats-protocol) に基づく NATS ゲートウェイをサポートしており、NATS クライアントが MQTT クライアントと接続してメッセージを交換できるようにします。

本ページでは、EMQX Cloud における NATS ゲートウェイの設定および使用方法について説明します。

## 機能概要

NATS ゲートウェイは現在、以下の機能をサポートしています。

### プロトコルサポート

- **完全な NATS プロトコルサポート**。以下のメッセージタイプを含みます：
  - 接続およびセッション管理：`INFO`、`CONNECT`
  - メッセージのパブリッシュおよびサブスクライブ：`PUB`、`HPUB`、`SUB`、`UNSUB`
  - メッセージの配信および応答：`MSG`、`HMSG`
  - ハートビートおよびステータス：`PING`、`PONG`、`+OK`、`-ERR`
- **詳細モード**：クライアントは `CONNECT verbose=true` によりアック応答を有効化できます。

### MQTT との相互運用性

- **MQTT との双方向メッセージ交換**：
  - NATS クライアントからパブリッシュされたメッセージは MQTT のパブリッシュにマッピングされます。
  - MQTT メッセージは対応するトピックをサブスクライブしている NATS クライアントに転送されます。
- **NATS のワイルドカードサブスクリプション**をサポートし、自動的に対応する MQTT トピック形式に変換されます。
- **キューグループ共有サブスクリプション**：NATS クライアントのキューグループサブスクリプションは MQTT の共有サブスクリプションに変換されます。
- **リクエスト／リプライパターン**をサポート：
  - NATS クライアントからのリクエストメッセージは MQTT のリクエストメッセージに変換されます。
  - 対象トピックにサブスクライバーが存在しない場合、ゲートウェイは即座に失敗応答を返すことが可能です。

### トランスポートおよび接続性

- **複数のリスナータイプ**：TCP、TLS、WebSocket（WS）、および TLS 上の WebSocket（WSS）をサポート。

## NATS と MQTT 間のクロスプロトコルメッセージング

NATS プロトコルはパブリッシュ・サブスクライブメッセージングパターンに完全対応しており、MQTT のパブリッシュ・サブスクライブと相互運用可能です。NATS ゲートウェイの変換ルールは以下の通りです。

- **PUB および HPUB パケット**はメッセージのパブリッシュとして扱われます。
  - トピックは PUB パケットの `subject` フィールドから取得します。例：subject `t.a` は MQTT トピック `t/a` に変換されてパブリッシュされます。
  - メッセージ本文は PUB パケットのペイロードです。
  - クライアントが CONNECT パケットで `verbose=1` を設定した場合、変換後のメッセージは QoS 1 で、それ以外は QoS 0 となります。
- **SUB パケット**はサブスクリプション要求として扱われます。
  - トピックは SUB パケットの `subject` フィールドから取得します。例：subject `t.a` は MQTT トピック `t/a` に変換されてサブスクライブされます。
  - クライアントが CONNECT パケットで `verbose=1` を設定した場合、変換後のサブスクリプションは QoS 1 で、それ以外は QoS 0 となります。
  - ワイルドカードをサポートします。例：`*.b.>` は `+/b/#` に変換されます。
  - キューグループサブスクリプションは MQTT の共有サブスクリプショングループ名に変換されます。
- **UNSUB パケット**はサブスクリプション解除要求として扱われます。トピックは UNSUB パケット内のサブスクリプション ID によって識別されます。

ゲートウェイ自体には独自のパブリッシュ・サブスクライブのアクセス制御はなく、トピックレベルの権限管理は [認可](../deployments/authz_overview.md) を通じて行う必要があります。

## 現在の制限事項

以下の制限が現在存在します。

- 同一接続内で TCP から TLS へのアップグレードはサポートされていないため、クライアントは `tls_handshake_first=false` で接続できません。
- 認証機能が設定されていない場合、CONNECT パケットを送信しない NATS クライアントはパブリッシュおよびサブスクライブが許可されますが、匿名クライアントの管理は現在サポートされていません。

## 基本設定

NATS ゲートウェイの **操作** 列にある **設定** ボタンをクリックすると、基本設定を行えます。

- **サーバー名**：ゲートウェイインスタンスの一意識別子で、参照用に使用されます。デフォルトは `emq_nats_gateway` です。

- **マウントポイント**：ゲートウェイを通じてパブリッシュおよびサブスクライブされるすべてのトピックに付加される文字列プレフィックスで、プロトコル間のメッセージルーティングの分離を提供します。例：`nats/`。このプレフィックスはゲートウェイ側で管理され、クライアントはパブリッシュやサブスクライブ時に明示的に含める必要はありません。

- **デフォルトハートビート間隔**：サーバーがクライアントのオンライン状態を検知するために積極的に送信する `PING` メッセージの間隔（秒）。デフォルトは `60` 秒です。

- **ハートビートタイムアウト閾値**：クライアントがハートビートに応答しないと判断されるまでの時間（秒）。デフォルトは `5` 秒です。

- **最大ペイロードサイズ**：単一の PUB または HPUB メッセージの最大ペイロードサイズ（バイト）。デフォルトは `1048576` バイトです。

- **アイドルタイムアウト**：接続中のクライアントが一定期間アクティビティがない場合に切断とみなす時間（秒）。デフォルトは `30` 秒です。

- **統計情報の有効化**：ゲートウェイによる統計情報の収集および報告を許可するかどうか。デフォルトで有効です。

- **クライアント情報の上書き**：CONNECT パケットから認証情報を抽出するためのクライアント接続情報の上書きポリシー：

  ::: tip

  認証機能を有効にしている場合は、`username` と `password` のマッピングフィールドを明示的に設定し、認証情報が正しく渡されるようにしてください。

  :::

  - **ユーザー名**：CONNECT パケットの `user` フィールドにマッピングされます。
  - **パスワード**：CONNECT パケットの `pass` フィールドにマッピングされます。
  - **クライアント ID**：`${generated}` を設定すると自動生成されるほか、カスタムのマッピング式も指定可能です。

設定完了後、**更新** ボタンをクリックして保存してください。

## クライアント

NATS ページの **クライアント** タブでは、デプロイメントに接続中のすべてのクライアントの基本情報を確認できます。**操作** 列では特定のクライアントをキックアウトすることも可能です。

<img src="./_assets/nats_client.png" alt="nats クライアント" style="zoom:67%;" />

## 認証管理

NATS プロトコルはユーザー名／パスワード認証やトークン認証など複数の認証方式をサポートしています。NATS ゲートウェイは以下の認証タイプをサポートします。

- [パスワード認証](../deployments/auth_overview.md#password-based-authentication-default)
- [HTTP 認証](../deployments/http_auth.md)
- [MySQL 認証](../deployments/mysql_auth.md)
- [PostgreSQL 認証](../deployments/pgsql_auth.md)
- [Redis 認証](../deployments/redis_auth.md)
- [JWT 認証](../deployments/jwt_auth.md)

MQTT プロトコルとは異なり、ゲートウェイは認証チェーンではなく単一の認証機能のみをサポートします。認証機能が設定されていない場合は、すべての NATS クライアントの接続が許可されます。

NATS ゲートウェイは CONNECT パケットからクライアント認証情報を取得します。デフォルトでは以下の通りです。

- **クライアント ID**：ランダムに生成された文字列
- **ユーザー名**：CONNECT パケットの `user` フィールドの値
- **パスワード**：CONNECT パケットの `pass` フィールドの値

ゲートウェイページの NATS ゲートウェイの **操作** 列にある **認証** ボタンをクリックすると認証管理ページが開き、認証エントリーの追加、編集、削除が可能です。

<img src="./_assets/nats_authn.png" alt="nats 認証管理" style="zoom:67%;" />
