I'm currently working on an MQTT project using an NVIDIA Jetson running Ubuntu 18.04. I have installed mosquitto (version 2.0.15) as my MQTT broker and paho-mqtt (version 1.6.1) for my Python MQTT client.
I'm encountering an issue where I consistently receive an "invalid protocol version" error with an "mid" (message identifier) code of 1 when attempting to publish messages to my MQTT broker. I have double-checked my code and configuration, and I believe I am specifying the correct protocol version (MQTTv5) in my Python MQTT client as mosquitto v2.0.15 supports MQTTv5 and MQTTv3.1.
The broker server and publish client are running on the same device/network.
The MQTT broker is indeed running:
gabe@gabe-desktop:~$ systemctl status mosquitto
mosquitto.service - Mosquitto MQTT Broker
Loaded: loaded (/lib/systemd/system/mosquitto.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2024-01-06 19:10:01 CET; 1h 35min ago
Docs: man:mosquitto.conf(5)
man:mosquitto(8)
Main PID: 22604 (mosquitto)
Tasks: 1 (limit: 4180)
CGroup: /system.slice/mosquitto.service
└─22604 /usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf
Jan 06 19:10:01 gabe-desktop systemd[1]: Starting Mosquitto MQTT Broker...
Jan 06 19:10:01 gabe-desktop systemd[1]: Started Mosquitto MQTT Broker.
and port 1883 is listening on addresses: localhost:1883
and ip6-localhost:1883
.
gabe@gabe-desktop:~$ netstat -at
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:sunrpc 0.0.0.0:* LISTEN
tcp 0 0 localhost:domain 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:ssh 0.0.0.0:* LISTEN
tcp 0 0 localhost:1883 0.0.0.0:* LISTEN
tcp 0 0 localhost:40283 0.0.0.0:* LISTEN
tcp 0 0 localhost:42269 0.0.0.0:* LISTEN
tcp 0 0 localhost:34941 0.0.0.0:* LISTEN
tcp 0 0 localhost:40451 0.0.0.0:* LISTEN
tcp 0 0 localhost:gpsd 0.0.0.0:* LISTEN
tcp 0 0 localhost:40283 localhost:47786 ESTABLISHED
tcp 0 0 gabe-desktop:35130 13.107.5.93:https ESTABLISHED
tcp 0 108 gabe-desktop:ssh Gabes-MBP:53006 ESTABLISHED
tcp 0 0 gabe-desktop:35140 13.107.5.93:https ESTABLISHED
tcp 0 0 localhost:40283 localhost:47788 ESTABLISHED
tcp 0 0 localhost:47786 localhost:40283 ESTABLISHED
tcp 0 0 localhost:47788 localhost:40283 ESTABLISHED
tcp 0 0 localhost:40283 localhost:47272 CLOSE_WAIT
tcp6 0 0 [::]:sunrpc [::]:* LISTEN
tcp6 0 0 [::]:ssh [::]:* LISTEN
tcp6 0 0 ip6-localhost:1883 [::]:* LISTEN
tcp6 0 0 ip6-localhost:gpsd [::]:* LISTEN
Here is the Python code and error when attempting to create a publish connection:
import paho.mqtt.client as mqtt
# MQTT broker information
BROKER_ADDRESS = "localhost"
PORT = 1883
TOPIC = "testing"
RESPONSE = {
0: "connection succeeded",
1: "connection failed - incorrect protocol version",
2: "connection failed - invalid client identifier",
3: "connection failed - the broker is not available",
4: "connection failed - wrong username or password",
5: "connection failed - unauthorized"
}
def on_publish(client, data, mid):
print(f"Connected to broker with status: {mid}: {RESPONSE.get(mid, 'Unknown')}")
def main():
client = mqtt.Client(client_id="jetson", protocol=mqtt.MQTTv5)
# Set the callback function for when the publisher connects to the broker
client.on_publish = on_publish
# Connect to the broker
client.connect(BROKER_ADDRESS, PORT)
# Publish a message to the "testing" topic
message = "Hello, world!"
client.publish(TOPIC, message)
# Keep client running "forever"
client.loop_forever()
if __name__ == '__main__':
main()
Connected to broker with status: 1: connection failed - incorrect protocol version
I also tried protocol version mqtt.MQTTv31
and received the same error.
All the resources online have to do ensuring the mosquitto config file is properly configured. However, I have double checked this and this seems to be the case.
To ensure the MQTT broker server was indeed running correctly I performed the following test in two separate terminals
Terminal 1:
gabe@gabe-desktop:~$ mosquitto_sub -h localhost -t test
Terminal 2:
gabe@gabe-desktop:~$ mosquitto_pub -h localhost -t test -m "hello world"
I get the "hello world" output in terminal 1.
def on_publish(client, data, mid):
print(f"Connected to broker with status: {mid}: {RESPONSE.get(mid, 'Unknown')}")
on_publish
is "called when a message that was to be sent using the
publish() call has completed transmission to the broker." and is passed:
client: the client instance for this callback
userdata: the private user data as set in Client() or userdata_set()
mid: matches the mid variable returned from the corresponding publish() call, to allow outgoing messages to be tracked.
You appear to be assuming that the mid
indicates whether the connection is successful or not (as per the docs copied above; it does not). .
So what is happening (well, what happens when I test your code) is that you are successfully connecting to the broker and then successfully publishing a message. However once the message has been transmitted your on_publish
is called (which incorrectly prints an error message).
I subject you intended something like:
def on_connect(client, userdata, flags, reasonCode, properties):
print(f"Connected to broker with status: {reasonCode}")
def on_publish(client, data, mid):
print(f"Publish completed: {mid}")
def main():
client = mqtt.Client(client_id="jetson", protocol=mqtt.MQTTv5)
# Set the callback function for when the publisher connects to the broker
client.on_connect = on_connect
client.on_publish = on_publish
...