본문 바로가기

Computer Science/Network

[Protocol] MQTT Protocol 이란 ?, Python 으로 MQTT 실행하기

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 subscribe/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' 라고 바꾸고 실행하면 된다.

반응형