Skip to content
Start free evaluation

Run a local Mosquitto broker

When you finish this tutorial, you can:

  • Run a Mosquitto broker from a configuration file.
  • Subscribe with a wildcard filter and follow the QoS 1 and QoS 2 packet flows in the logs.
  • Create and delete a retained message.
  • Receive the Will message of a client that fails.

The later tutorials reuse this broker setup.

  • Mosquitto 2.x with mosquitto_pub and mosquitto_sub. Step 1 of the MQTT quickstart shows how to install them.
  • Three terminal windows.
  • No other broker on port 1883. If mosquitto -v from the quickstart is still running, stop it with Ctrl+C.
  1. Create a working directory and save the broker configuration:

    터미널 창
    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
    Setting Meaning
    listener 1883 127.0.0.1 Accept plain MQTT on port 1883 of the loopback address. Other computers can’t connect.
    allow_anonymous true Accept clients without a user name. Once you configure a listener yourself, Mosquitto 2.x defaults to false.
    persistence false Don’t save sessions or retained messages to disk; they’re gone when the broker restarts.
    log_dest stdout, log_type all Print every log line, including each packet, to the terminal.
  2. In the first terminal, start the broker:

    터미널 창
    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

    If you see Error: Address already in use, another program owns port 1883. Stop it and run the command again. If you installed Mosquitto with Homebrew, check brew services list for a running mosquitto service.

  3. In the second terminal, create a QoS 1 subscription with a wildcard filter:

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

    -v prints the topic together with each payload. The broker logs the subscription:

    Received SUBSCRIBE from auto-3768C1CB-…
    factory/+/temperature (QoS 1)
  4. In the third terminal, publish at QoS 1 and watch the packet flow:

    터미널 창
    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 prints the packets the client sends and receives. q1 is QoS 1 and m1 is packet identifier 1. The second terminal prints factory/line1/temperature 21.5.

  5. Publish to the same topic at 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)

    The broker log shows that a message received at QoS 2 goes to the subscriber at QoS 1. The subscription is QoS 1, and the lower of the two applies.

    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. Create a retained message. Run this in the third terminal:

    터미널 창
    mosquitto_pub -V 5 -q 1 -r -t factory/line1/state -m RUN

    Then create a new subscription after the publication:

    터미널 창
    mosquitto_sub -V 5 -t factory/line1/state -C 1 -F '%t %p retain=%r'
    factory/line1/state RUN retain=1

    The subscriber connected after the message was published, yet it receives the retained message right away. retain=1 shows that it arrived as a retained message. -C 1 stops the client after one message.

  7. Delete the retained message and check that it’s gone:

    터미널 창
    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 sends an empty payload, and an empty retained message deletes the retained message of its topic. -W 2 stops the client when no message arrives within two seconds; it then exits with code 27.

  8. Watch a Will message. Stop the subscription in the second terminal with Ctrl+C, and subscribe to the status topics:

    터미널 창
    mosquitto_sub -V 5 -t 'factory/+/status' -v

    In the third terminal, start a client that leaves a Will message, wait a second for it to connect, and kill it:

    터미널 창
    mosquitto_sub -V 5 -i cell2 -t factory/line1/cmd --will-topic factory/line1/status --will-payload offline -k 5 &
    sleep 1
    kill -KILL $!

    The Will message appears in the second terminal:

    factory/line1/status offline

    A process killed with kill -KILL can’t send DISCONNECT, so the broker treats it as a failure and publishes the Will. Ctrl+C sends a normal DISCONNECT instead, and the broker doesn’t publish the Will. On Windows, close the terminal window that runs the cell2 client to get the same result.

  1. Stop mosquitto_sub in the second terminal with Ctrl+C.
  2. Stop the broker in the first terminal with Ctrl+C. With persistence false, no retained messages or sessions remain.
  3. Keep the mqtt-lab directory and local.conf; the next tutorials use them.
Output Cause Fix
Error: Address already in use Another broker owns port 1883. Stop that broker, or change the port of listener and pass -p <port> to the clients.
Error: Bad file descriptor The client couldn’t connect because no broker is running. The wording can differ by operating system. Check that the broker from step 2 is running.
Nothing appears in the subscriber The filter doesn’t match the topic; remember that topics are case-sensitive. Compare the -t filter with the published topic.
Step 6 prints nothing instead of retain=1 You published without -r. Publish again with -r.