2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

mqttについて / 動作を確認

Last updated at Posted at 2025-11-30

mqtt Advent Calandar 1日目

はじめに

mqttのアドベントカレンダーを書き始めようと思います。この記事では基本的な事柄を抑えてから、動作環境の説明をしたいと思います。
 mqttのアドベントカレンダーを通じて実際に手を動かして確かめていただけたら嬉しいです。

基礎となる知識

PythonやGoなど基本的なプログラムの構造がわかっていれば読めます。動作させるプログラムはできるだけ完全な状態で掲載しようと思います。

mqttプロトコルについて

mqttについて、記事はすでにたくさんありますが改めて、規格書OASIS MQTT Version 3.1.1の記事を引用し、確認します。

MQTT is a Client Server publish/subscribe messaging transport protocol. It is light weight, open, simple, and designed so as to be easy to implement. These characteristics make it ideal for use in many situations, including constrained environments such as for communication in Machine to Machine (M2M) and Internet of Things (IoT) contexts where a small code footprint is required and/or network bandwidth is at a premium.

下記は意訳です

MQTTはPub/Subメッセージトランスポートプロトコルで軽量、オープン、シンプルそして実装が簡単なように設計されています。たくさんの場合において最適ですが、M2MやIoTのような小さいコードフットプリントが求められて、ネットワーク帯域幅が限られているM2MやIoTといった環境における通信に最適です。

だそうです。「シンプルなプロトコル」かどうかは筆者的には疑問ですが、IoT界隈においては割とメジャーなプロトコルです。

実際の例

有名なのはIoTではAWS IoT Coreが対応しているということかど思います。
また、オープンであることでベンダロックインになりづらいところもIoTとしては強みになると思っています。

OSI参照モデル的に、MQTTのプロトコルの下にあるプロトコルとしては「欠損がない」、「順番が入れ替わらない」「双方向のデータが可能」なプロトコルの上ならなんでも良いですが、一般的にはTCP/IPもしくはWebsocketがデファクトスタンダードとなっています。本アドベントカレンダーを通じてはTCP/IPを前提にします。

動作させてみよう

サーバ起動

サーバとしては2つ使います。当初はmochiのみを使用していましたが、規格通りの実装がされていないところが一部あり、mosquittoも使用します。有名なのはmosquittoかと思います。

mosquitto

mosquittoは有名なmqtt brokerでmqttの規格の準拠度合いに関しては信頼感があります。

前提

  • Dockerがインストールされていること
docker-compose.yml
version: "3"
services:
  mqtt:
      image: eclipse-mosquitto
      container_name: mqtt
      expose:
        - 1883
      ports:
        - 1883:1883
      restart: unless-stopped
      volumes:
        - ./mosquitto/config:/mosquitto/config

mosquitto.conf
set_tcp_nodelay true
listener 1883
allow_anonymous true
ディレクトリ構造
[~/qiita/mosquitto]$tree
.
├── docker-compose.yml
└── mosquitto
    └── config
        └── mosquitto.conf

起動は下記のように行います

canceled
[~/qiita/mosquitto]$docker compose up
[+] Building 0.0s (0/0)                                                                                 docker:desktop-linux
[+] Running 1/0
 ✔ Container mqtt  Created                                                                                              0.0s 
Attaching to mqtt
mqtt  | 1764385187: mosquitto version 2.0.18 starting
mqtt  | 1764385187: Config loaded from /mosquitto/config/mosquitto.conf.
mqtt  | 1764385187: Opening ipv4 listen socket on port 1883.
mqtt  | 1764385187: Opening ipv6 listen socket on port 1883.

次に別のブローカーを立ち上げるためCtrl + Cで停止します

mochi-co mqtt broker

mochi-co mqtt brokerはGoで書かれたmqtt brokerです。システムに組み込みやすいインターフェイスやカスタマイズしやすいフックの仕組みを備えています。

前提

  • goがインストールされていること

mochi-mqttからソースをダウンロードしてexampleのなかから一番シンプルな設定を起動します。

[~/qiita]$git clone https://github.com/mochi-mqtt/server.git
[~/qiita]$cd server/
[~/qiita/server]$cd cmd
[~/qiita/server/cmd]$go build -o mqtt && ./mqtt
time=2025-11-11T21:42:53.199+09:00 level=INFO msg
...

このあとのクライアントの動作確認のため、端末を開きっぱなしにしておきます。

クライアント作成

Pythonの人気が高いのでPythonとクライアントとしてはメジャーなpaho-mqttで作成することにしました。

準備

前提

  • pythonが動作すること
  • 特にこだわりはありませんが筆者はuvで動作させています(なんでもよいです)
[~/qiita/1day]$uv init .
[~/qiita/1day]$uv add paho-mqtt

ソースコード(main.py)

端末をいろいろ開くのが面倒なのでマルチスレッドにします。Threadingを使ってPubとSubを非同期にします。

やっていること

  • 受信するスレッドを立ち上げて、次に1秒ごとに5回送信して終了します
  • daemon=Trueになっているのでメインの送信プログラムが終了したら受信するスレッドも自動的に終了します
import paho.mqtt.client as mqtt
import threading
import time

BROKER = "localhost"   
TOPIC = "test/topic"

# ======================
# Subscriber
# ======================
def on_message(client, userdata, msg):
    print(f"[受信] {msg.topic}: {msg.payload.decode()}")

def subscriber():
    sub = mqtt.Client(client_id="sub-client", callback_api_version=mqtt.CallbackAPIVersion.VERSION2)
    sub.on_message = on_message
    sub.connect(BROKER, 1883, 60)
    sub.subscribe(TOPIC)
    sub.loop_forever()

# =================
# Publisher
# =================
def publisher():
    pub = mqtt.Client(client_id="pub-client", callback_api_version=mqtt.CallbackAPIVersion.VERSION2)
    pub.connect(BROKER, 1883, 60)
    for i in range(5):
        msg = f"Hello {i}"
        pub.publish(TOPIC, msg)
        print(f"[送信] {msg}")
        time.sleep(1)
    pub.disconnect()

# ======================
# メイン処理
# ======================
if __name__ == "__main__":
    # 受信スレッドを起動
    t = threading.Thread(target=subscriber, daemon=True)
    t.start()

    # 少し待ってから送信
    time.sleep(1)
    publisher()

    # 終了待ち
    time.sleep(2)

実行

mochi mqttを相手にしてデータを送信し、サブスクライバーから受信されることを確認しましょう。

[~/qiita/1day]$uv run main.py 
[送信] Hello 0
[受信] test/topic: Hello 0
[送信] Hello 1
[受信] test/topic: Hello 1
[送信] Hello 2
[受信] test/topic: Hello 2
[送信] Hello 3
[受信] test/topic: Hello 3
[送信] Hello 4
[受信] test/topic: Hello 4

まとめ

mqttの概要を説明し、簡単に送受信を試してみました。
アドベントカレンダーを通じて、わからないところを調べながら実際に手を動かして試すような記事を書いていければいいなと思っています。

著作権情報

Copyright © OASIS Open 2014. All Rights Reserved.
Available at: https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html

2
0
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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?