4

私は Mosquitto と Paho の Python 実装を使用して、いくつかのプログラムを通信しようとしています。最後の意志機能を使用すると、いくつかの問題が発生します。私のコードはこれです:

加入者:

import paho.mqtt.client as mqtt
def on_message(client, userdata, msg):
    print 'Received: ' + msg.payload

client = mqtt.Client()
client.on_message = on_message

client.connect('localhost', 1883)
client.subscribe('hello/#')

client.loop_forever()

出版社:

import paho.mqtt.client as mqtt

client = mqtt.Client()

client.will_set('hello/will', 'Last will', 0, False)
client.connect('localhost', 1883)

client.publish('hello/world', 'Regular msg', 0, False)
client.disconnect()

出力:

Received: Last will

client.disconnect()接続を閉じるために使用するため、通常のメッセージのみを受信する必要があります。行にコメントするwill_setと、通常のメッセージが表示されます。また、同じトピックで両方を公開しようとしましたが、うまくいきません。

4

3 に答える 3

11

MQTT を最後に設定する方法は、適切にメッセージを送信します

最後の遺言機能は、いくつかの規則に従う必要があります。

client.will_set接続する前に電話する

will_setの前に呼び出しを置きますclient.connect

client = mqtt.Client()
client.will_set("stack/clientstatus", "LOST_CONNECTION", 0, False)
client.connect(host, port, timeout)

接続後の呼び出しwill_setはうまくいきませんでした。

最後のclient.will_setカウントのみ

複数回使用することwill_setは可能ですが、最後の 1 つだけが有効で、前のものは無視されます。

client.disconnect完成させます

これclient.disconnectは、実際には「DISCONNECT」メッセージをブローカーに送信するための要求です。

メッセージは非同期で送信されるため、プログラムがより早く終了し、「DISCONNECT」メッセージが完了する可能性があります。

Use client.loop_*()afterclient.disconnect これにより、クライアントは「DISCONNECT」メッセージを送信するプロセスを完了できます。

次の組み合わせが私のために働いた:

  • loop_start()->loop_stop()
  • loop_start()loop_forever()(DISCONNECTメッセージ送信後完了)

他の組み合わせは試していません。

これらのオプションから、最初のオプションの方が優れているように思えます (loop_startとペアを維持しますloop_stop)。2 番目のオプションは単に間違っている可能性があります。

私の作業コード:

import paho.mqtt.client as mqtt

host = "test.mosquitto.org"
port = 1883
timeout = 10

client = mqtt.Client()
client.will_set("stack/clientstatus", "LOST_CONNECTION", 0, False)
client.connect(host, port, timeout)

client.publish("stack/clientstatus", "ON-LINE")

client.loop_start()
for msg in ["msg1", "msg2", "msg3"]:
    client.publish("stack/message", msg)
    print msg

client.publish("stack/clientstatus", "OFF-LINE")
client.disconnect()
client.loop_stop()  # waits, until DISCONNECT message is sent out
print "Now I am done."

信頼できない方法 ( sleep、追加on_disconnect)

追加time.sleepすると役立つ場合がありますが、他の状況 (信頼できない接続) では失敗する可能性があります。

私の場合、追加client.on_disconnect = on_disconnectしても役に立たなかったようです。このコールバックは非同期で処理され、client.disconnect呼び出しをブロックしません。

于 2016-01-10T18:59:13.253 に答える
3

disconnect()ブローカーにコマンドを送信する必要DISCONNECTがあります。これが、ブローカーが意志を送信しないことを知る方法です。電話をかけただけdisconnect()では、これが起こったという保証はありません。loop*()発信ネットワーク トラフィックを処理するには、呼び出す必要があります。on_disconnect()呼び出されているコールバックをチェックすることで、DISCONNECT メッセージが送信されたことを確認できます。呼び出すこともできますがloop_forever()、その後disconnect()は同じように機能します。

import paho.mqtt.client as mqtt

client = mqtt.Client()

client.will_set('hello/will', 'Last will', 0, False)
client.connect('localhost', 1883)

client.publish('hello/world', 'Regular msg', 0, False)
client.disconnect()
client.loop_forever()

またはpaho.mqtt.publish.single()@hardillbが示唆するように使用してください。

于 2015-02-20T16:57:55.007 に答える
2

次のように、単一の方法を使用して、メッセージを 1 つだけ発行してみることができます。

import paho.mqtt.publish as publish

publish.single('hello/world', 'Regular msg', 0, False, 'localhost' , 1883, 'publisher', 10, {'topic': 'hello/will', 'payload': 'Will msg', 'qos': 0, 'retain': False})

https://pypi.python.org/pypi/paho-mqtt#single

問題は、公開が実際に完了する前に切断していることだと思います。これが、意志メッセージが表示されている理由かもしれません。

編集 - mosquitto_sub -v -t 'hello/#' でコードを実行すると、通常のメッセージと配信されるメッセージの両方が表示されます。

EDIT2 -

これは私にとってはうまくいきます:

import paho.mqtt.client as mqtt

client = mqtt.Client()

client.will_set('hello/will', 'Last will', 0, False)
client.connect('localhost', 1883)

client.publish('hello/world', 'Regular msg', 0, False)
client.loop();
client.disconnect()
client.loop();
于 2015-02-19T22:21:20.917 に答える