前置き
※途中まで頑張りましたが、断念したため供養記事となります。m..m
背景
IoTの制御としてArduino, Raspberry Piなどを用いて各種センサー情報を収集、又はアクチュエータの制御などを想定する。
MQTTとは
- ネットワークプロトコルの一種
- HTTPと比較すると以下が特徴的
- 一対多, 多対多で情報のやりとりが可能
- リアルタイムでの通信が可能
- ヘッダー情報が少なくHTTPの10分の1と軽量 など
詳細はIBMのサイトに記載されています。
MQTT の基本知識
基本的に Subscriber(受け手), Publisher(送り手), Broker(中継点)の3者で構成します。
Brokerにはtopicと呼ばれるパスを設定し、Sub,Pub共に共通のtopicで送受信を行います。
例: Publish =(topic: hoge)=> Subscribe
topicはhoge/bar, hoge/hoge など"/"を用いて階層化することができます。
topicを分けることで任意のクライアント同士で情報のやり取りを行います。
MQTTを利用するにあたってはBrokerを構築する必要があります。
手早く無料で利用するには(制約がありますが)いくつかのサービスが利用できます。
構成図
今回は Beebotte と Heroku を組み合わせた場合を紹介します。
- Beebotte を利用するメリット
- 接続台数が無制限
- メッセージが一日あたり5万件送信できる
- メッセージを一日あたり5千件保存できる
- SSL接続が可能
- デメリット
- 中継点にアプリケーションが乗せられない
- topicの管理がやや複雑(channel / resource の形。生成、削除にAPIを叩く必要がある)
接続台数と送信可能件数が魅力的ですが、BrokerにDBを接続したり、メッセージによって特定の処理を行いたい場合は工夫が必要です。
そこでHerokuをSubscriber, PublisherとしてBeebotteに接続することで擬似的に実現します。
HerokuはPaaSなのでBrokerとして利用できますが、無料だと5台までしか接続できません。
実装
環境
- Mac
- node.js v8.12.0 (npm v6.4.1)
- git v2.14.3 (Apple Git-98)
環境構築
Brokerとトピックの開設
- Beebotte のサイトでアカウント登録
- Control Panel > Channels > Create New
- Channel Name, Description と Resource Name, Description を入力し Create channel
- 今回の例: ChannelName: TestCh, ResourceName: Hoge
- Channels > Channel Name > Channel Token を確認(チャンネル毎に別)
- Control Panel > Account Settings > Access Management > API Key, Secret Key を確認
Beebotteの場合 トピック名は "ChannelName / ResourceName" です
MQTT クライアントの実装
Beebotteからライブラリが提供されている他、MQTT.jsや他の言語のライブラリ1でも可能です。
Tutorialsから実装例が紹介されています
今回はMQTT.jsを用いた例を紹介します
プロジェクトを作成するディレクトリで
npm install mqtt --save
Subscriber
メッセージを受信する
トピックを開設した際に確認したChannel Token と トピック名を書き換えてください
const mqtt = require('mqtt')
const CHANNEL_TOKEN = '*********************'
const client = mqtt.connect('mqtt://mqtt.beebotte.com',
{username: 'token:' + CHANNEL_TOKEN, password: ''}
)
const onMessageCallback = (topic, message) => {
console.log(topic + ' ' + message)
}
client.on('message', onMessageCallback)
client.subscribe('TestCh/Hoge')
Publisher
メッセージを発信する
インターバルで定期的に送ってます。
const mqtt = require('mqtt')
const CHANNEL_TOKEN = '*********************'
const client = mqtt.connect('mqtt://mqtt.beebotte.com',
{username: 'token:' + CHANNEL_TOKEN, password: ''}
);
setInterval(function() {
const message = 'Hello, world!'
client.publish('TestCh/Hoge', message)
}, 1000);
2つのターミナルで動作確認してみます
node publisher.js
node subscriber.js
#TestCh/Hoge Hello, world!
#TestCh/Hoge Hello, world!
#...
メッセージが表示されていればうまく送信、受信できています。
Heroku 編
志半ばで筆を投げました。すみません。