はじめに
zabbixのwebhookから通知されたアラートをmqttでばらまきたくて、httpでpostされたjsonデータをmqttでpublishする簡単なプログラムを書いてみました。
websocketではなくmqttにした理由
mqttをつかったことがなく、使ってみたかったから
実装
pythonで実装します。flaskとpaho-mqttが必要なのでインストールします。
$ pip install flask paho-mqtt
topic, payload, client_idがjsonでPOSTされてきたときmqttでpublishするようコーディングします。
http_publisher.py
from flask import Flask, request
import paho.mqtt.publish as publish
app = Flask(__name__)
BROKER = 'localhost'
PORT = 1883
@app.route('/', methods=["POST"])
def send():
data = request.json
if data and 'topic' in data and 'payload' in data and 'client_id' in data:
try:
publish.single(
data["topic"],
data["payload"],
hostname=BROKER,
port=PORT,
client_id=data['client_id'],
)
except Exception as e:
print(e)
raise e
return data
else:
return "Bad Request", 400
if __name__ == '__main__':
app.run()
動作確認
ここで作ったコンテナとsubscriber.pyを使って動作確認してみます。
コンテナ起動
$ docker run -it -d -p 1883:1883 -p 9001:9001 -v $PWD/mosquitto.conf:/mosquitto/config/mosquitto.conf eclipse-mosquitto
subscriber起動
$ python subscriber.py
Connected to MQTT Broker!
http_publisher起動
$ python http_publisher.py
* Serving Flask app 'http_publisher' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployme nt.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
データをPOST
$ curl -X POST -H 'Content-Type:application/json' -d '{"topic":"pyjackal/mqtt", "payload":"hello world!!", "client_id": "publisher1"}' http://127.0.0.1:5000/
{"client_id":"publisher1","payload":"hello world!!","topic":"pyjackal/mqtt"}
$
無事受け取れました
$ python subscriber.py
Connected to MQTT Broker!
Received `hello world!!` from `pyjackal/mqtt` topic
実運用するには認証とかリクエストが集中した時の挙動とか考慮しなければならないことがいろいろありますが、やりたいことはできそうです。