何回かMeshbluのコンテナを再作成して作業しているとMQTT-HTTP Bridgeが突然動かなくなりました。はじめはNode.jsのコードのデバッグに適当なところでconsole.logしていたのですが、Meshbluではdebugパッケージを使っているのでこれを活用してみます。結局MQTT-HTTP Bridgeが動かなくなったのはRedisと連携する設定が抜けていたためでした。
debugパッケージ
Meshbluの一部のコードではdebugパッケージをrequireしています。名前を引数にしてdebug関数を作成します。
worker.jsvar debug = require('debug')('worker');
setInterval(function(){ debug('doing some work'); }, 1000);
|
デバッグを有効にする場合はDEBUG環境変数にdebug関数で引数にした名前を設定します。
DEBUG=worker node example/app
|
複数設定する場合はカンマ区切りします。
DEBUG=worker,http node example/app
|
使い方
Mesubluの場合debug関数は以下のように作成しています。
~/docker_apps/meshblu/lib/sendMessage.jsvar debug = require('debug')('meshblu:sendMessage');
|
Node.jsのプログラムはSupervisorから実行しているのでsupervisor.conf
に環境変数を追加します。
~/docker_apps/meshblu/docker/supervisor.conf[program:node] environment=DEBUG="meshblu:sendMessage" command=/usr/bin/node /var/www/server.js --http --coap --mqtt
|
デバッグしたいところにdebug関数を使います。
~/docker_apps/meshblu/lib/sendMessage.js debug('Sending message', emitMsg); debug('protocol',check.protocol); if(check.protocol === 'mqtt'){ mqttEmitter(check.uuid, wrapMqttMessage(topic, emitMsg), {qos: data.qos || DEFAULT_QO\ S}); } else{ socketEmitter(check.uuid, topic, emitMsg); }
|
docker logs
にデバッグが表示されるようになります。
$ docker logs -f meshblu Wed, 25 Mar 2015 14:30:53 GMT meshblu:sendMessage Sending message { devices: [ 'my-iot' ], payload: { yello: 'on' }, fromUuid: 'temp-sens' } Wed, 25 Mar 2015 14:30:53 GMT meshblu:sendMessage protocol undefined
|
Redisの有効化
デバッグしていくとmqttServer.js
のsocketEmitter関数でemitがされていないようです。この関数はprotocolがhttpに設定されているデバイスに対してMQTTからHTTPにブリッジするときに実行されます。ブリッジされなかったのはRedisの設定がconfig.js
から読み取れないためdした。
~/docker_apps/meshblu/lib/mqttServer.js if(config.redis && config.redis.host){ var redis = require('./redis'); io = require('socket.io-emitter')(redis.client); } ... function socketEmitter(uuid, topic, data){ if(io){ io.in(uuid).emit(topic, data); } }
|
redisの設定値は環境変数から読み込んでいます。
~/docker_apps/meshblu/config.jsredis: { host: process.env.REDIS_HOST, port: parseInt(process.env.REDIS_PORT), password: process.env.REDIS_PASSWORD },
|
docker run
の環境変数にRedisの設定を追加して起動します。
docker run -d --name meshblu \ -p 3000:3000 \ -p 4443:4443 \ -p 5683:5683 \ -p 1883:1883 \ -e PORT=3000 \ -e MQTT_PORT=1883 \ -e MQTT_PASSWORD=skynetpass \ -e MONGODB_URI=mongodb://localhost:27017/skynet \ -e REDIS_HOST=localhost \ -e REDIS_PASSWORD=localhost \ -e SSL_PORT=4443 \ -e SSL_CERT=/opt/meshblu/certs/server.crt \ -e SSL_KEY=/opt/meshblu/certs/server.key \ -v $PWD:/var/www \ -v $PWD/docker:/etc/supervisor/conf.d \ -v $HOME/docker_apps/certs/meshblu:/opt/meshblu/certs \ meshblu
|
pub/sub
最初にpublishとsubscribeのデバイスのUUID/TOKENを~/.bashrc
へ環境変数に設定します。
~/.bashrcexport TEMP_SENS_UUID=temp-sens export TEMP_SENS_TOKEN=123 export MY_IOT_UUID=my-iot export MY_IOT_TOKEN=456
|
最初にcurlでsubscribeします。
$ curl -X GET \ "http://localhost:3000/subscribe" \ --insecure \ --header "meshblu_auth_uuid: $MY_IOT_UUID" \ --header "meshblu_auth_token: $MY_IOT_TOKEN"
|
次に新しいシェルを開きMosquittoからpublishします。
$ mosquitto_pub \ -h localhost \ -p 1883 \ -t message \ -m '{"devices": ["'"$MY_IOT_UUID"'"], "payload": {"yello":"on"}}' \ -u $TEMP_SENS_UUID \ -P $TEMP_SENS_TOKEN \ -d Client mosqpub/39356-minion1.c sending CONNECT Client mosqpub/39356-minion1.c received CONNACK Client mosqpub/39356-minion1.c sending PUBLISH (d0, q0, r0, m1, 'message', ... (50 bytes)) Client mosqpub/39356-minion1.c sending DISCONNECT
|
curlでsubscribeしているシェルにメッセージが標準出力されました。
{"devices":["my-iot"],"payload":{"yello":"on"},"fromUuid":"temp-sens"},
|