안녕하세요! 오랜만에 포스팅합니다. 그 사이에 케이웨더라는 회사에 취직하게 되었고, 집안에 우환이 있었고 서울에 집을 구한다고 바빴습니다. 여러분 꼭 한달은 고시원에 살다가 한달 동안 부동산을 다녀보면서 최적의 장소를 찾아보세요. 2 - 3일 정도만 알아보았다가 청소하고 준비한다고 정말 힘들었네요... 서울 집값 너무 비싸요
아무튼 회사에 입사하게되니 공부해야될께 우후죽순 쏟아지기 시작해, 일 마치고 나서 이렇게 포스팅할려고합니다.
MQTT(Message Queuing Telemetry Transport)는 발행-구독 기반의 메시지 프로토콜 입니다. 저희 회사에서는 IOT와 통신하기 위해서 이 MQTT를 사용합니다. 이 MQTT를 사용하는 이유는 최소한의 전력과 패킷량으로 통신할 수 있는 프로토콜이기 때문입니다.
Publisher은 Topic을 발행하고 Subscriber은 Topic에 구독합니다. Broker는 이들을 중계하는 역할을 합니다.
QoS(Quality of Service) 서비스의 질을 보장해주는 레벨을 말합니다. 서비스의 종류에 따라 QoS레벨을 선택해야합니다.
Level 0 : 메세지는 한 번만 전달되며 전달의 성공여부는 확인 하지않는 레벨입니다. (UDP 와 비슷하네요)
Level 1 : 메세지는 최소 한 번 이상 전달되며 Publishr에게 Puback을 전달하여 성공여부를 알립니다. 하지만 Publishr 가 PUBACK을 성공적으로 받지 못하면 Subscriber에게 중복메세지를 보내는 경우가 생깁니다.
Level 2 : 메세지는 반드시 한번만 전달됩니다. PUBACK 방식을 PUBREC으로 핸드셰이킹 함으로써 Broker가 PUBACK을 받지 못하더라도 Broker에게 메세지를 보냈다는 사실을 알고 있기 때문에 중복메세지를 보내지않습니다.
대표적으로 Mosquitto, HiveMQ, RabbitMQ가 있습니다.
Mosquitto의 경우 간편하지만 C기반이고 클러스터링이 되지않습니다.
RabbitMQ
MQTT는 경량의 메시징 프로토콜이라 최대한 경화한 것이 특징입니다. 그러다보니 있어야하는 기능이 없는데 부하를 분산시키기위한 Job Queue 기능이 없습니다. 이러한 용도로는 AMQP 등을 사용합니다.
MQ의 오픈소스를 기반으로 한 표준 프로토콜을 의미합니다.
RabbitMQ는 AMQP를 구현한 메세지 브로커입니다. RabbitMQ는 같은 Queue를 바라보고있는 Consumer에게 메세지를 균등 분배합니다.
npm install mqtt --save
const mqtt = requitre('mqtt');
const clinet = mqtt.connect(url, [options]);
MQTT broker와 연결해주고 client class를 반환하여줍니다.
options는 broker와 연결할 때 설정될 속성들입니다.
만약 broker에 username이나 password를 요구하는 broker가 있다면 자바스크립트 객체를 생성해서 options를 작성하고 넣어주면 됩니다.
const mqtt = require('mqtt')
const host = 'broker.emqx.io'
const port = '1883'
const clientId = `mqtt_${Math.random().toString(16).slice(3)}`
const connectUrl = `mqtt://${host}:${port}`
const client = mqtt.connect(connectUrl, {
clientId,
clean: true,
connectTimeout: 4000,
username: 'emqx',
password: 'public',
reconnectPeriod: 1000,
})
const topic = '/nodejs/mqtt'
client.on('connect', () => {
client.subscribe([topic], () => {
})
client.publish(topic, 'nodejs mqtt test', { qos: 0, retain: false }, (error) => {
if (error) {
console.error(error)
}
})
})
client.on('message', (topic, payload) => {
console.log('Received Message:', topic, payload.toString())
})
연결할 때는 connect 이벤트가 호출되어야 제어할 수 있습니다.
이 connect메소드는 client.connected 변수를 true로 설정합니다.
client.on("connect", () => {
console.log("connected"+ client.connected);
}
연결 실패시에는 error 이벤트를 호출해서 제어할 수 있습니다.
client.on("error", (error) => {
console.log(error)
})
process.exit(1);
process.exit을 하지않으면 오류만 잡고 client는 계속해서 연결을 시도할 것입니다. 그렇기 때문에 exit를 사용해서 클라이언트를 종료해야합니다.
구독했다면 메세지가 왔을 때 message 이벤트를 호출해 리스너를 만들어 처리할 수 있습니다.
client.on("message", (topic, message, packet))
연결을 종료하고싶으면 end 메소드를 사용하면 됩니다.
client.end()
client.publish(topic, message, [options], [callback])
브로커에 구독을 할려면 subscribe 메소드를 사용하면 됩니다. 토픽이 배열이나 객체도 가능합니다.
client.subscribe(topic/topic array/topic object, [options], [callback])
clean : true, 오프라인 상태에서 QoS 1 및 2 메세지를 수신하려면 false로 설정해야합니다.
reconnectPeriod : 재연결 사이 간격, 자동 재연결 비활성화할려면 0
queueQoSZero : 연결이 끊어지면 나가는 QoS제로 메세지를 대기열에 넣음
resubscribe : 연결이 끊어졌다가 다시 연결되면 구독한 토픽이 자동으로 다시 구독됩니다.
publish 옵션
qos : QoS수준, 기본값 0
retain : 유지 플래그 기본값 false
cbStorePut :
https://yonghyunlee.gitlab.io/node/node-mqtt/
https://medium.com/@jspark141515/mqtt%EB%9E%80-314472c246ee
https://www.npmjs.com/package/mqtt