時雨堂さんのMQTT brokerサービスsango試してみました


https://sango.shiguredo.jp/


2014/8/29から無料試用できるサービスが公開されているというので、MQTTってどんな使い勝手なのだろうと試してみました。（註：セキュリティなどの関係上、時刻やログの内容は一部改竄されています）

<a href="https://sango.shiguredo.jp/mqtt">MQTTについて（sangoのサイトより）</a>

追記：その後、2014/11頃から有料サービスも開始されたので、そちらを試した記事もあります。http://qiita.com/kgbu/items/4338c0386b65b2883e5a

## TODOs：まだやってないこと

+ Websocketでsubscribeしてチャット: subscriberをwebsocketにしてみる。

+ PahoのPythonライブラリのサンプルだとユーザー、パスワード認証の使い方がわからなかったので、調べてやってみる

## 登録 - githubアカウント使うのが吉　

現在無料使用アカウントでは以下の情報が貰えます。
ユーザー名とパスワードで認証しています。

+ MQTTでの接続先 : サービスの’ホスト名（MQTTのポート番号は一般的な奴です）
+ WebSocket接続先 : Websocketでも繋がる！（私はまだテストできてないです）
+ アクセス先トピック : ワイルドカードが使えます。なお、サポートの方から、トピックとしては先頭に'/'の付いていないものを使うことを推奨されています。9/1以前に利用を開始した方はご注意を。
+ ユーザー名: 認証のために使います
+ パスワード: 認証のために使います。鍵アイコンをクリックすると表示されます


## MQTTクライアントの準備

### mosquittoを使う

自分はRHELベースのOSのインスタンスをいくつか手持ちがあるので、mosquittoをインストールして使うのが手頃だったのでそうしました。

#### Mosquittoのinstall
いきなりsourceをmakeしようとしても巧く行きませんでした。

CentOS(RHEL)用にyum.repos.d設定があるそうなので、それを拝借。以下はCentOS6のケース。CentOS5,7でも対応できるそうです。
参照: http://mosquitto.org/download/

```
$ cd /etc/yum.repos.d
$ sudo wget http://download.opensuse.org/repositories/home:/oojah:/mqtt/CentOS_CentOS-6/home:oojah:mqtt.repo
$ sudo yum install mosquitto
``` 

# 繫いで使ってみます


## from internet(global address領域)

まぁ、特に問題なく使えるであろうと予想して、ここからテストを初めてみました。

- subscriber側の待ち受け設定

-tのオプションで、'#'のワイルドカードを指定しているので、'/'をセパレータとしてpublisher側がトピック文字列を拡張できます。
-vのオプションで、どのようなtopicで送信されたかもわかるようにします。

```
$ mosquitto_sub -h sangoサーバー名 -u ユーザー名 -t "トピック文字列/sense/#" -P パスワード -v
```

- publisher側
標準入力をパイプから取り込んで使うので```-s```のオプションを付けています。

```
$ echo "hi" | mosquitto_pub -h sangoサーバー名 -u ユーザー名 -t "トピック文字列/sense/a" -P パスワード -s
```

- subscriber側の表示
トピック文字列と、echoの出力'hi'が表示されました。タイムラグは感じられません。

```
/トピック文字列/sense/a hi
```

- publisher側でdateコマンドを使ってみた場合

```
$ date | mosquitto_pub -h sangoサーバー名 -u ユーザー名 -t "トピック文字列/sense/date" -P パスワード -s
```

- subscriber側の表示

```
トピック文字列/date 2014年  9月  1日 火曜日 11:35:24 JST
```

- publisher側でlogをtailしたらどうなるか？

-lのオプションは、標準入力を１行づつ別個のメッセージとして取り込むオプションです。-sも標準入力を使うのですが、複数行を１つのメッセージにまとめて処理します。

```
$ sudo tail -f /var/log/secure | mosquitto_pub -h sangoサーバー名 -u ユーザー名 -t "トピック文字列/sense/log" -P パスワード -l
```

- subscriber側

ログの内容が表示され、追加分もリアルタイムで見られました。(ログの内容はいろいろ改変してあります）

```
：
トピック文字列/sense/log Sep  1 11:45:21 鯖名 sshd[11643]: Accepted publickey for ユーザー名 from 106.146.106.13 port 49353 ssh2
トピック文字列/sense/log Sep  1 11:45:21 鯖名 sshd[11643]: pam_unix(sshd:session): session opened for user ユーザー名 by (uid=0)
：（以下、ログインのときに追加で表示された部分）
トピック文字列/sense/log Sep  1 11:47:42 鯖名 sshd[11762]: Accepted publickey for ユーザー名 from IPアドレス port 49359 ssh2
トピック文字列/sense/log Sep  1 11:47:42 鯖名 sshd[11762]: pam_unix(sshd:session): session opened for user ユーザー名 by (uid=0)
```

この内容をfluentdで繫ぐ、ということもできるでしょう。自分はZabbixという監視サービスも使うのですが、Zabbixでログを監視すると、イベントが集中したときに取りこぼしてしまう（複数のイベントが１通のメールで通知される）ことがあったので、これで改善できるかも、なんて思いました。というか、内容を分析した後はAWSのSNSに繫ぐのが普通かもしれません。


## from my home(NAT越え: private address領域)

subscriberがリアルタイムでメッセージを受け取るため、NATをまたいでセッションを維持しているはずなので、それを確認しました。
お家のガジェットを監視するのに、お家のなかにsubscriberを置いてインターネット上のMQTTブローカーが使えないとちょっと困るので、結構重要なポイント。

なお、自宅の回線はCATVのネットワークで、自宅のルーターにグローパルアドレスがDHCPで割当てられる形式です。subscriber, publisherともにルーターのNATの内部にあります。

+ subscriber　繋がるかどうかの確認なのでシンプルに

```
$ mosquitto_sub -h sangoサーバー名 -u ユーザー名 -t "トピック文字列/#" -P パスワード 
```


+ publisher dateと'hi'を送るだけ


```
$ date | mosquitto_pub -h sangoサーバー名 -u ユーザー名 -t "トピック文字列/a" -P パスワード -s
$ echo "hi" | mosquitto_pub -h sangoサーバー名 -u ユーザー名 -t "トピック文字列/a" -P パスワード -s
```

+ subscriber側　ちゃんとメッセージがやってきました。

```
2014年  9月  1日 月曜日 13:05:07 JST

hi
```

## multi-subscriberの構成：当然のように動きました。

現状、subscriberの接続の上限は３つまで。だから、３人までならそれぞれsubscriberを立てれば原始的なチャットができる。
これもテストしてみましたが、subscriberを１つのサーバーにまとめて立ててしまったので、いまいちテストとしては面白くないので詳細は割愛します。