Entwickler-Ecke

Netzwerk - MQTT Mosquitto SUBSCRIBER


GoofiGoofi - Fr 15.02.19 19:13
Titel: MQTT Mosquitto SUBSCRIBER
Hallo zusammen,

vorerst muss ich sagen, dass ich mich auf dem Gebiet MQTT nicht besonders gut auskenne.

Mein Problem ist ich möchte von einem Mosquitto Broker einen string empfangen und diesen an einen label.text übergeben.

Kann mir bitte jemand sagen was ich falsch mache oder was ich übersehen habe? Oder ist das vielleicht ein komplett falscher Ansatz?

Ich bin für jeden Vorschlag sehr dankbar!

Das ist meine bisherige Vorgehensweise:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
public partial class Form1 : Form
{
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // create client instance

            MqttClient client = new MqttClient("10.14.9.205");

            // register to message received

            client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;

            string clientId = Guid.NewGuid().ToString();

            client.Connect(clientId);

            // subscribe to the topic "/home/temperature" with QoS 2

            client.Subscribe(new string[] { "/home/temperature" }, new byte[] { MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE });

            label1.Text = clientId;
        }

        static void client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
        {
            // handle message received
        }
    }
}


Moderiert von user profile iconTh69: C#-Tags hinzugefügt


Th69 - Fr 15.02.19 19:36

Hallo und :welcome:,

könntest du bitte deinen Beitrag nochmal editieren und den Code in passende C#-Tags packen?

Unter MQTT Client [https://gist.github.com/cwschroeder/7b5117dca561c01def041e7d4c6d2771] gibt es Beispielcode dafür.
Für WinForms beachte den letzten Kommentar von "MarkJoel60" bzgl. Control.Invoke.


Ralf Jansen - Fr 15.02.19 20:57

Die MqttClient Instanz an einer lokalen Variablen zu halten ist sicher keine gute Idee. Nach dem Ende der Form1_Load Methode wird die Instanz dereferenziert und wird an die Garbage Collection übergeben. Die wird also zu einem undefinierten Zeitpunkt danach ohne dein weiteres zutun zerstört. Die Variable sollte eine Klassenvariable sein. Wie übrigens auch in dem verlinkten Beispiel von user profile iconTh69 gezeigt.

Den EventHandler client_MqttMsgPublishReceived statisch zu machen ist auch eher ungewöhnlich. Wenn du das schon in einer Form machst willst du bestimmt auch aus dem EventHandler auf die Form zugreifen können.


Und bitte kein Crossposting [https://entwickler-forum.de/forum/net-und-windows/c/432443-mqtt-mosquitto-subscriber]. Zumindest nicht heimlich.


GoofiGoofi - Fr 15.02.19 22:24

Vielen Dank für den Tip!
Wie schon gesagt ist das alles NOCH Neuland für mich.
Wie meinst du das „den EventHandler client_MqttMsgPublishReceived statisch zu machen„, wie muss ich da vorgehen? Funktioniert das so nicht auch?

Moderiert von user profile iconTh69: C#-Tags hinzugefügt


Ralf Jansen - Sa 16.02.19 12:35

Im Moment hast du client_MqttMsgPublishReceived mit dem static [https://docs.microsoft.com/de-de/dotnet/csharp/language-reference/keywords/static] Schlüsselwort markiert. Damit gehört der EventHandler nicht mehr zu einer bestimmten Instanz der Form1 Klasse und hat damit keinen Zugriff mehr auf die Instanzdaten. Zum Beispiel das Label in das du was schreiben möchtest ist Teil einer Instanz der Form1 Klasse und aus einer statischen Methode der Klasse nicht erreichbar.


GoofiGoofi - So 17.02.19 17:14

Hallo zusammen,

vielen Dank erst mal für euere Unterstütztung.
Ich bin dem Beispielcode gefolgt, habe aber immer noch ein Problem.
Wenn ich clientId an eine Ausgabe Variable (txtReceived.Text) übergebe bekomme ich nur wirres Zeug raus in etwa so "ft5456e-ezd5-465f-647ztee"
Was mache ich falsch?

hier mein neuer Code:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
public partial class MainWindow : Window
    {
        MqttClient client;
        string clientId;

        public MainWindow()
        {
            InitializeComponent();

            string BrokerAddress = "10.14.9.205";

            client = new MqttClient(BrokerAddress);

            // register a callback-function (we have to implement, see below) which is called by the library when a message was received
            client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;

            // use a unique id as client id, each time we start the application
            clientId = Guid.NewGuid().ToString();

            client.Connect(clientId);
            //txtTopicSubscribe.Text = clientId;

        }
        // this code runs when a message was received
        void client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
        {
            string ReceivedMessage = Encoding.UTF8.GetString(e.Message);

            Dispatcher.Invoke(delegate {              // we need this construction because the receiving code in the library and the UI with textbox run on different threads
                txtReceived.Text = ReceivedMessage;
                
            });

        }
        protected override void OnClosed(EventArgs e)

        {
            client.Disconnect();
            base.OnClosed(e);
            App.Current.Shutdown();
        }
        

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (txtTopicSubscribe.Text != "")
            {
                // whole topic

                string Topic = "/ElektorMyJourneyIoT/" + txtTopicSubscribe.Text + "/test";

                // subscribe to the topic with QoS 2
                client.Subscribe(new string[] { Topic }, new byte[] { 2 });      // we need arrays as parameters because we can subscribe to different topics with one call
                txtReceived.Text = clientId;
               
            }
            else
            {
                System.Windows.MessageBox.Show("You have to enter a topic to subscribe!");
            }          
        }
    }
}


Ralf Jansen - So 17.02.19 17:23

Zitat:
Wenn ich clientId an eine Ausgabe Variable (txtReceived.Text) übergebe bekomme ich nur wirres Zeug raus in etwa so "ft5456e-ezd5-465f-647ztee"
Was mache ich falsch?


Nichts du hast eine GUID in clientID reingeschrieben und so sieht halt eine GUID in Textdarstellung aus.


GoofiGoofi - So 17.02.19 17:39

Ok dann habe ich die Frage falsch gestellt.
Wo sehe ich den string den ich empfangen möchte? (Subscriber)


Ralf Jansen - So 17.02.19 17:48

Voraussichtlich irgendwas aus den MqttMsgPublishEventArgs.

Im Moment zeigst du irgendwas in txtReceived aus diesen EventArgs an. Aber ob Message was relevantes ist oder etwas anderes aus den EventArgs wichtig ist solltest du dir aus der Doku anlesen. Vielleicht solltest du auch einfach mal deinen Code debuggen? Setze einen Breakpoint in deinen Received Event und schau dir im Deugger an was da alles in den EventArgs steckt wenn der Code aufgerufen wird.