로컬 Mosquitto 브로커 실행
이 튜토리얼을 마치면 다음을 할 수 있습니다.
- 설정 파일로 Mosquitto 브로커를 실행합니다.
- 와일드카드 필터로 구독하고 QoS 1, QoS 2의 패킷 흐름을 로그로 확인합니다.
- 보존 메시지를 만들고 지웁니다.
- 비정상 종료한 클라이언트의 Will 메시지를 받습니다.
이 브로커 구성은 이후 튜토리얼에서도 그대로 씁니다.
준비물
섹션 제목: “준비물”- Mosquitto 2.x와
mosquitto_pub,mosquitto_sub. 설치 방법은 MQTT 빠른 시작의 1단계를 참고합니다. - 터미널 창 3개
- 1883번 포트를 쓰는 다른 브로커가 없어야 합니다. 빠른 시작의
mosquitto -v가 실행 중이면 Ctrl+C로 끝냅니다.
-
작업 디렉터리를 만들고 브로커 설정 파일을 저장합니다.
터미널 창 mkdir mqtt-labcd mqtt-lablocal.conf # Local development broker for the PDComm MQTT tutorials.# Plain TCP on the loopback interface only, without authentication.listener 1883 127.0.0.1allow_anonymous true# Keep nothing between runs and log every connection and packet.persistence falselog_dest stdoutlog_type all설정 뜻 listener 1883 127.0.0.1루프백 주소의 1883번 포트에서 평문 MQTT를 받습니다. 다른 컴퓨터에서는 연결할 수 없습니다. allow_anonymous true사용자 이름 없이 연결을 허용합니다. 리스너를 직접 설정하면 Mosquitto 2.x의 기본값은 false입니다.persistence false세션과 보존 메시지를 디스크에 저장하지 않습니다. 브로커를 다시 시작하면 사라집니다. log_dest stdout,log_type all모든 로그를 터미널에 출력합니다. 패킷 하나하나가 보입니다. -
첫 번째 터미널에서 브로커를 시작합니다.
터미널 창 mosquitto -c local.confmosquitto version 2.1.2 startingConfig loaded from local.conf.Opening ipv4 listen socket on port 1883.mosquitto version 2.1.2 runningError: Address already in use가 나오면 다른 프로그램이 1883번 포트를 쓰고 있습니다. 그 프로그램을 끝내고 다시 실행합니다. Homebrew로 설치했다면brew services list에서mosquitto서비스가 실행 중인지 확인합니다. -
두 번째 터미널에서 와일드카드 필터로 QoS 1 구독을 만듭니다.
터미널 창 mosquitto_sub -V 5 -q 1 -t 'factory/+/temperature' -v-v는 메시지마다 토픽과 페이로드를 함께 출력합니다. 브로커 로그에 구독이 기록됩니다.Received SUBSCRIBE from auto-3768C1CB-…factory/+/temperature (QoS 1) -
세 번째 터미널에서 QoS 1로 발행하고 패킷 흐름을 봅니다.
터미널 창 mosquitto_pub -d -V 5 -q 1 -t factory/line1/temperature -m 21.5Client null sending CONNECTClient auto-7BDD9F5C-… received CONNACK (0)Client auto-7BDD9F5C-… sending PUBLISH (d0, q1, r0, m1, 'factory/line1/temperature', ... (4 bytes))Client auto-7BDD9F5C-… received PUBACK (Mid: 1, RC:0)Client auto-7BDD9F5C-… sending DISCONNECT-d는 클라이언트가 주고받는 패킷을 출력합니다.q1은 QoS 1,m1은 패킷 식별자 1입니다. 두 번째 터미널에는factory/line1/temperature 21.5가 나옵니다. -
같은 토픽에 QoS 2로 발행합니다.
터미널 창 mosquitto_pub -d -V 5 -q 2 -t factory/line1/temperature -m 21.6Client auto-DB1B2CB5-… sending PUBLISH (d0, q2, r0, m1, 'factory/line1/temperature', ... (4 bytes))Client auto-DB1B2CB5-… received PUBREC (Mid: 1)Client auto-DB1B2CB5-… sending PUBREL (m1)Client auto-DB1B2CB5-… received PUBCOMP (Mid: 1, RC:0)브로커 로그를 보면 QoS 2로 받은 메시지를 구독자에게는 QoS 1로 보냅니다. 구독이 QoS 1이므로 둘 중 낮은 QoS가 적용됩니다.
Received PUBLISH from auto-A40DF054-… (d0, q2, r0, m1, 'factory/line1/temperature', ... (4 bytes))Sending PUBREC to auto-A40DF054-… (m1, rc0)Received PUBREL from auto-A40DF054-… (Mid: 1)Sending PUBLISH to auto-3768C1CB-… (d0, q1, r0, m2, 'factory/line1/temperature', ... (4 bytes)) -
보존 메시지를 만듭니다. 세 번째 터미널에서 실행합니다.
터미널 창 mosquitto_pub -V 5 -q 1 -r -t factory/line1/state -m RUN발행이 끝난 뒤에 구독을 새로 만듭니다.
터미널 창 mosquitto_sub -V 5 -t factory/line1/state -C 1 -F '%t %p retain=%r'factory/line1/state RUN retain=1구독자는 발행보다 늦게 연결했지만 브로커가 저장한 보존 메시지를 바로 받습니다.
retain=1은 보존 메시지로 받았다는 뜻입니다.-C 1은 메시지 하나를 받으면 끝내라는 옵션입니다. -
보존 메시지를 지우고 확인합니다.
터미널 창 mosquitto_pub -V 5 -r -n -t factory/line1/statemosquitto_sub -V 5 -t factory/line1/state -C 1 -W 2 -F '%t %p retain=%r'Timed out-n은 빈 페이로드를 보냅니다. 빈 보존 메시지는 그 토픽의 보존 메시지를 지웁니다.-W 2는 2초 동안 메시지가 없으면 끝내라는 옵션이며, 이때 종료 코드는 27입니다. -
Will 메시지를 확인합니다. 두 번째 터미널의 구독을 Ctrl+C로 끝내고 상태 토픽을 구독합니다.
터미널 창 mosquitto_sub -V 5 -t 'factory/+/status' -v세 번째 터미널에서 Will 메시지를 맡긴 클라이언트를 백그라운드로 실행하고, 연결될 때까지 1초 기다린 뒤 강제로 끝냅니다.
터미널 창 mosquitto_sub -V 5 -i cell2 -t factory/line1/cmd --will-topic factory/line1/status --will-payload offline -k 5 &sleep 1kill -KILL $!두 번째 터미널에 Will 메시지가 나옵니다.
factory/line1/status offlinekill -KILL로 끝난 프로세스는 DISCONNECT를 보내지 못합니다. 브로커는 비정상 종료로 보고 Will을 발행합니다. Ctrl+C로 끝내면 정상 DISCONNECT를 보내므로 Will이 발행되지 않습니다. Windows에서는cell2클라이언트를 실행한 터미널 창을 닫아 같은 결과를 얻습니다.
- 두 번째 터미널의
mosquitto_sub를 Ctrl+C로 끝냅니다. - 첫 번째 터미널의 브로커를 Ctrl+C로 끝냅니다.
persistence false이므로 보존 메시지와 세션은 남지 않습니다. mqtt-lab디렉터리와local.conf는 다음 튜토리얼에서 다시 씁니다.
자주 나는 오류
섹션 제목: “자주 나는 오류”| 출력 | 원인 | 해결 |
|---|---|---|
Error: Address already in use |
다른 브로커가 1883번 포트를 쓰고 있습니다. | 기존 브로커를 끝내거나 listener의 포트를 바꿉니다. 포트를 바꾸면 클라이언트에 -p <포트>를 줍니다. |
Error: Bad file descriptor |
브로커가 실행 중이 아니어서 연결하지 못했습니다. 운영체제에 따라 문장이 다를 수 있습니다. | 2단계의 브로커가 실행 중인지 확인합니다. |
| 구독자에 아무것도 나오지 않음 | 필터와 토픽이 맞지 않습니다. 대소문자도 구분합니다. | -t의 필터와 발행 토픽을 비교합니다. |
6단계에서 retain=1 대신 아무것도 나오지 않음 |
-r 없이 발행했습니다. |
mosquitto_pub에 -r을 붙여 다시 발행합니다. |