MQTT 는 'MQ Telemetry Transport' 를 뜻하는데, 매우 간단하고 경량의 메세지 프로토콜이라
제한적인 자원 환경과 적은 bandwidth, 불안한 네트워크 환경에서 특히 적합하다.
따라서, M2M (machine to machine) 환경이나 IoT(internet of Things, 사물인터넷) 환경에서 자주 사용한다.
MQTT 는 클라이언트와 서버에서 publish/subscribe 개념을 가지는 메세지 프로로콜이다.
이 프로토콜은 TCP/IP 환경에서 작동한다.
동작 원리는
1) client 에서 MQTT server 에 connect requeset 를 보내고,
2) server 로 부터 일정 시간 안에 connect ACK 를 받으면 MQTT connection 이 완료가 되고,
3) client 는 원하는 토픽에 subscribe 를 하고,
4) 어딘가에서 (이것 또한 client 가 될 수 있다) 그 토픽에 관해 message 가 publish 하면,
5) MQTT server (broker) 가 이를 감지하고, 해당 토픽에 subscribe 하고 있는 client 들에게 메세지를 전달한다.
결국, 아래 그림 처럼, 어떤 test 라는 topic 을 subscribe 하고 있는
client 들에는 test 라는 topic 에 publish 된 메세지가 전달 되게 된다.
따라서, MQTT는 client 가 먼저 server 에 등록 요청을 하고,
등록이 되면 하나의 socket 이 생성된 것처럼 서로의 연결 통로가 생기게 되고,
이를 계속 듣고 있던 client 와 server 가 서로의 신호가 나타날때 감지를 하는 것이다.
MQTT document 를 참고하면, MQTT server (broker) 는
client 로 부터 오는 첫번째 connect packet 은 연결 요청 신호로 인지하고,
그 다음으로 두번째로 오는 오는 connect packet 은 이상 징후나 연결 끊음 요청으로 본다고 한다.
진정한 연결을 의미하는 connect packet 은 network 에서 1번만 전송되는 법칙이 있기 때문이다.
따라서, 이를 주의할 필요가 있다.
이제, python 으로 mqtt 를 간단하게 시험해보고자 한다.
일단, mqtt 를 위한 python 패키지를 설치한다.
$ pip install paho-mqtt
설치 후에, sub.py 코드를 작성한다.
import paho.mqtt.client as mqtt
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("connected OK")
else:
print("Bad connection Returned code=", rc)
def on_disconnect(client, userdata, flags, rc=0):
print(str(rc))
def on_subscribe(client, userdata, mid, granted_qos):
print("subscribed: " + str(mid) + " " + str(granted_qos))
def on_message(client, userdata, msg):
print(str(msg.payload.decode("utf-8")))
# 새로운 클라이언트 생성
client = mqtt.Client()
# 콜백 함수 설정 on_connect(브로커에 접속), on_disconnect(브로커에 접속중료), on_subscribe(topic 구독),
# on_message(발행된 메세지가 들어왔을 때)
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_subscribe = on_subscribe
client.on_message = on_message
# 로컬 아닌, 원격 mqtt broker에 연결
# address : broker.hivemq.com
# port: 1883 에 연결
client.connect('broker.hivemq.com', 1883)
# test/hello 라는 topic 구독
client.subscribe('test/hello', 1)
client.loop_forever()
다음은, 메세지를 발행하는 pub.py 를 작성한다.
import paho.mqtt.client as mqtt
import json
def on_connect(client, userdata, flags, rc):
# 연결이 성공적으로 된다면 완료 메세지 출력
if rc == 0:
print("completely connected")
else:
print("Bad connection Returned code=", rc)
# 연결이 끊기면 출력
def on_disconnect(client, userdata, flags, rc=0):
print(str(rc))
def on_publish(client, userdata, mid):
print("In on_pub callback mid= ", mid)
# 새로운 클라이언트 생성
client = mqtt.Client()
# 콜백 함수 설정 on_connect(브로커에 접속), on_disconnect(브로커에 접속중료), on_publish(메세지 발행)
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_publish = on_publish
# 로컬 아닌, 원격 mqtt broker에 연결
# address : broker.hivemq.com
# port: 1883 에 연결
client.connect('broker.hivemq.com', 1883)
client.loop_start()
# 'test/hello' 라는 topic 으로 메세지 발행
client.publish('test/hello', "Hello", 1)
client.loop_stop()
# 연결 종료
client.disconnect()
이제, sub.py 를 작동 시켜놓고 pub.py를 동작시키면, 'Hello' 라는 메세지가 sub 터미널에 출력됨을 볼 수 있다.
이 예제에서는, 원격 broker를 사용했지만, local mqtt로 동작하고 싶다면, mqtt 를 설치하여 실행시키고
'broker.hivemq.com' 을 'localhost' 라고 바꾸고 실행하면 된다.