티스토리 뷰

프로그래밍 기초/통신

MQTT에 대하여.

StartCoriny 2024. 12. 28. 12:05

MQTT란 무엇인가? 이게 뭐하는것이지? 싶을수 있다.

본인도 처음 프로젝트에 배정받았을때

"Coriny님 외부에서 MQTT로 데이터 받아서 작업하시면 되요."라고 했을때 그게 뭔가 싶었다.

언젠가 한번 어렴풋이 들어본적은 있는거같은데 관심을 가지지 않아서 넘어갔던 부분이였다.

 

Message Queuing Telemetry Transport

경량 메시징 프로토콜로서, 주로 사물인터넷(IoT) 환경에서 기기 간 통신을 위해 개발된 프로토콜

 

MQTT는 쉽게 말하면 줄임말이다. 풀어서 보면

 

Queue는 자료구조를 공부한다면 쉽게 접할수있는 단어이다.

FIFO 즉, 간단하게 데이터가 순차적으로 쌓이고 먼저 쌓인 순으로 나간다. 

은행으로 비교하자면 번호표를 순서대로 뽑고 순서대로 업무를 진행하고 먼저 온 순서대로 나간다는 방식으로 

이해할 수 있다.

 

Telemetry는 원격 측정법이라고 한다.

원격에 있는 장치나 시스템의 상태 정보를 실시간으로 수집하고 전송하는 기술을 말한다.

어떤 공장 기계가 산속 공장에 설치되어 있다고 가정보자.

이 기계의 온도, 진동 수치, 동작 상태 등의 데이터가 센서를 통해 실시간으로 본사 서버나 관리자의 PC로 전송되며

관리자는 직접 공장에 가지 않고도 원격으로 기계 상태를 모니터링할 수 있다.

 

Transport는 데이터나 정보를 한지점에서 다른지점으로 전달한다.

네트워크 통신에서 주로 데이터 전송을 위한 프로토콜이나 메커니즘을 가리킨다.

가장 쉽게 이해한다면 이메일 전송으로 이해할수 있다.

문서나 텍스트를 메일에 첨부하여 상대방에게 전송할 때 네트워크를 통해서 나에게서 상대방으로 안전하게 전달되는

과정이다.

 

이 모든걸 합쳐서 보면

메시지를 큐에 저장하고 관리하며 원격 장치 간의 데이터 수집하며 데이터를 한 지점에서 다른 지점으로 효율적으로

전달하는 역할을 하는 것이다.

 

 

MQTT의 특징

발행/구독(Publisher / Subscribe) 모델

간단한 MQTT의 PUB/SUB 구조

- 클라이언트나 특정 프로세스는 작업이 완료된 후 특정 주제(토픽, Topic)에 해당하는 메시지를 발행한다.

- 발행된 메시지는 MQTT 브로커라는 중간 매개체에 전달된다.

- MQTT 브로커는 들어온 메시지의 토픽을 기준으로 해당 토픽을 구독한 모든 구독자(Subscriber)에게 메시지를 전송한다.

- 그러면 수신받은곳에서는 메세지에대한 처리를 할수가 있다.

- 발행자는 단순히 메시지를 보내기만 한다.

- 발행은 한번에 하나밖에 할수가 없다.

- 그 메시지는 여러 곳으로 동시에 전달될 수 있다.

- 하나의 메시지 토픽에 대하여 여러 구독자가 존재할 수 있다.

- 각 구독자는 해당 메시지를 받아 자신의 용도에 맞게 처리한다.

 

예시)

클라이언트 1,2,3,은 아이템을 사기위해서 쇼핑몰에 해당 아이템이 들어온다면 알림이 울리도록 했다.

클라이언트 1과 2는 신발, 클라이언트 3은 모자의 알림을 설정해놓았다.

이것을 구독의 과정이라고 볼수가 있다.

 

여기서 쇼핑몰을 브로커라고 지칭할 수 있다.

 

관리자 또는 협업자가 신발이 들어와서 쇼핑몰에 신발을 올렸다.

그러면 신발이 올라감과 동시에 쇼핑몰은 신발알림을 신청한 클라이언트 1과 2에게 알림을 보내주어야 한다.

여기에서 관리자가 쇼핑몰에 신발을 올린것이 발행의 과정이고

알람이 전송되는 과정이 MQTT의 활용이라고 하면 쉽게 이해할수 있을것이다.

 

위 예시로 MQTT의 Pub/Sub개념을 직관적으로 이해할수 있을 것이다.

 

 

경량성과 낮은 대역폭

MQTT는 HTTP 기반 요청 / 응답방식 (axios, fetch) 보다 훨씬 적은 오버헤드를 가지고 있다.

 

HTTP는 텍스트 기반 프로토콜이기 때문에 요청/응답의 헤더와 메세지 포맷이 MQTT에 비해 상대적으로 무겁다.

HTTP의 전송 과정은

| 브라우저 → 서버요청 → 서버 처리 → 응답 |  으로 진행이 된다.

이 과정 안에서도 헤더정보, 쿠키, HTTP 메소드와 같은 다양한 메타데이터를 포함하기때문에 패킷의 크기가 커지면서

네트워크 사용량이 많아질수가 있다.

 

하지만 MQTT는 이와 반대다.

MQTT는 매우 적은 오버헤드로 메시지를 주고받을 수 있다.

가장 먼저 MQTT의 메세지는 바이너리 형식으로 되어있다. 바이너리 형식이란 문자열을 특정 인코딩으로 변환한

바이트 시퀀스를 의미한다. (일반적으로는 UTF-8)

