MQTT : Message Queuing Telemetry Transport

1. MQTT?

  • Overview
    • 제한된 컴퓨팅 환경과 신뢰하지 못하는 네트워크(ZigBee) 환경에서 효율적으로 device간의 통신을 위해 디자인됨.
    • IBM에 의해 개발되고 OASIS에 의해서 IoT 표준 프로토콜이 됨.
    • 비슷한 Protocol로 XMPP 인데 XMP는 XML 기반이어서 성능이 현저히 떨어지는 IoT device에서 사용하기 어렵다.
    • MQTT는 최소 2byte으로 전송가능한 lightweight 프로토콜이어서 IoT 통신 프로토콜로 제격임.
    • => Remaining Length 필드만 보아도 얼마나 프로토콜에 사용되는 byte 하나라도 줄이려는 노력이 보임. Remaining Length의 MSB bit값으로 payload length 필드값이 1 ~ 4 byte까지 확장 가능함.
  • 특징
    • 신뢰하지 못하는 Network환경을 위해서 QoS(0 ~ 2) 지원함.
    • Device 간의 통신을 중계하는 Broker라는 Server가 존재하는데 이 서버에 Subscribe/Publish하는 방식으로 메시지가 Broker를 통하여 전달됨.
    • 초보적인 authentication을 제공하지만  보안을 위해서 SSL을 사용해야 함.

2. 맛보기
  • 동작환경: Ubuntu 16.04 
  • mosquitto broker 설치
    • sudo apt install mosquitto
    • sudo service mosquitto start 
  • mosquitto client(publisher/subscriber) 설치
    • sudo apt install mosquitto-clients
    • subscriber 실행
      • mosquitto_sub -d -t topic/child1  (localhost의 mosquitto broker에 접속)
      • mosquitto_sub -d -t topic/child1 -h iot.eclipse.org (이클립스에서 운영하는 테스트 broker에 접속)
    • publisher 실행
      • mosquitto_pub -d -t topic/child1 -m "Hello~MQTT!!"

3. 프로토콜 분석
  • Fixed Header + Variable Header(optional) + Payload(optional)

  • Fixed Header
    • 위와처럼 최소 2byte로 되어 있고 Remaining Length의 MSB bit에 따라서 확장될 수 있다.
    • Message type에 따라서 Fixed Header 뒤에 Variable Header 와 Playload가 추가될 수 있다.

  • Message Type
  • DUP flag
    • client 또는 server가 PUBLISH, PUBREL, SUBSCRIBE, UNSUBSCRIBE를 재전송할 때 1로 셋되고 그 외에는 0 임.
    • QoS 1 or 2 일때 사용할 수 있음.
  • QoS Level
    • UDP나 ZigBee처럼 신뢰되지 않는 network환경에서 유용한 기능임.
    • TCP 환경에서는 QoS 0 또는 1을 사용하는 것임 좋음.
    • QoS 0: 재전송하지 않는 UDP 통신과 비슷함.  패킷이 전달 안될 수 있다.
    • QoS 1: 재전송되는 UDP 통신과 비슷하다. 상대의 패킷 수신 ACK 메시지가 없을 경우 재전송되어 중복 전달될 수 있다.
      • PUBLISH, PUBACK 명령이 사용됨.
    • QoS 2: TCP 통신과 비슷하다. 
      • PUBLISH, PUBREC, PUBREL, REPCOMP 명령이 사용됨.
  • RETAIN
    • PUBLISH을 전송할때만 이 flag가 set 될 수 있음.
    • 이 flag가 set되어 PUBLISH되면 전송된 메시지가 Broker에서 항구적으로 저장된다.
    • 동일한 topic으로 subscribe하는 client에게 retain true로 전송된 메시지가 전달된다.
    • broker를 restart하거나 retain 이 true을 사용하여 zero-length 메시지를 publish할 때  broker에 저장된 retain 메시지는 삭제된다.
  • Remaining Length
    • 즉 MSB=0이면 Payload의 최대는 길이는 127까지 사용할 수 있음.
    • 1byte ~ 최대 4 byte까지 Length 필드 확장 가능함.
    • Remaining Length Encoding 규칙:
      • http://indigoo.com/petersblog/?p=263 
대표로 CONNECT, PUBLISH 명령에 대해서 패킷 구조를 살펴보겠습니다.
나머지 명령은 아래 사이트 참고하세요.
  • http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html 

  • CONNECT
    • Fixed Header
      • CONNECT 명령에서 DUP, QoS, RETAIN 필드는 사용되지 않음.
    • Variable Header
      • 서로 다른 Open Source를 사용하는 경우, Protocol Name과 Version 정보가 일치하는 확인이 필요함.
      • User name flag
        • mosquito broker가 사용하는 설정파일 mosquitto.conf에서 아래처럼 anonymous를 허용하지 않는 경우 이 flag가 set 되고 Payload에 User name(UTF-8)이 추가된다.
          • allow_anonymous false
          • password_file  <account_file> 
            • mosquitto_passwd 로 생성함.
      • Password flag
        • anonymous를 허용하지 않는 경우 이 flag가 set 되고 Payload에 Password(UTF-8)이 추가된다.
      • Will RETAIN
        • Will Message가 전달될 때 사용되는 RETAIN flag값
      • Will QoS
        • Will Message가 전달될 때 사용되는 QoS
      • Will flag
        • Will flag가 true로 CONNECT한 client에 대해서 Broker가 에러상황이 감지되었을때 동일한 topic을 사용한 subscriber에게 Will Message를 전달하기 위해서 사용됨.
        • 이 flag가 Set되면 Payload에 Will Message(UTF-8)이 추가된다.
      • Clean Session
        • Broker가 관리하는 Session State를 핸들링하기 위해서 사용됨.
        • 이 flag가 set되면 Broker는 이전에 연결한 Session정보를 삭제해야 한다.
      • Payload
        • ClientID
          • Broker가 client를 관리하기 위한 ID로 사용된다.
          • 이 값은 동일 네트워크 상에서 유일하게 관리되어야 한다.
        • Connection Flag Set된 순서대로 UTF-8 String이 연속 추가된다.
    • PUBLISH
      • Fixed Header
      • Variable Header
        • Topic Name
          • UTF-8 String
          • PUBLISH 명령에서는 Topic Wildcard(#, +) 문자를 포함하면 안된다.
          • 동일한 Topic으로 Subscription한 client에게만 publish message가 전달된다.
        • Message Identifier
          • QoS 1 또는 2 일때만 존재하는 필드이다.
          • Broker에서 Publish message를 저장할때 사용되는 ID 값으로 사용된다.
      • Payload
        • PUBLISH Message가 추가된다.
      • 응답메시지
        • QoS 0일때: 응답은 없다.
        • QoS 1일때: PUBACK
        • QoS 2일때: PUBREC  (PUBlish RECeive)


    • Use Case1 : QoS=0 

    • Use Case2 : QoS=1

    • Use Case3 : QoS=2

    • Use Case4 : Retain=true



    4. Client 개발
    • mosquitto-dev 설치
      • C Library: sudo apt install mosquitto-dev
      • C++ Library: sudo apt install mosquittopp-dev
    • mosquitto 소스 다운로드
      • https://mosquitto.org/download/
    • client 개발시 사용되는 library 파일
      • mosquitto.h
      • libmosquitto.so
    <TBD>

    5. 참고 사이트
    • https://www.joinc.co.kr/w/man/12/MQTT/Tutorial
    • https://mosquitto.org/
    • [broker lists] https://github.com/mqtt/mqtt.github.io/wiki/servers
    • [spec] http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html
    • [spec] http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html

    댓글