195
208

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-07-18
1 / 21

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バイト)1・優れた処理速度・省電力
    • 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バイト1
  • 通信量が膨大になるほどこの10byteの差が意味を持つ

暗号化

  • TLSを使った暗号接続が可能
    • port: 8883
  • ただし通信毎に認証が必要なので軽量さは失われる2
    • メッセージ全体のサイズが大きいならヘッダの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

  • 一般的に/(スラッシュ)で階層化3
    • 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制御、速度低下

(閑話)ログの質が精度を分ける

  • 米テックジャイアントのログ収集は実は雑
    • 重複やロストは気にしない
    • ログ設計はすごい。デモグラなど混ぜて1レコードに豊富な情報量
  • 重複もロストも許さないログでディープラーニングにかけたら、モデルの精度がテックジャイアントより高かった
    • precision/recallがほぼ1
    • 1レコードは購買やPVなど基本情報のみ
    • 日本向けサービス同士の比較なので、日本語の壁など外的要因な可能性も

※社外秘のため詳細は公開しません


MQTTブローカー


MQTTクライアント


mosquitto & paho by Python

MQTT通信の実例
Macで下記セットアップ

$brew install mosquitto
# mosquitto起動のため以下のどちらかを実行
# bg
$brew services start mosquitto
# fg
$/usr/local/opt/mosquitto/sbin/mosquitto -c /usr/local/etc/mosquitto/mosquitto.conf

$pip install paho-mqtt

paho pub.py

Pythonクライアントのチュートリアルを真似つつ

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)

paho sub.py

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()

Let's try MQTT

$python pub.py &
$python sub.py
world/darai0512 test
world/darai0512 test
...

195
208
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
195
208