콘텐츠로 이동
무료 평가 시작

로컬 Mosquitto 브로커 실행

이 튜토리얼을 마치면 다음을 할 수 있습니다.

  • 설정 파일로 Mosquitto 브로커를 실행합니다.
  • 와일드카드 필터로 구독하고 QoS 1, QoS 2의 패킷 흐름을 로그로 확인합니다.
  • 보존 메시지를 만들고 지웁니다.
  • 비정상 종료한 클라이언트의 Will 메시지를 받습니다.

이 브로커 구성은 이후 튜토리얼에서도 그대로 씁니다.

  • Mosquitto 2.x와 mosquitto_pub, mosquitto_sub. 설치 방법은 MQTT 빠른 시작의 1단계를 참고합니다.
  • 터미널 창 3개
  • 1883번 포트를 쓰는 다른 브로커가 없어야 합니다. 빠른 시작의 mosquitto -v가 실행 중이면 Ctrl+C로 끝냅니다.
  1. 작업 디렉터리를 만들고 브로커 설정 파일을 저장합니다.

    터미널 창
    mkdir mqtt-lab
    cd mqtt-lab
    local.conf
    # Local development broker for the PDComm MQTT tutorials.
    # Plain TCP on the loopback interface only, without authentication.
    listener 1883 127.0.0.1
    allow_anonymous true
    # Keep nothing between runs and log every connection and packet.
    persistence false
    log_dest stdout
    log_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 모든 로그를 터미널에 출력합니다. 패킷 하나하나가 보입니다.
  2. 첫 번째 터미널에서 브로커를 시작합니다.

    터미널 창
    mosquitto -c local.conf
    mosquitto version 2.1.2 starting
    Config loaded from local.conf.
    Opening ipv4 listen socket on port 1883.
    mosquitto version 2.1.2 running

    Error: Address already in use가 나오면 다른 프로그램이 1883번 포트를 쓰고 있습니다. 그 프로그램을 끝내고 다시 실행합니다. Homebrew로 설치했다면 brew services list에서 mosquitto 서비스가 실행 중인지 확인합니다.

  3. 두 번째 터미널에서 와일드카드 필터로 QoS 1 구독을 만듭니다.

    터미널 창
    mosquitto_sub -V 5 -q 1 -t 'factory/+/temperature' -v

    -v는 메시지마다 토픽과 페이로드를 함께 출력합니다. 브로커 로그에 구독이 기록됩니다.

    Received SUBSCRIBE from auto-3768C1CB-…
    factory/+/temperature (QoS 1)
  4. 세 번째 터미널에서 QoS 1로 발행하고 패킷 흐름을 봅니다.

    터미널 창
    mosquitto_pub -d -V 5 -q 1 -t factory/line1/temperature -m 21.5
    Client null sending CONNECT
    Client 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가 나옵니다.

  5. 같은 토픽에 QoS 2로 발행합니다.

    터미널 창
    mosquitto_pub -d -V 5 -q 2 -t factory/line1/temperature -m 21.6
    Client 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))
  6. 보존 메시지를 만듭니다. 세 번째 터미널에서 실행합니다.

    터미널 창
    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은 메시지 하나를 받으면 끝내라는 옵션입니다.

  7. 보존 메시지를 지우고 확인합니다.

    터미널 창
    mosquitto_pub -V 5 -r -n -t factory/line1/state
    mosquitto_sub -V 5 -t factory/line1/state -C 1 -W 2 -F '%t %p retain=%r'
    Timed out

    -n은 빈 페이로드를 보냅니다. 빈 보존 메시지는 그 토픽의 보존 메시지를 지웁니다. -W 2는 2초 동안 메시지가 없으면 끝내라는 옵션이며, 이때 종료 코드는 27입니다.

  8. 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 1
    kill -KILL $!

    두 번째 터미널에 Will 메시지가 나옵니다.

    factory/line1/status offline

    kill -KILL로 끝난 프로세스는 DISCONNECT를 보내지 못합니다. 브로커는 비정상 종료로 보고 Will을 발행합니다. Ctrl+C로 끝내면 정상 DISCONNECT를 보내므로 Will이 발행되지 않습니다. Windows에서는 cell2 클라이언트를 실행한 터미널 창을 닫아 같은 결과를 얻습니다.

  1. 두 번째 터미널의 mosquitto_sub를 Ctrl+C로 끝냅니다.
  2. 첫 번째 터미널의 브로커를 Ctrl+C로 끝냅니다. persistence false이므로 보존 메시지와 세션은 남지 않습니다.
  3. 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을 붙여 다시 발행합니다.