회사에서 MQTT Broker를 이용한 통신방법을 사용하기 위한 공부
2016년 국제 표준화 된 (ISO 표준 ISO/IEC PRF 20922)
발행-구독(Publish-Subscribe) 기반의 메시지 송수신 프로토콜이다.
작은 코드 공간이 필요하거나 네트워크 대역폭이 제한되는 원격 통신을 위해
즉 IoT와 같은 제한된, 혹은 대규모 트래픽 전송을 위해 만들어진 프로토콜이다.
그렇기에 TCP/IP 프로토콜 위에서 동작하지만 동시에 굉장히 가벼우며,
많은 통신 제약들을 해결해준다.
그러나 이 말은 동시에
MQTT는 Bluetooth나 Zigbee처럼 별도의 모듈로 별도의 대역폭을 갖는 통신 규약이 아닌,
인터넷을 사용한 WiFi나 기타 방법을 통해서
<TCP/IP>기반의 메시지 송수신을 한다는 것을 의미하기도 한다.
MQTT 브로커를 사용하는 사람은 topic을 통해 publish(게시)해서 데이터를 보내고
topic을 subscribe(구독)하고 있던 구독자는 topic에 전송된 데이터를 받아들입니다.
두대의 컴퓨터를 이용하여 MQTT Broker서버를 구축하여봅시다.
컴퓨터 A / B 두 대를 통해 MQTT통신을 해볼 것입니다.
컴퓨터 A = 데스크탑
컴퓨터 B = 노트북
=> 이경우 데스크탑/노트북 여부는 상관없다. => 그냥 컴퓨터 두대입니다.
A의 컴퓨터에서 발신 / 수신을 모두 할 예정
=> 8082포트 서버(발신) / 8083포트 서버(수신)
B는 MQTT 브로커로 사용할 예정
사용할 프레임워크는 express.js입니다.
먼저 MQTT Broker로 사용할 컴퓨터(B)에 mosquitto를 설치하여봅시다.
https://mosquitto.org/download/


설치 파일의 기본 경로로 mosquitto를 설치합니다.
설치가 끝났다면 CMD를 실행한뒤
설치된 경로인 Program Files - mosquitto로 이동하여 명령어를 실행하여 봅시다.
mosquitto -v

이러한 실행 결과를 확인할 수 있습니다.
이제 위의 명령프롬프트 창을 종료하지 않은 상태에서 명령프롬프트를 두개 더 실행하고, 같은 경로로 이동하여
토픽을 구독하고, 토픽을 발행하여 발행한 토픽의 값을 읽을 수 잇는지 확인하여 보겠습니다.
mosquitto_sub -h localhost -t /testTopic

이 상태는 이제 'testTopic' 토픽을 구독한 상태입니다.
이제 나머지 하나의 명령프롬프트로 토픽을 발행해 봅시다.
mosquitto_pub -h localhost -t /testTopic -m "Test Message"

이제 발행한 토픽을 확인할 수 있습니다.

토픽을 구독한 명령프롬프트에서 'testTopic'으로 발행한 토픽의 값이 전달되는 것을 볼 수 있습니다.
이렇게 MQTT Broker가 실행되는것을 확인하였으니, 이제 다른 컴퓨터에서 데이터를 전달하여봅시다.
// publish(게시자)
var express = require('express');
var mqtt = require('mqtt');
var app = express();
var client = mqtt.connect('mqtt://192.168.0.3:1883');
client.on('connect', function () {
console.log('Connected to MQTT broker');
});
client.on('error', function (err) {
console.log('MQTT Error: ', err);
});
app.get('/send', function (req, res) {
client.publish('my_topic', 'Hello MQTT');
res.send('Message sent to MQTT broker');
console.log('발신확인용 콘솔메세지');
});
app.listen(8082, function () {
console.log('포트 8083 서버실행 완료');
});
해당 발행자의 ip에서 /send로 접속한다면
mqtt://192.168.0.3:1883브로커에 'my_topic' 토픽으로 'Hello MQTT'라는 값을 보내는 코드입니다.
따라서 주소창에 localhost:8082/send로 접속한다면 MQTT Broker로 값을 보냅니다.
var express = require('express');
var mqtt = require('mqtt');
var app = express();
var client = mqtt.connect('mqtt://192.168.0.3:1883');
client.on('connect', function () {
client.subscribe('my_topic', function (err) {
if (!err) {
console.log('Connected to MQTT broker');
}
});
});
client.on('message', function (topic, message) {
// message is Buffer
console.log(message.toString());
});
app.listen(8083, function () {
console.log('포트 8083 서버실행 완료');
});
브로커의 my_topic을 구독하여 my_topic에 특정값이 publish됬을 때 그 값을 읽어오는 코드입니다.
이제 두 서버를 실행시켜볼까요?

분명히 서버는 실행되었지만
client.on('connect', function () {});
해당 function에 의해 MQTT 브로커와 연결되었다면 발행자와 구독자 모두
Connected to MQTT broker
이런 메세지가 출력되야하는데 서버만 실행되고 아무런 메세지가 출력되지 않는걸 볼 수있습니다.
이는 mosquitto에서 설정파일에 기본적으로 특정 포트에 값을 받는부분이 누락되어잇어 생기는 현상이라고 합니다.
먼저 코드에 이 코드를 추가하여주세요,
client.on('offline', function() {
console.log('MQTT client is offline');
});
client.on('reconnect', function() {
console.log('MQTT client is trying to reconnect');
});

이 코드는 MQTT서버가 offline인지 확인하고,
연결이 되지않았다면 일정시간마다 다시 연결을 시도해줍니다.
이제 mosquitto가 설치된 폴더로 가서 mosquitto.conf 파일을 실행하여주세요.
listener port-number [ip address/host name/unix socket path]
해당 구문으로 Ctrl + F를하면 주석처리된 listener를 확인할 수 있습니다.

이제 주석처리된 listener의 주석처리를 해제하고, listener 1883으로 수정하여주세요.

그리고 이제
allow_anonymous
해당 구문으로 Ctrl + F를 하면 allow_anonymous false'라고 설정된 부분이 보입니다.

이부분 또한 false를 true로 변경하고 주석처리를 해제하여 주세요.

VS Code로 실행시 알림이 뜨는데 그냥 관리자로 실행하시면 수정이 됩니다.

그러나 이렇게 하여도 여전히 접속이 안되는걸 확인할 수 있는데,
이는 Broker로 사용되는 컴퓨터의 방화벽이 외부의 요청을 막고있기 때문입니다.
따라서 방화벽의 설정으로 들어가서 인바운드 요청을 변경해줘야 합니다.

이렇게 규칙을 생성했다면, 컴퓨터를 재부팅하여주세요.

MQTT Broker가 잘 작동하는것을 볼 수 있습니다.