I have setup a mosquitto client that sends data to a dygraph script which plots the data real time. My issue is that sometimes, when i close the dygraph html window, the terminal from which my mqtt script sends the data comes with the line "errno 104 connection reset by peer". After this, if I close and reopen my mqtt script, it won't run with the message "socket.error: [Errno 111] Connection refused"
I have enabled websockets in order to send data to my html file, so there must be a conflict there.
The mqtt code is:
import paho.mqtt.client as mqtt
import time
import random
def on_connect(client, userdata, flags, rc): #function to call on connect
print("Connected with result code "+str(rc))
client.subscribe("topic1/")
def on_message(client, userdata, msg): #function to call on message
print(msg.topic+" "+str(msg.payload))
client = mqtt.Client()
client.reinitialise() #initiate mqtt client
#client.on_connect = on_connect
#client.on_message = on_message
client.connect("localhost", 1883, 60) #connect to broker
client.loop_start()
while True:
client.publish("topic1/", random.uniform(-20, 20))
time.sleep(0.5)
and the websocket from which my html file reads the data is:
var MQTTport = 9001;
9001 is what I have said to be the websocket in the mqtt config file.
So why does it crash when i press I close the tab in the html window but runs normally if I keep it open?
Thank you in advance.
Related
I am having an issue with the code below.
The code works perfectly at the beginning. First it says Connected to MQTT Broker! and receives data from it. But after a long time (like 6 hours, or 10 hours etc.) it says again Connected to MQTT Broker! and after that id does not receive any other data.
I am trying to make this program work forever, but i don't know what i have done wrong.
Any ideas?
# python3.6
import random
import mysql.connector
from paho.mqtt import client as mqtt_client
import json
# Code for MQTT Connection
broker = 'YOUR_BROKER'
port = 1883
topic = "YOUR_TOPIC"
# generate client ID with pub prefix randomly
client_id = f'python-mqtt-{random.randint(0, 100)}'
username = "THE_USERNAME"
password = "THE_PASSWORD"
# Function to connect on mqtt
def connect_mqtt() -> mqtt_client:
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("Connected to MQTT Broker!")
else:
print("Failed to connect, return code %d\n", rc)
client = mqtt_client.Client(client_id)
client.username_pw_set(username, password)
client.on_connect = on_connect
client.connect(broker, port)
return client
# function to subscribe from mqtt
def subscribeFunc(client: mqtt_client):
def on_messageFunc(client, userdata, msg):
print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")
client.subscribe(topic)
client.on_message = on_messageFunc
def run():
client = connect_mqtt()
subscribeFunc(client)
client.loop_forever()
if __name__ == '__main__':
run()
I tried to find the problem but it seems that nothing changed significantly.
I am expecting this program to receive data without stopping.
Network connections may not be 100% reliable (and servers etc are restarted from time to time) so expecting the connection to remain up forever is unrealistic. The issue with your code is that it connects then subscribes; if the connection is dropped it does not resubscribe. As the connection is clean_session=true and subscription qos=0 (the defaults) the broker will forget about any active subscriptions when the connection drops (so the client will reconnect but not receive any more messages).
The Simple solution is to use the approach shown in the docs and subscribe in the on_connect callback (that way the subscription will be renewed after reconnection):
def on_connect(client, userdata, flags, rc):
# Subscribing in on_connect() means that if we lose the connection and
# reconnect then subscriptions will be renewed.
client.subscribe("$SYS/#")
client = mqtt.Client()
client.on_connect = on_connect
client.connect("mqtt.eclipseprojects.io", 1883, 60)
You may also want to consider the advice in this answer (as per the comment from #mnikley) because that way the broker will queue up messages for you while the connection is down (otherwise these will be lost).
My MQTT subscribe generally is fine, but when something exception in server, My MQTT will not working, like out of momeory then server kill postgresql or some task, and postgresql into the recovery mode, that will let mine MQTT's PostgreSQL connection fail( Connection Close) in spite of Postgresql service is back, My MQTT still connection fail(or close).
so, Is there anyway can auto reconnect?
import threading
import paho.mqtt.client as paho_mqtt
def t1():
client = paho_mqtt.Client(client_id="*****")
client.on_connect = on_connect
client.on_message = on_message
client.username_pw_set("****", "****")
client.connect("******", ***, **)
client.loop_forever()
def on_connect(client, userdata, flags, rc):
client.subscribe(topic="********", qos=1)
print('subcriptions')
print(userdata)
print(flags)
print(rc)
thread1 = threading.Thread(target=t1)
thread1.start()
time.sleep(10)
thread1.join()
Now, I find a way to resolve this problem.
django.db.close_old_connections()
when I try exception the error ' connection already close ' then I close old connections
the Django will reconnect.
But I still testing.
I installed MQTT broker Mosquitto on my pi and are having some problems getting it to work with boxes in my network. Locally, if I putty in to the RPi running the Mosquitto MQTT broker everything is OK. I can use the client commands (mosquitto_sub, mosquitto_pub) to subscribe and publish to topics, no problem. BUT, if I try to connect from another box, Win2k12 server with a python script it states it cant connect.
I've tried turning the firewall off in my router
I've tried turning the firewall off on my Win2k12 server
I've added TCP 1883 to allowed ports outbound from my Win2k12 server
The Python script:
import paho.mqtt.client as mqtt
def on_connect(client, userdata, flags, rc):
client.publish("test_mqtt", "test")
client.subscribe("test")
def on_disconnect(client, userdata, rc):
print("Disconnect, reason: " + str(rc))
print("Disconnect, reason: " + str(client))
client = mqtt.Client("testclient")
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.connect("192.168.1.20", 1883, 60)
client.loop_forever()
The output here is
Disconnect, reason: <paho.mqtt.client.Client object at 0x01F41EF0>
Disconnect, reason: 1
I've tried to have a look at the documentation but it only mentioned the flags, not defining what they are.
The raspberry pi that is running Mosquitto is also running Node-red. It has no problem connecting to the MQTT broker (both of them are running on the same rpi)
Has enyone set up MQTT on Raspberry Pi and got it to work with other devices? I want it to work with a NodeMCU thingy, but when I had problems I started working on a python script to further debug the problem.
You can force the paho client to use the 3.1 level of the protocol by adding an option to the mqtt.Client constuctor:
import paho.mqtt.client as mqtt
def on_connect(client, userdata, flags, rc):
client.publish("test_mqtt", "test")
client.subscribe("test")
def on_disconnect(client, userdata, rc):
print("Disconnect, reason: " + str(rc))
print("Disconnect, reason: " + str(client))
client = mqtt.Client("testclient", protocol=mqtt.MQTTv31)
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.connect("192.168.1.20", 1883, 60)
client.loop_forever()
First you have to make sure that you can connect to the Raspberry Pi. You can try using libraries other than Paho or using one MQTT client:
http://www.hivemq.com/blog/seven-best-mqtt-client-tools
The other thing you can try is setting both client and broker to use port 80 to see if they can communicate through that port.
I wrote a simple python program to connect RabbitMqtt server and hope to generate a queue and publish messages. However, after building the connection and creating a queue, the message was not published successfully (when I check the information of message, I cannot find any records and data). I wonder I miss some parameters or setting in client.publish(), but I do not know how to figure it out.
import paho.mqtt.client as mqtt
# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
print("Connected with result code " + str(rc))
# Subscribing in on_connect() means that if we lose the connection and
# reconnect then subscriptions will be renewed.
client.subscribe('SEEDQ')
client.publish('SEEDQ', 'deqwdqwefqwefwefqwefqwe', 0, False)
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
print(msg.topic + " " + str(msg.payload))
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.connect("15.78.xx.xx", 1883, 60)
client.loop_forever()
The problem is that you are calling client.publish() before the connection is complete. Move the client.publish into the on_connect function, AFTER client.subscribe('SEEDQ') and it will work.
# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
# Subscribing in on_connect() means that if we lose the connection and
# reconnect then subscriptions will be renewed.
# client.subscribe("$SYS/#")
client.subscribe('SEEDQ')
client.publish('SEEDQ', 111, 0, False)
Output:
Connected with result code 0
SEEDQ 111
FYI I used the public test server at iot.eclipse.org, port 1883.
FYI there is a very useful browser client HERE -using this and the public test server messagesight.demos.ibm.com port 1883 you can subscribe to SEEDQ and see your python script publish, and also using the browser client you can publish to SEEDQ from your browser and your script will display the message while it is in the loop_forever(). Obviously using these test servers is public visible.
UPDATE here is the complete code - this works against the public servers I show above.
import paho.mqtt.client as mqtt
# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
# Subscribing in on_connect() means that if we lose the connection and
# reconnect then subscriptions will be renewed.
# client.subscribe("$SYS/#")
client.subscribe('SEEDQ')
client.publish('SEEDQ', 111, 0, False)
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
print(msg.topic+" "+str(msg.payload))
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
#client.connect('15.xx.xx.xx', 1883, 60)
#client.connect("iot.eclipse.org", 1883, 60)
client.connect("messagesight.demos.ibm.com", 1883, 60)
#client.publish('SEEDQ', 111, 0, False)
# Blocking call that processes network traffic, dispatches callbacks and
# handles reconnecting.
# Other loop*() functions are available that give a threaded interface and a
# manual interface.
client.loop_forever()
Here is the code I'm running for my client. It works pretty well, but it doesn't allow python inputs to be made. I considered making another .py-file for typing and sending messages, but I'm not sure how to import the established connection.
Is it somehow possible to enable a python input chat using mqtt?
import paho.mqtt.client as mqtt
# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
print("Connected with result code "+str(rc))
# Subscribing in on_connect() means that if we lose the connection and
# reconnect then subscriptions will be renewed.
client.subscribe("hello/world")
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
print(msg.topic+"| "+ userdate + " said: "+str(msg.payload))
id = raw_input('username: ')
client = mqtt.Client(id)
client.on_connect = on_connect
client.on_message = on_message
client.connect_async("192.168.0.24", 1883, 60)
# Blocking call that processes network traffic, dispatches callbacks and
# handles reconnecting.
# Other loop*() functions are available that give a threaded interface and a
# manual interface.
client.loop_forever()