0
votes

The following python code on my raspberrypi doesn't connect to my mqtt broker, it just hangs after printing Connecting...:

import paho.mqtt.client as mqtt

def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))
    client.subscribe("test")


def on_message(client, userdata, msg):
    print(msg.topic+" "+str(msg.payload))


client = mqtt.Client(client_id="",clean_session=True,userdata=None,protocol=mqtt.MQTTv311,transport="tcp")
client.on_connect = on_connect
client.on_message = on_message

client.username_pw_set(username="stackoverflow",password="stackoverflow")
print("Connecting...")
client.connect("learn.evermight.net", 9101, 10)
client.loop_forever()

What did I do wrong with my Python code?


Command Line Success

I confirmed that my mqtt does work because I can subscribe from terminal with this command:

mosquitto_sub -h learn.evermight.net -p 9101 -t "test" -u "stackoverflow" -P "stackoverflow" --capath /etc/ssl/certs/

And I will see messages in my terminal as soon as I run this command from another terminal

mosquitto_pub -h learn.evermight.net -p 9101 -t "test" -u "stackoverflow" -P "stackoverflow" -m "hello world" --capath /etc/ssl/certs/

What is wrong with my python code?


NodeJS Success

Additionally, the following NodeJS code also works for connecting and publishing to my MQTT server.

const mqtt = require('async-mqtt');

  try{
    const client = await mqtt.connectAsync("mqtts://learn.evermight.net",{
      port:9101,
      host:"mqtts://learn.evermight.net",
      username:"stackoverflow",
      password:"stackoverflow",
      connectTimeout:5000,
      protocolId:"MQIsdp",
      protocolVersion:3,
      encoding:"utf8",
      keepalive: 60
    });
    await client.publish("test","hello world");
    await client.end();
  } catch(e) {
    console.log(e);
  }

Website JavaScript Success

And the following code can also connect to a websocket port via web browser javascript website, subscribe to the test topic and receive published messages (note that my websockets use port 9102)

import Paho from "paho-mqtt";

const client = new Paho.Client("learn.evermight.net",9102,"WebBrowser");
  client.onConnectionLost = response=>console.log("lostMQTTConnection: " +(response.errorCode !== 0 ? response.errorMessage : "Unknown MQTT Error" ));
  client.onMessageArrived = message=>console.log(message.payloadString);
  client.connect({
    onSuccess:_=>client.subscribe("test"),
    useSSL:true,
    userName:"stackoverflow",
    password:"stackoverflow",
  });
1
why do you know if it hangs ? loop_forever() should runs code all the time until you kill it. - furas
as for me all problem can be --capath /etc/ssl/certs/. When I run your code with my broker then it runs, and when I run mosquitto_pub without --capath /etc/ssl/certs/ then it also runs but I get Error: Connection refused when I use --capath /etc/ssl/certs/. Probably in code you would have to use something similar to --capath /etc/ssl/certs/ - furas
@furas I updated my code to give real credentials to my mqtt server and I give real working examples in bash, nodejs and plain javascript. The only thing that fails is my python code. Does my server work for your python script? - John
it doesn't work with Python. It works only with mosquitto_sub/mosquitto_pub so I can connect. There are command client.tls_set() and client.tls_set_context() and maybe they could help. But I never had to use it. I have own MTTQ in local network so I didn't bother to use certs - furas

1 Answers

7
votes

I found that I can connect if I add this command without arguments

client.tls_set()

In paho documentation at the end of description for tls_set() you can see

Must be called before connect*().

but it works for me event after client.connect()


In the same domentation you can see that without arguments it uses defult system settings

By default, on Python 2.7.9+ or 3.4+,  
the default certification authority of the system is used. 

On older Python version this parameter is mandatory.

It is needed only if mosquitto_sub/mosquitto_pub needs --capath /etc/ssl/certs/.
If mosquitto_sub/mosquitto_pub works without --capath /etc/ssl/certs/ then don't use it.


import paho.mqtt.client as mqtt

def on_connect(client, userdata, flags, rc):
    print("Connected with result code", rc)
    client.subscribe("test")

def on_message(client, userdata, msg):
    print(msg.topic, msg.payload)


client = mqtt.Client(client_id="", clean_session=True, userdata=None, protocol=mqtt.MQTTv311, transport="tcp")
client.on_connect = on_connect
client.on_message = on_message

client.tls_set()  # <--- even without arguments

client.username_pw_set(username="stackoverflow", password="stackoverflow")
print("Connecting...")
client.connect("learn.evermight.net", 9101, 10)
client.loop_forever()