IoT時代のプログラミング(主にMQTTについて)

  • 8
    いいね
  • 0
    コメント

IoTにおけるソフトと特徴

  • Arduino
    • イベント駆動
  • MQTT
    • 軽量プロトコル
    • publish/subscribe型のMQ

Arduinoとは

  • 無償で使えるマイコン用プログラム作成アプリ
    • マイコン毎にアドオンがある(ex, ESP8266)
  • スケッチ(=プログラム)はsetup/loopで構成
    • setup: 電源入り後一度だけ呼ばれる
    • loop: (電源切るまで)繰り返し呼ばれる
  • 提供されているスケッチ例を改造して動かす
$brew cask install arduino

MQTTとは

  • Message Queuing Telemetry Transport
  • 非常に軽量なプロトコル
    • 2000年代初めに登場し標準化
    • 基本的にTCP/IP上で動く
  • publish/subscribe型のメッセージ転送
  • IoT/モバイルに適する
    • センサーデバイス
    • Facebook Messenger

HTTPよりも

  • 軽量(最小2バイト)・優れた処理速度・省電力
    • HTTPではヘッダのオーバーヘッドが高い
    • AgostoのテストではHTTPSの10倍以上オーバーヘッドが低い
  • IoTの利用場面に適している
    • 貧弱な電波環境(通信帯域制限)
    • バイト毎に料金・バッテリーを消費する環境

HTTPヘッダとの比較

$curl --head https://www.yahoo.co.jp/
HTTP/1.1 200 OK
Date: Tue, 18 Jul 2017 18:10:57 GMT
(中略)
$curl --head https://www.yahoo.co.jp/ | wc -c
703
  • 最小まで減らすとしたらHTTP/1.1 200 OKの15byte
  • MQTTでは最小2バイト
  • 通信量が膨大になるほどこの10byteの差が意味を持つ

暗号化

  • TLSを使った暗号接続が可能
    • port: 8883
  • ただし通信毎に認証が必要なので軽量さが失われる
    • メッセージ全体のサイズが大きいならヘッダの10バイト差は誤差
    • MQTTとHTTPsどちらが適しているか要検討

HTTPとのすみ分け

protocol 適した用途
http 1対1で画像など大きなデータをやりとりしたい, secureな通信がしたい
mqtt 複数台から小さいデータを大量にもらいたい

Publish/Subscribe

pub-sub.jpg

  • メッセージの送信者(publisher)が特定の受信者(subscriber)に直接メッセージを送信しない
  • メッセージのやりとりにはBrokerと呼ばれる中継serverが必要
    • サーバーがメッセージを保管するため受信側の状態に関係なくメッセージを送れる
      • オフラインでもOK
    • publisher/subscriberがMQTT client
  • 接続時のデバイスIDが被ると古い接続が切れる

出典: Securing MQTT - BuildingIoT 2016 slides


message(= topic + data)

pub-sub-model.png

  1. subscriberはbrokerへtopicの受信を申し込む
    • 接続後一度だけで良い
  2. brokerはtopicへのpublishがあると接続中のtopicを申し込んだsubscriberへmessageを送信
    • 過去分は送れない(最後のmessageはオプションで受け取れる)
    • publisherにsubscriberのアクセス情報は通知されない

出典: Paho Python client for MQTT and G-code Visualization Talks, Chennaipy


topic

  • 一般的に/(スラッシュ)で階層化
    • ex, tokyoA/temp
  • ワイルドカード(#,+)
  • (mosquittoなどでは)ACL管理可能

QoS

  • client間のメッセージ到達保証レベル(Quality of Service)
  • 通常は0、コントロール系のメッセージは1以上、が基本
    • 1以上はbrokerでstoreが必要
  • Kafkaの例だが佐伯さんのスライドがわかりやすい
level desc example
0 At most once(メッセージ到達保証無) subscriberの受信失敗時のケアがない、など
1 At least once(届くけど重複するかも) subscriberのACK受信失敗時に再送、など
2 Exactly once(確実に重複無く届ける) transaction制御、速度低下

MQTTブローカー


mosquitto & paho-mqtt

$brew install mosquitto
# bg実行は`$brew services start mosquitto`だがfgは下記
$/usr/local/opt/mosquitto/sbin/mosquitto -c /usr/local/etc/mosquitto/mosquitto.conf

$pip install paho-mqtt
$cat pub.py
import paho.mqtt.client as mqtt
import time

client = mqtt.Client()
client.connect('localhost', 1883, keepalive=60)
client.loop_start()
while True:
  client.publish('world/darai0512', 'test')
  time.sleep(1)

$cat sub.py
import paho.mqtt.client as mqtt

def on_connect(client, userdata, flags, respons_code):
  print('connected')
  client.subscribe('world/#')

def on_message(client, userdata, msg):
  print(msg.topic + ' ' + str(msg.payload))

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect('localhost', 1883, keepalive=60)
client.loop_forever()

$python pub.py
$python sub.py
world/darai0512 test
world/darai0512 test
(中略)

参考資料