Invalid protocol "MQTT" in CONNECT の対処方法

Ubuntu 14.04 の MQTTブローカー (mosquitto - MQTT version 3.1 compatible message broker) を利用すると、node.js の MQTTクライアントから匿名接続できず、"Invalid protocol "MQTT" in CONNECT" が発生して接続できないので、対処方法について確認した。


## ソフトウェアのバージョン
* Ubuntu14.04 
* npm install mqtt でインストールできるクライアント ライブラリ(https://www.npmjs.com/package/mqtt) 
* apt-get install mosquitto でインストールできる MQTTメッセージ・ブローカー

```
$ apt-cache show mosquitto
Package: mosquitto
Priority: optional
Section: universe/net
Installed-Size: 190
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Roger A. Light <roger@atchoo.org>
Architecture: amd64
Version: 0.15-2ubuntu1
```
(バージョンが 0.15である事に注意)


## 動作しないJavaScript サンプルコード
このウェブページ(https://www.npmjs.com/package/mqtt) で紹介されているコードで、自己のメッセージ・ブローカーに接続すると動作しない。

```
var mqtt    = require('mqtt');
//var client  = mqtt.connect('mqtt://test.mosquitto.org');
var client  = mqtt.connect('mqtt://localhost');

client.on('connect', function () {
  client.subscribe('presence');
  client.publish('presence', 'Hello mqtt');
});
 
client.on('message', function (topic, message) {
  // message is Buffer 
  console.log(message.toString());
  client.end();
});
```
実行すると、結果を表示する事もなく、だんまりとなる。 netstat -nat を実行すると TIME_WAITがどんどん増えていく。


## 接続エラーメッセージ
この時のエラーメッセージは以下の様に、Socket read error と良く分からない。

```
Jan  3 06:59:03 tkr02 mosquitto[351]: New connection from 127.0.0.1.
Jan  3 06:59:03 tkr02 mosquitto[351]: Socket read error on client (null), disconnecting.
```
そこで、/etc/mosquitto/mosquitto.conf の log_type を全て有効にすると、以下の様にプロトコルエラーであることが識別できる。

```
Jan  3 07:14:38 tkr02 mosquitto[383]: New connection from 127.0.0.1.
Jan  3 07:14:38 tkr02 mosquitto[383]: Invalid protocol "MQTT" in CONNECT from 127.0.0.1.
Jan  3 07:14:38 tkr02 mosquitto[383]: Socket read error on client (null), disconnecting.
```

## インターネットで検索すると
"Invalid protocol "MQTT" in CONNECT" のフレーズで、グーグル検索をするとエラーの原因らしきものがわかる。

![google_search.png](https://qiita-image-store.s3.amazonaws.com/0/42829/3aff7bf7-b38c-e59c-3e04-c87472c68a85.png)

どうも Ubuntu 14.04 の mosquitto バージョンが MQTT3.1.1に対応していない事が原因らしい。

## Ubuntu 14.04 に適用できるバイナリパッケージは無いのか？
探したんだけど、あるには在った(mosquitto 1.4.7-1)が、依存関係が多くインストールを断念した。次のURL (https://launchpad.net/ubuntu/+source/mosquitto) を参照すると、以下のパッケージを前提としている。

```
ibwebsockets6 (>= 1.6.0)
lsb-base (>= 4.1+Debian11ubuntu7) 
```
これは、Ubuntu14.04のパッケージ構成に影響が大きいと思われるので、この方向で対応するのは断念することにした。


方向を変えて、このぺージ(http://mosquitto.org/download/)のUbuntuの項にある内容に従って進める。 まずリポジトリの追加する。

```
apt-get install software-properties-common
apt-add-repository ppa:mosquitto-dev/mosquitto-ppa
apt-get update
```
パッケージがどうなったか確認してみる。そうすると、mosquittoのバージョンが変わっている。

```
# apt-cache show mosquitto
Package: mosquitto
Priority: optional
Section: net
Installed-Size: 352
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Architecture: amd64
Version: 1.4.5-0mosquitto1
Depends: libc6 (>= 2.14), libssl1.0.0 (>= 1.0.1), libuuid1 (>= 2.16), libwebsockets3 (>= 1.2), libwrap0 (>= 7.6-4~), sysv-rc (>= 2.88dsf-24) | file-rc (>= 0.8.16), adduser (>= 3.10), lsb-base (>= 4.1+Debian3), apparmor
Filename: pool/main/m/mosquitto/mosquitto_1.4.5-0mosquitto1_amd64.deb
```
インストールを実行して、サービスを立ち上げる

```
# apt-get install mosquitto
# service mosquitto start
mosquitto start/running, process 18934
```

# さぁテストだ
テストコードは、最初のコードと同じコードを利用する。

```
$ cat test1.js
var mqtt    = require('mqtt');
var client  = mqtt.connect('mqtt://127.0.0.1');

client.on('connect', function () {
  client.subscribe('sensor');
  client.publish('sensor', 'Hello mqtt');
});
 
client.on('message', function (topic, message) {
  console.log(message.toString());
  client.end();
});
```
動作結果は以下の通り成功！

```
tkr@tkr02:~/mqtt_nodejs$ node test1.js 
Hello mqtt
```

# まとめ
最初は設定が悪いのかと思って調べていたが、原因らしきものがない。そこでログのレベルを上げて、メッセージを手掛かりに、調べて行ったら解決策が見つかった。　やはり、ログ、エラーメッセージの順でPDするのが良いね。