時雨堂さんがMQTTブローカーサービスhttp://sango.shiguredo.jp をリリースして以来、ちょっと元気がでたので、素振りと称してやっつけてますw
motivated by:http://null.ly/post/56517703680/apache-apollo-node-js-mqtt
とりあえずの置き場:github: https://github.com/kgbu/nodem9ttcli
History
- Draft : 2014/9/18
- initial post on Qiita : 2014/9/21
- Websocket使う例をmowsで追加しました: 2014/10/6
準備
case Mac:
Mac OSX (10.9)の環境で、まずはnode.jsをインストール。これはhttp://nodejs.org/ でINSTALLボタンをクリックするだけ。
その後、MQTTと必要になるパッケージをnpmでインストール。
- node : v0.10.32
- npm : 1.4.28
$ npm install mqtt fs process
- mqtt : 0.3.12
- fs(filesystem) : 1.0.1
- process : 0.8.0
case CentOS (64bit):
x86, x86-64のLinuxの場合バイナリパッケージがあるので、http://nodejs.org/からダウンロードのリンクをコピーしてwgetできる。
詳しくはパッケージを解凍してできるREADME.mdを参照してください。
パッケージを解凍してできたbin/
のディレクトリにパスが切られていれば使えます。
root権限でやってみる場合。
# cd /usr/local/src
# wget http://nodejs.org/dist/v0.10.32/node-v0.10.32-linux-x64.tar.gz
# cd /usr/local && tar --strip-components 1 -xzf \
> /usr/local/src/node-v0.10.32-linux-x64.tar.gz
-v0.10.32-linux-x64.tar.gz
npmでのモジュールのインストールは各個人で。やり方はMac OSXと同じ
$ npm install mqtt fs process
サンプルうごかしてみました
小学生の日記レベルですいません。
pub.js - publisher clientサンプル
MQTT.jsのサンプルをいじりました。
※topicの部分はsango.shiguredo.jpをちょっと意識してます。MQTTの仕様としては特に制限は無いので、publishしたtopicと同じであれば任意の文字列でかまいません。
var mqtt = require('mqtt');
var fs = require('fs');
var process = require('process');
var cfg = JSON.parse(fs.readFileSync(process.env.HOME+'/.mqttcli.cfg', 'utf8'));
var host = cfg.host || 'localhost';
var port = cfg.port || 1883;
var client = mqtt.createClient(cfg.port, cfg.host, { username: cfg.username, password : cfg.password });
var topic= cfg.username+'/pubtest';
setInterval(function() {
client.publish(topic, 'aaaa');
client.publish(topic, Date.now().toString());
}, 1000);
設定ファイルはこんな感じ。githubにもsample.mqttcli.cfgとして上げておきました。
{
"host": "localhost",
"port": "1883",
"username": "kgbu",
"password": "passwordstring"
}
とりあえずmqttcliのsubscriberで見てみると、、、
$ mqttcli/mqttcli sub -t "トピック/#"
aaaa
1410979794228
aaaa
1410979795230
aaaa
1410979796231
aaaa
1410979797234
:
(以後1秒毎に繰り返す)
sub.js - subscriber clientサンプル
var mqtt = require('mqtt');
var fs = require('fs');
var process = require('process');
var cfg = JSON.parse(fs.readFileSync(process.env.HOME+'/.mqttcli.cfg', 'utf8'));
var host = cfg.host || 'localhost';
var port = cfg.port || 1883;
var client = mqtt.createClient(cfg.port, cfg.host, { username: cfg.username, password : cfg.password });
var topic= cfg.username+'/#';
client.subscribe(topic);
console.log('topic:message');
client.on('message', function(topic,message) {
console.log(topic+':'+message);
});
動かしてみます。sub.jsを起動してから、先の例と同じpub.jsを動かすと、mosquittoのclientと同様に動きます。(ちょっと表示がいじってあります)
$ node sub.js
topic:message
kgbu/pubtest:aaaa
kgbu/pubtest:1411268401976
kgbu/pubtest:aaaa
kgbu/pubtest:1411268402984
kgbu/pubtest:aaaa
kgbu/pubtest:1411268403987
:
この出力を、たとえば public_html/mqtt_text.htmlにリダイレクトすれば、、、
$ node sub.js > ~/public_html/mqtt_text.html
http://hoge.hoge/~username/mqtt_text.html の内容がどんどん変化していくのがわかります。
TODOだったことなど、、、
websocket経由ではどうか?結局MOWSのサンプル動かしました
sangoはWebsocketでも繋がるので、試したくなるのは人情です。
いろいろ自分でやってみようとしたのですが、結局は[mows]のサンプルをどうぞ、ということになりました。
元のサンプルはここ参照: https://github.com/mcollina/mows#on-node
(自分のサンプルではURLとport番号がカブっているのが気に入らないのですが...)
var ops = {username: 認証用ユーザー名,
password: 認証用パスワード};
var mows = require('mows')
, client = mows.createClient(ポート番号,'ws://MQTTサーバー:ポート番号/mqtt',ops);
client.subscribe ('トピックのベース/#');
client.publish('トピックのベース/mowstest', 'Hello mqtt');
client.on('message', function (topic, message) {
console.log(topic, message);
client.end();
});
実行結果
$ node mowspub.js
kgbu@github/mowstest Hello mqtt
MQTT.jsとmowsの関係を理解したい
そもそもmowsはMQTT.jsをwebsocketで繫ぐ、ということで、自分も同じことをしようとして、MQTT.jsがstream使っているところへWSのwebsocket出力をどう繫ごうかと考えていました。
実際にwebsocketへのupgradeまではできましたが、binaryのデータとしてMQTTのパケットを構築する部分は是非MQTT.jsのコードを利用したいと思ってコード読んでいましたが、疲れたので(w、MOWSにおすがりしましたw
mowsではそこをwebsocket-streamを使っていました。
その実体は https://github.com/maxogden/websocket-stream/blob/master/index.js にあり、勉強になりました。
参考文献 肩に乗せてもらった巨人達
http://wiki.eclipse.org/Paho/Paho_Websockets - PahoのMQTT Websocket clientドキュメント
http://tools.ietf.org/html/rfc6455 - websocket RFC
http://yosuke-furukawa.hatenablog.com/entry/2014/05/30/093103 - Socket.IO 1.0の紹介 (翻訳)
http://blog.wnotes.net/blog/article/nodejs-socketio-summary (socket.ioの使い方)
http://d.hatena.ne.jp/yudetamago_orz/20120109/1326037157 (net.connectの使い方)