졸업과제에서는 현재 Raspberry pi 4 를 사용하고 있다.
해당 기기와 서버간의 통신이 원할하게 가능하려면 프로토콜이 필요한데,
처음에는 REST API로 모두 해결하려 하였으나, 효율적이지 못하다고 판단.
이후 MQTT 라는 프로토콜이 있다는 조언을 듣고 조사하게 되었다.

MQTT란?

MQTT는 Message Queuing Telemetry Transport의 약자이다.
이름 그대로를 해석해보면 메세지 큐를 이용한 원격 전송이라는 의미이다.
ISO 표준으로 등록되어있는 발행-구독 기반의 메시지 프로토콜이라고 한다.

주로 M2M(Machine To Machine) 환경이나 IoT에 사용하기 위해 만들어졌으며,
IoT를 위해 낮은 전력, 낮은 대역폭에서도 사용할 수 있도록 구현되었다.
TCP/IP 위에서 동작을 함에도 굉장히 가볍다는 것은 엄청난 장점이다.

하지만 모든 것은 장점만 있을 수는 없는 법.
메시지 유형이 단순해지고 서비스 품질이 낮아지는 것은 어쩔 수 없는 부분이다.

MQTT의 특징

Publish & Subscribe

위에서 언급했듯이 기본적으로 발행(Publish)-구독(Subscribe) 을 기반으로 한다.

  • Topic : MQTT에는 메세지 채널을 사용하는데, 해당 채널을 Topic 이라고 칭한다.
    • Topic은 아래와 같이 디렉토리처럼 계층적으로 구성이 가능하다.
      MQTT drawio
  • Publish : 특정 채널(Topic)에 메세지를 보내는 행위를 의미한다.
  • Subscribe : 특정 채널(Topic)을 구독하면, 해당 채널에 발행되는 메세지를 수신할 수 있다.

위의 구성요소들은 아래와 같은 구조를 가질 수 있다.
서버가 장치를 구독하고 있으면, 중간자인 Broker를 통해 장치의 측정 값을 받을 수 있다.
wdwd drawio

혹은 아래와 같이 여러개의 장치가 한번에 서버를 구독하는 구성도 가능할 것이다.
qwd drawio

Message bus

위와 같은 발행 - 구독 형태의 메시지 전송은 버스 형태로 이루어지게 된다.
bbus drawio

먼저 MQTT Broker가 queue에 저장된 메시지를 bus에 흘려보낸다.
그럼 해당 Topic을 구독한 사용자들이 해당 메시지를 읽어가는 방식으로 동작한다.

QoS

MQTT 프로토콜에서는 3단계의 QoS(Quality of Service)가 제공된다.

  • 0 : 메시지를 단 한 번만 전달하며, 전달여부를 확인하지 않는다.
  • 1 : 메시지는 반드시 한 번 이상 전달됨을 보장한다.
    • 하지만 핸드셰이킹 과정을 추적하지 않아, 중복 전송의 위험이 있다.
  • 2 : 메시지는 단 한 번만 전달되며, 대신 핸드셰이킹 과정을 점검한다.
    • 높은 신뢰성을 가지게 되지만, 성능이 저하될 수 밖에 없다.

프로젝트 적용

오픈소스 MQTT Broker인 Mosquitto 를 Rpi에 설치해서 사용할 것이다.
또한, Spring에서도 MQTT를 공식적으로 지원하고 있다.
이로써 Server에서도 MQTT 사용이 가능함이 확인되었다.

  • 실제 서버 - python 간 통신
    MQTT 실제

위와 같이 subscriber(python), publisher(java)를 만들어 통신이 가능했다.

  • 실제 서버 - 기기 간 통신
    기기통신

서버와 통신이 가능함을 확인한 이후, 기기로 python 코드를 옮겼다.
코드가 기기에서 잘 작동함을 확인했고, 서버 - 기기 간 통신이 가능했다.
이제 실제 졸업과제 프로젝트에 적용하기만 하면 될 것 같다.

참고문헌

JOINC : MQTT
Spring : MQTT