// UTF - 8
안녕 = EC 95 88 EB 85 95

물론 HTTP도 바이너리형식으로 전송이 된다.

하지만 MQTT는 추가적인 내용없이 바이너리 형식의 토픽명, 메세지, Qos수준, 유지 시간같이 최소한의 정보만

교환하기 때문에 패킷의 크기가 훨씬 단순하고 작다.

 

또한 MQTT는 지속적으로 연결되어있다.

MQTT는 클라이언트와 브로커 사이에 하나의 TCP 연결을 유지하면서, 이 연결을 통해 메시지를 주고받는다.

매번 요청-응답을 하는것은 그만큼의 오버헤드가 많아지는데

MQTT는 이미 연결이 유지된 상태에서 데이터만 전송하면 되므로 추가적인 핸드셰이크나 교환이 최소화된다.

 

 

기본적으로 모든 요소가 가능한 한 단순하고 효율적으로 되어 있어 

네트워크 자원이 제한되어 있거나 전력 소비를 줄여야 하는 임베디드 기기, 센서 네트워크, 모바일 애플리케이션 등에 적합하다.

 

메시지 품질(Qos) 보장 수준 제공

MQTT는 전송 신뢰성을 위해 QoS(Quality of Service) 레벨을 제공한다.

QoS 0, 1, 2 총 세 단계의 전송 신뢰성을 통해 상황에 맞는 메시지 전달 보장 수준을 선택할 수 있다.

예를 들어, 센서 데이터처럼 매 순간 갱신되는 정보는 QoS 0(전송 보증 없음)로도 충분할 수 있고,

결제 정보나 중요한 명령은 QoS 1 또는 QoS 2로 전송 실패 시 재시도, 중복 방지 등의 추가적 신뢰성을 보장하도록

설정할 수 있다.


MQTT 연결

const mqtt = require('mqtt')
const client = mqtt.connect('브로커 서버')

 

MQTT 메서드

// 메세지 발행
client.publish('topic', 'Hello World', () => {
  console.log('topic 메세지로 발행')
})
// 메세지 구독
client.subscribe('topic', (err) => {
  if (!err) {
    console.log('topic 구독 성공')
  }else{
  	console.log('문제 발생')
  }
})

위 메서드를 가장 많이 쓰고 unsubscribe, end, reconnect 와 같은 메서드도 존재한다.

 

MQTT 이벤트

connect: 최초 연결 성공 시

client.on('connect', function () {
  console.log('브로커 서버에 연결성공');
});

 

message: 구독한 토픽에 메시지 수신 시

client.on('message', function (topic, message) {
  console.log(`받은 토픽과 메세지 |  ${topic}: ${message.toString()}`);
});

 

reconnect: 연결 끊김 후 재연결 시도 시

client.on('reconnect', function () {
  console.log('브로커 서버에 재연결 시도');
});

 

close: 연결이 완전히 닫혔을 때

client.on('close', function () {
  console.log('클라이언트와 브로커의 연결 닫힘');
});

 

error: 오류 발생 시

client.on('error', function (error) {
  console.error('MQTT 에러:', error);
});

 

MQTT 사용해보기

publish.js

const mqtt = require('mqtt');
const brokerUrl = 'mqtt://broker.hivemq.com'; // 동일 브로커

const client = mqtt.connect(brokerUrl);

const publish = ()=>{
    setInterval(() => {
        const message = `${DATE()}`;
        client.publish('time', message);
        console.log(`Published: ${message}`);
    }, 5000);
}

publish()

/**
 * 결과
 *  Published: Thu Dec 26 2024 00:16:03 GMT+0900 (대한민국 표준시)
 *  Published: Thu Dec 26 2024 00:16:08 GMT+0900 (대한민국 표준시)
 *  Published: Thu Dec 26 2024 00:16:13 GMT+0900 (대한민국 표준시)
 *  ...
 */

 

subscribe.js

const mqtt = require('mqtt');
const brokerUrl = 'mqtt://broker.hivemq.com'; // 동일 브로커

const client = mqtt.connect(brokerUrl);

client.subscribe('time')

client.on('message', (topic, message) => {
    console.log(`topic: ${topic}`);
    console.log(`message: ${message.toString()}`)
});

/**
 * 결과
 *  topic: time
 *  message: Thu Dec 26 2024 00:16:03 GMT+0900 (대한민국 표준시)
 * 
 *  topic: time
 *  message: Thu Dec 26 2024 00:16:08 GMT+0900 (대한민국 표준시)
 * 
 *  topic: time
 *  message: Thu Dec 26 2024 00:16:13 GMT+0900 (대한민국 표준시)
 *  ...
 */

 

위처럼 mqtt가 발행 - 브로커 - 구독 식으로 진행이 된다.

구독된곳에서는 해당 토픽, 또는 메세지에 따라서 time이라는 토픽으로 오면 어떤작업을 할지, 시간에 관련된 message가

온다면 어떤작업을할지는 개발자의 목적에 따라서 작업하면된다.

 

 

참조

 

GitHub - mqttjs/MQTT.js: The MQTT client for Node.js and the browser

The MQTT client for Node.js and the browser. Contribute to mqttjs/MQTT.js development by creating an account on GitHub.

github.com

 

Eclipse Mosquitto

Eclipse Mosquitto is an open source (EPL/EDL licensed) message broker that implements the MQTT protocol versions 5.0, 3.1.1 and 3.1. Mosquitto is lightweight and is suitable for use on all devices

mosquitto.org

 

MQTT Version 5.0

docs.oasis-open.org

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
글 보관함