I used the following code and I get this error :
Time out error : [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host failed to respond.
I also turned off the firewall in the systems i am using , still i get that error.
#!/usr/bin/env python3
import paho.mqtt.client as mqtt
# This is the Publisher
client = mqtt.Client()
client.connect("10.12.114.103",1883,60)
client.publish("topic/test", "Hello world!");
client.disconnect();
The problem probably isn't with your python code as I tried a slightly modified version with hivemq's public test server and it worked fine. Here is the version I tried:
#!/usr/bin/env python3
import paho.mqtt.client as mqtt
# This is the Publisher
def on_log(client, userdata, level, buf):
print(level, buf)
client = mqtt.Client()
client.on_log = on_log
client.connect("broker.hivemq.com",1883,60)
client.publish("topic/test", "Hello world!");
client.disconnect();
Note that I modified it to return the log output which would be useful in debugging this. The script returned:
16 Sending PUBLISH (dFalse, q0, r0, m1, 'topic/test', ... (12 bytes)
Which is what I would expect from a successful connection. I also checked your code with the mosquitto test server and it worked fine.
It looks like your broker is not accepting your connection attempt. If you tried a public test server and it still didn't work then it suggests that something is interfering with your traffic on port 1883.
I think this is a broker issue, however, I did notice that you are not using any of the network loop functions (like client.loop_start) which, according to the paho documentation, may cause unpredictable behavior. You could try adding a loop like this to see if that helps
client = mqtt.Client()
client.on_log = on_log
client.connect("broker.hivemq.com",1883,60)
client.loop_start
client.publish("topic/test", "Hello world!");
client.disconnect();
client.loop_stop
Related
I have been struggeling with a strange case of random client MQTT publish failing for certain payloads. It happends randomly when trying to publish some large amount of BASE64 data.
I've finally managed to narrow it down to payloads containing a lot of consequtive forwards slashes (/). I've searched the net to find a good reason why this happends, but havent found anythong. Is it a MQTT feature, a Paho client feature or a broker feature, or just some bug...
Setup:
Python 3.8.8 (Windows 10)
paho-mqtt 1.5.0
mosquitto 1.6.9-1 amd64
On my setup, it fails when I send a payload of 255 '/' to a 1 character topic 'a'. Larger topic length, reduces the possible number of forward slashes.
Code to reproduce error:
import paho.mqtt.client as mqtt_client
import time
address = 'some.server.com'
port = 1883
connected = False
def on_connect(client, userdata, flags, rc):
global connected
connected = True
print("Connected!")
client = mqtt_client.Client()
client.on_connect = on_connect
client.connect(host=address, port=port, keepalive=60)
client.loop_start()
while not connected:
time.sleep(1)
payload = '/'*205
print('Payload: {}'.format(payload))
client.publish(topic='a', payload=payload)
time.sleep(2)
client.loop_stop()
client.disconnect()
print('Done!')
This generates this output:
Connected!
Payload: /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Connected!
Done!
This produces the following error in /var/log/mosquitto/mosquitto.log for the mosquitto broker:
1616605010: New connection from a.b.c.d on port 1883.
1616605010: New client connected from a.b.c.d as auto-CEF15129-E74C-F00A-A6FA-5B5FDA0CEF1D (p2, c1, k60).
1616605011: Socket error on client auto-CEF15129-E74C-F00A-A6FA-5B5FDA0CEF1D, disconnecting.
1616605012: New connection from a.b.c.d on port 1883.
1616605012: New client connected from a.b.c.d as auto-0149B6DB-5997-9E08-366A-304F21FDF2E1 (p2, c1, k60).
1616605013: Client auto-0149B6DB-5997-9E08-366A-304F21FDF2E1 disconnected.
I observe that the client() connects twice, but do not know why, but this is probably caused by a disconnect...
Any Ideas?
Update 1: I've tested this on Linux Ubunit running Python 3.7.3, and same paho-mqtt version, and this does not produce the same error... Seems like some problem in Windows then.
Update 2:
I also tried running mosquitto_pub and experienced the same error, so this has to be Windows-related (or system related) in some way. Possibly firewall? I will close question if I find manage to solve this.
"C:\Program Files\mosquitto\mosquitto_pub.exe" -h some.server.com -t a -m '/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////'
Update 3 The issue is related to OpenVPN. I closed my open VPN connection and MQTT messages were passing! I'm running OpenVPN Client (Windows version 3.2.2 (1455). I have no idea what causes this conlflict...
When I built about 5000 MQTT clients by using threading, I got the error message which is [WinError 10061] as following code.
import paho.mqtt.client as mqtt
import threading
def client(id):
subscriber=mqtt.Client(id)
subscriber.on_connect=on_connect
subscriber.on_message=on_message
subscriber.connect('192.168.233.142',keepalive=20)
subscriber.loop_forever()
def on_connect(subscriber,userdata,flags,rc):
if int(subscriber._client_id.decode())%1000==0:
logging.info('連接伺服器')
def on_message(subscriber,userdata,msg):
message=str(loads(msg.payload.decode()))
if int(subscriber._client_id.decode())%1000==0:
logging.info(message)
for i in range(5001):
threading.Thread(target=client,args=(str(i),)).start()
sleep(0.01)
I have seen this error before when I using ZMQ.SUB in another program, but the numbers of clients were over 10000.
Does too much connections make this problem?
If true, what makes these two package have the huge difference?
Google says 'Win10061' is a "Connection Refused" error....so go look at the log file of your MQTT Broker and see what it says....that is where the error is occuring.
Most MQTT Brokers should be able to handle 5000 connections, but maybe you are starting them too close together and the MQTT Broker gets too busy trying to update its table of clients and push out CONACKs??
Where in your code does the error come back from??
I'm using the gevent-websocket module with Bottle Python framework.
When a client closes the browser, this code
$(window).on('beforeunload', function() { ws.close(); });
helps to close the websocket connection properly.
But if the client's network connection is interrupted, no "close" information can be sent to the server.
Then, often, even 1 minute later, the server still believes the client is connected, and the websocket is still open on the server.
Question: How to detect properly that a websocket is closed because the client is disconnected from network?
Is there a websocket KeepAlive feature available in Python/Bottle/gevent-websocket?
One answer from Web Socket: cannot detect client connection on internet disconnect suggests to use a heartbeat/ping packet every x seconds to tell the server "I'm still alive". The other answer suggests using a setKeepAlive(true). feature. Would this feature be available in gevent-websocket?
Example server code, taken from here:
from bottle import get, template, run
from bottle.ext.websocket import GeventWebSocketServer
from bottle.ext.websocket import websocket
users = set()
#get('/')
def index():
return template('index')
#get('/websocket', apply=[websocket])
def chat(ws):
users.add(ws)
while True:
msg = ws.receive()
if msg is not None:
for u in users:
u.send(msg)
else:
break
users.remove(ws)
run(host='127.0.0.1', port=8080, server=GeventWebSocketServer)
First you need to add a timeout to the receive() method.
with gevent.Timeout(1.0, False):
msg = ws.receive()
Then the loop will not block, if you send even an empty packet and the client doesn't respond, WebsocketError will be thrown and you can close the socket.
I'm using this python script to implement a basic Paho(MQTT) subscriber but under certain circumstances it doesn't invoke on_connect.
I tried the following, all with exactly the same code:
Running in a Raspbery pi, broker on desktop Pc (Ubuntu). Works.
Running in a Pc(Ubuntu), broker on the same Pc. Doesn't work.
Running in a Pc(Ubuntu), broker on other Pc(Ubuntu). Doesn't work.
Running in a Pc(Ubuntu), broker.hivemq.com as broker. Works.
Running in a Pc(Ubuntu), broker.hivemq.com (it's IP) as broker. Works.
I also usually do:
mosquitto_sub/pub in terminal in all previous combinations. Works.
Official C++ paho wrapper in all previous combinations. Works.
Also tried all setup methods listed in the official website. So python's paho library doesn't seem to be getting along with my local broker unless I run it from my raspberry. But using the same broker works well with c++'s paho library and if using MQTT from the terminal. Any ideas of what can be happening?
import paho.mqtt.client as mqtt
def on_connect(mqtt_client, obj, flags, rc):
mqtt_client.subscribe("test")
print "on_connect"
def on_message(mqtt_client, obj, msg):
print "on_message"
mqtt_client = mqtt.Client()
mqtt_client.on_connect = on_connect
mqtt_client.on_message = on_message
mqtt_client.connect("127.0.0.1",1883)
mqtt_client.loop_forever()
I had the same problem and changing the version of MQTT protocol in Client's constructor solved it.
mqtt_client = mqtt.Client("", True, None, mqtt.MQTTv31)
Since you do not specify the protocol, it uses the default one: MQTTv311.
I have installed the last version of raspbian on my raspberry pi, and I have opened an account AWS IoT on Amazon, then in the IoT web interface I have created a thing, with "RaspberryPi_2" name and create certificate and connect the certificate to the thing, I have followed this guide:
http://blog.getflint.io/blog/get-started-with-aws-iot-and-raspberry-pi
I have then created the script in the guide, to connect and subscribed the raspberry pi, this is my code:
#!/usr/bin/python3
#required libraries
import sys
import ssl
import paho.mqtt.client as mqtt
#called while client tries to establish connection with the server
def on_connect(mqttc, obj, flags, rc):
if rc==0:
print ("Subscriber Connection status code: "+str(rc)+" | Connection status: successful")
elif rc==1:
print ("Subscriber Connection status code: "+str(rc)+" | Connection status: Connection refused")
#called when a topic is successfully subscribed to
def on_subscribe(mqttc, obj, mid, granted_qos):
print("Subscribed: "+str(mid)+" "+str(granted_qos)+"data"+str(obj))
#called when a message is received by a topic
def on_message(mqttc, obj, msg):
print("Received message from topic: "+msg.topic+" | QoS: "+str(msg.qos)+" | Data Received: "+str(msg.payload))
#creating a client with client-id=mqtt-test
mqttc = mqtt.Client(client_id="mqtt-test")
mqttc.on_connect = on_connect
mqttc.on_subscribe = on_subscribe
mqttc.on_message = on_message
#Configure network encryption and authentication options. Enables SSL/TLS support.
#adding client-side certificates and enabling tlsv1.2 support as required by aws-iot service
mqttc.tls_set("/home/pi/aws_iot/things/raspberryPi_2/certs/aws-iot-rootCA.crt",
certfile="/home/pi/aws_iot/things/raspberryPi_2/certs/0ea2cd7eb6-certificate.pem.crt",
keyfile="/home/pi/aws_iot/things/raspberryPi_2/certs/0ea2cd7eb6-private.pem.key",
tls_version=ssl.PROTOCOL_TLSv1_2,
ciphers=None)
#connecting to aws-account-specific-iot-endpoint
mqttc.connect("A2GF7W5U5A46J1.iot.us-west-2.amazonaws.com", port=8883) #AWS IoT service hostname and portno
#the topic to publish to
mqttc.subscribe("$aws/things/RaspberryPi_2/shadow/update/#", qos=1) #The names of these topics start with $aws/things/thingName/shadow."
#automatically handles reconnecting
mqttc.loop_forever()
but when I do this command:
python3 mqtt_test.py
or this command:
python mqtt_test.py
and press enter, and the cursor flash and doesn't print anything and stay stuck there, someone can help me?
I haven't also understand if the client-id name should be the same of the things name, and the meaning of the subscribe path, for example in a tutorial I have found this:
mqttc.publish("temperature", tempreading, qos=1)
why there isn't the complete path?
or this:
$aws/things/RaspberryPi_2/shadow/update/delta
so I can put everything I want in the path?
thanks
The code is subscribing to a topic but there is no one publishing to it. So, the code also has a on_connect function that would be triggered after a success connection. Is the message "Subscriber Connection status code: ..." being printed? If it is, the message from on_subscribe should also appear. Is it?
If it is not you have a problem before connect to the AWS server. Use netstat command to see where your Raspberry Pi is connected or not and post more debug information in this case.
If the connect and subscribe messages are shown and nothing happens after it, this is normal because you are only subscribing to a topic but not publishing anything.
Regarding topics, think of them as a directory structure. There is no strict rule for topic hierarchy. A "temperature" topic would be temperature topic on the server and a "temperature/livingroom" would be temperature/livingroom, you can subscribe to one, another or both on the same server. The path you choose for your things shall be meaningful to your application. A house, for instance, might be represented as:
house/kitchen/env/temperature
house/kitchen/env/humidity
house/kitchen/lamp/sinklamp
house/kitchen/lamp/mainlap
house/masterbed/env/temperature
house/masterbed/env/humidity
house/masterbed/lamp/readinglampleft
house/masterbed/lamp/readinglampright
house/masterbed/lamp/mainlamp
house/masterbed/lamp/mirrorlamp
And so on.
Let´s say you have a thermostat at master bedroom. It is interested only in temperature but not humidity. It is also interested only in master bedroom temperature. This thermostat shall subscribe to house/masterbed/env/temperature. Opposite to this, a room wide panel that shows state of every thing in the room, would subscribe to house/masterbed/#, meaning "everything after house/masterbed". Read more on wildcards here
The topic you subscribed for: $aws/things/RaspberryPi_2/shadow/update/# means, "every thing after $aws/things/RaspberryPi_2/shadow/update/". Notice that his is a special topic, it starts with $aws, specially, it starts with $ character. In the AWS context this means:
Any topics beginning with $ are considered reserved and are not
supported for publishing and subscribing except when working with the
Thing Shadows service. For more information, see Thing Shadows.
So you need to understand what thing shadow is. This is a AWS specific (and very util) concept. Please read docs on this subject.
Finally, I would you suggest you install a local broker (mosquitto is available on respbian) and try with it before got to AWS. This way you can master mqtt concept without connectivity issues. Later you put AWS to the mix.