Node.js(mqtt.js)로 실시간 IoT 데이터 전송
Node.js 환경에서 mqtt.js를 사용해 센서 데이터를 브로커로 전송하고 구독하는 과정을 단계별 예제와 설정 설명으로 정리하고, 설치·인증·메시지 형식·QoS·에러 처리 예시를 포함한 실무 참고자료
목차
개요
IoT 장치에서 발생하는 센서 데이터를 실시간으로 수집하려면 가볍고 신뢰성 있는 메시지 프로토콜이 필요하다. MQTT는 그 목적에 잘 맞는 프로토콜이다. 이 글에서는 Node.js 환경에서 mqtt.js 사용법을 중심으로 연결, 퍼블리시, 구독, 보안, 에러 처리까지 실제 운영에 필요한 흐름을 설명한다. 처음 접하는 사람도 이해하기 쉽도록 단계와 예제를 함께 제시한다.
MQTT 기본 개념 요약
MQTT는 퍼블리셔(publisher)와 서브스크라이버(subscriber)를 브로커(broker)가 중계하는 구조다. 토픽(topic) 기반으로 메시지를 주고받으며, QoS(Quality of Service)를 통해 전달 보장 수준을 설정할 수 있다. IoT에서는 센서 → 게이트웨이 → 브로커 → 서버의 흐름이 일반적이다. 여기서는 Node.js를 게이트웨이나 처리 노드로 가정한다.
준비물 및 설치
준비는 간단하다. Node.js와 npm이 설치되어 있어야 한다. 프로젝트 폴더를 만들고 mqtt 패키지를 설치한다.
mkdir mqtt-example
cd mqtt-example
npm init -y
npm install mqtt
기본 연결과 퍼블리시/구독 예제
아래 예제는 로컬 브로커(예: Mosquitto)에 연결해 메시지를 보내고 받는 가장 기본적인 흐름을 보여준다. node mqtt mqtt.js 예제를 찾는 초보자에게 적합한 예시다.
공통 연결 코드
const mqtt = require('mqtt')
const client = mqtt.connect('mqtt://localhost:1883')
client.on('connect', () => {
console.log('Connected to broker')
})
client.on('error', (err) => {
console.error('Connection error:', err.message)
})
퍼블리시 예제
// 퍼블리시: 센서 데이터 전송
const topic = 'sensors/temperature'
const payload = JSON.stringify({ deviceId: 'dev01', value: 23.7, ts: Date.now() })
client.publish(topic, payload, { qos: 1 }, (err) => {
if (err) console.error('Publish error:', err)
else console.log('Message published')
})
구독 예제
// 구독: 서버나 다른 장치에서 수신
client.subscribe('sensors/#', { qos: 1 }, (err, granted) => {
if (err) console.error('Subscribe error:', err)
else console.log('Subscribed to', granted.map(g => g.topic).join(', '))
})
client.on('message', (topic, message) => {
try {
const data = JSON.parse(message.toString())
console.log('Received', topic, data)
} catch (e) {
console.warn('Invalid JSON payload')
}
})
메시지 형식과 QoS 설정
메시지 페이로드는 가급적 JSON처럼 구조화된 형식을 사용한다. 필수 필드로는 디바이스 ID, 측정값, 타임스탬프가 있다. QoS는 0, 1, 2 세 가지가 있으며 실시간성이나 신뢰성 요구에 따라 선택한다. 일반 센서 데이터는 QoS 0 또는 1이 적절하다. 반복 전송을 피하려면 페이로드에 고유한 아이디를 포함하면 도움이 된다.
인증과 TLS 기반 보안
공용 네트워크에서는 TLS와 인증이 필수다. mqtt.js는 옵션으로 키·인증서·사용자명·비밀번호를 지원한다. 아래 예제는 TLS 연결과 사용자 인증을 설정하는 방법을 보여준다.
const fs = require('fs')
const options = {
host: 'broker.example.com',
port: 8883,
protocol: 'mqtts',
username: 'user1',
password: 'securepass',
ca: fs.readFileSync('ca.crt')
}
const secureClient = mqtt.connect(options)
에러 처리와 재연결 전략
네트워크 환경은 불안정하다. 안정성을 높이려면 재연결 로직과 큐잉 전략을 구현해야 한다. mqtt.js는 자동 재연결 옵션을 제공한다. 그러나 메시지 손실을 최소화하려면 로컬 큐에 저장 후 연결 복구 시 재전송하는 로직을 추가하는 것이 바람직하다.
- 재연결 간격: 지수 백오프(exp backoff)를 적용
- 메시지 큐: 디스크 기반 큐로 영속성 확보
- 중복 처리: idempotent 설계 또는 메시지 ID 사용
// 간단한 재연결 로직 예시
client.on('close', () => console.log('Connection closed'))
client.on('reconnect', () => console.log('Attempting reconnect'))
client.on('offline', () => console.log('Client offline'))
성능과 배포 고려사항
운영 환경에서는 다음 사항을 점검한다.
- Keepalive 설정: 세션 유지와 자원 사용 균형
- 배칭 전송: 비슷한 토픽은 묶어 전송하면 오버헤드 감소
- 페이로드 크기: 불필요한 필드는 제거하여 네트워크 사용량 절감
- 모니터링: 브로커 상태와 지연(latency) 측정 도구 도입
예제 응용: 센서 게이트웨이 구조
현실적 구조를 정리하면 게이트웨이는 로컬 센서 데이터를 수집해 브로커로 전송한다. 서버는 중요한 메시지를 구독해 DB에 적재하거나 알림을 발생시킨다. 장애를 고려해 로컬 저장소와 재전송 로직을 두면 데이터 유실을 크게 줄일 수 있다. nodejs mqtt 실시간 데이터 처리에는 이런 패턴이 자주 사용된다.
마무리
여기까지 mqtt.js 사용법의 핵심 흐름을 다뤘다. 기본 연결, 퍼블리시/구독, QoS, 보안, 재연결과 성능 고려사항을 통해 실제 운영에 필요한 요소를 확인할 수 있다. 글에서 제공한 node mqtt mqtt.js 예제는 빠르게 시작하는 데 도움을 줄 것이다. 추가로 브로커 설정과 대규모 배포는 별도로 검토할 것을 권한다.