2016-04-05 12 views
2

Ich habe ein einfaches Skript auf einem Raspberry Pi, die eine Beispielnachricht alle 3 Sekunden veröffentlicht. Ich habe die Callbacks on_connect, on_publish und on_disconnect deklariert. Dieser Client verbindet sich erfolgreich, aber on_connect wird nicht aufgerufen, publishs und on_publish wird aufgerufen, trennt und on_disconnect wird aufgerufen.Paho Python MQTT-Client verbindet erfolgreich, aber on_connect Callback wird nicht aufgerufen

Das ist mein Skript

import paho.mqtt.client as mqtt 
import time 

def on_connect(mqttc, userdata, rc): 
    print("Connected with result code "+str(rc)) 
    if rc!=0 : 
     mqttc.reconnect() 

def on_publish(mqttc, userdata, mid): 
    print "Published" 

def on_disconnect(mqttc, userdata, rc): 
    if rc != 0: 
     print("Unexpected disconnection. Reconnecting...") 
     mqttc.reconnect() 
    else : 
     print "Disconnected successfully" 

# Setup MQTT 
# broker='test.mosquitto.org' 
broker = 'iot.eclipse.org' 
broker_port=1883 

# Create a client instance 
mqttc=mqtt.Client(client_id="MyClient") 
mqttc.on_connect = on_connect 
mqttc.on_publish = on_publish 
mqttc.on_disconnect = on_disconnect 

while 1: 

    mqttc.connect(broker, broker_port, 60) 
    # print "Connected." # I don't want this message. 
          # Why isn't the on_connect callback invoked? 

    try: 
     topic = "this/is/a/test/topic" 
     payload = "test_message" 
     print "Publishing " + payload + " to topic: " + topic + " ..." 
     mqttc.publish(topic, payload, 0) 

    except Exception as e: 
     print "exception" 
     log_file=open("log.txt","w") 
     log_file.write(str(time.time())+" "+e.__str__()) 
     log_file.close() 

    mqttc.disconnect() 
    print "" 
    time.sleep(3) 

Obwohl diese kleinen „Fehler“ die Nachricht nicht Verlag beeinflussen, was in erster Linie ist das, was ich erreichen will, warum es passiert und wie kann ich es beheben?

Antwort

3

Der Grund, warum dies nicht funktioniert, ist, dass Sie keine der loop*() Funktionen aufrufen. Diese verarbeiten Netzwerkverkehr. Wenn Sie keines verwenden, gibt es keine Garantie, dass Ihre ausgehenden Nachrichten gesendet werden und absolut keine eingehenden Nachrichten verarbeitet werden.

loop_forever() ist ein blockierender Anruf, der die Netzwerkschleife verarbeitet - wahrscheinlich nicht das, was Sie wollen.

loop_start() startet einen Thread zur Verarbeitung der Netzwerkschleife und kehrt so sofort zurück.

Ich würde dies tun:

mqttc.connect(broker, broker_port, 60) # Don't forget to handle errors 
mqttc.loop_start() 

while 1: 
    try: 
     topic = "this/is/a/test/topic" 
     payload = "test_message" 
     print "Publishing " + payload + " to topic: " + topic + " ..." 
     mqttc.publish(topic, payload, 0) 

    except Exception as e: 
     print "exception" 
     log_file=open("log.txt","w") 
     log_file.write(str(time.time())+" "+e.__str__()) 
     log_file.close() 

    print "" 
    time.sleep(3) 

Sie müssen noch Ihre on_connect Rückruf beheben, wie @Kiran sagt.

Es ist nicht notwendig, jedes Mal zu trennen - und tatsächlich gibt es keine Garantie, dass Ihre Nachricht gesendet wurde, wenn Sie die Verbindung trennen. Sie sollten den Rückruf on_publish verwenden, um zu wissen, wann die Nachricht gesendet wird.

Wenn Sie einen einfachen connect-publish-disconnect tun wollen, dann verwenden Sie vielleicht den paho.mqtt.publish Helfer-Modul:

import paho.mqtt.publish as publish 

while 1: 
    try: 
     topic = "this/is/a/test/topic" 
     payload = "test_message" 
     print "Publishing " + payload + " to topic: " + topic + " ..." 
     publish.single(topic, payload, 0, host=broker, port=broker_port) 

    except Exception as e: 
     print "exception" 
     log_file=open("log.txt","w") 
     log_file.write(str(time.time())+" "+e.__str__()) 
     log_file.close() 

    print "" 
    time.sleep(3) 
1

In Ihrer on_connect() Methodendeklaration fehlen die Flags (1) Parameter. Es wird also nicht aufgerufen. Der Flags-Parameter enthielt die vom Broker gesendete Antwort. Es musste sein

def on_connect(mqttc, userdata, flags, rc): 

Auch, warum verbinden und trennen Sie in Schleife? Versuchen Sie es mit den Methoden loop_start() und loop_stop(), die automatische Reconnections bei Verbindungsabbruch behandeln (example).

+0

Der Makler, die ich bin derzeit mit (nicht mit dem im Beispiel) kann maximal handhaben Anzahl der angeschlossenen Clients. Da es mehr Clients gibt, die Daten periodisch senden, besteht die Logik hinter connect-send-disconnect darin, mehr von ihnen mit dem Broker verbunden zu lassen. – evgi9

+0

@ evgi9 Dazu können Sie auch globale Hilfsfunktionen verwenden ([1] (https://pypi.python.org/pypi/paho-mqtt/1.1#single)) – Kiran

Verwandte Themen