Laden...

MQTT Subscriber: wie gehe ich vor, wenn ich mehrere Topics abonnieren will?

Erstellt von scoobidoobi vor 4 Jahren Letzter Beitrag vor 4 Jahren 3.288 Views
S
scoobidoobi Themenstarter:in
7 Beiträge seit 2019
vor 4 Jahren
MQTT Subscriber: wie gehe ich vor, wenn ich mehrere Topics abonnieren will?

Hallo zusammen,

ich bin noch relativ neu auf dem MQTT Gebiet und hätte da ein paar Fragen.

Ich habe einen MQTT Subscriber in WinForm geschrieben und es funktioniert soweit ganz gut. Aber eines verstehe ich noch nicht ganz: wie gehe ich vor, wenn ich mehrere Topics abbonieren will?
Z.B: Topic2 soll in Textbox3 geschrieben werden.
ich habe schon einiges probiert aber alles ohne Erfolg.
Hat zufällig jemand eine Idee?

Hier mein bisheriger Ansatz


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using uPLibrary.Networking.M2Mqtt;
using uPLibrary.Networking.M2Mqtt.Messages;


namespace MQTT_002
{
    public partial class Form1 : Form
    {
        MqttClient client;
        
        string clientId;
        

        public Form1()
        {
            InitializeComponent();

            string BrokerAddress = "10.14.9.114";

            client = new MqttClient(BrokerAddress);
            
            client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;
            
            clientId = Guid.NewGuid().ToString();
            
            client.Connect(clientId);            
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string Topic = "WO3/KmSollE1";
            string Topic2 = "WO3/KmSollE2";

            // in Textbox schreiben
            client.Subscribe(new string[] { Topic }, new byte[] { 0 });   
            textBox2.Text = "";
            
        }
        
        private void button1_Click(object sender, EventArgs e)
        {
            client.Disconnect();
        }

        private void client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
        {
            string ReceivedMessage = Encoding.UTF8.GetString(e.Message);
          
            {

                textBox2.Invoke((MethodInvoker)delegate
                {              
                    textBox2.Text = ReceivedMessage;
                });
            }
        }
    }

}

Wäre für jeden Vorschlag sehr dankbar!

709 Beiträge seit 2008
vor 4 Jahren

Hallo und willkommen scoobidoobi,

bei der Behandlung der empfangenen Nachricht kannst du das Topic auslesen und anhand dessen die TextBox zum Hineinschreiben der Nachricht wählen.

S
scoobidoobi Themenstarter:in
7 Beiträge seit 2019
vor 4 Jahren

Hallo pinki,

danke für die schnelle Antwort. Ich abe mich leider etwas zu undeutlich ausgedrückt. Ich meinte
Topic = "WO3/KmSollE1" -> Ihnalt der Nachricht steht in TextBox2 (z.B: 1234). Wie bekomme ich das hin den Inhalt von Topic2 = "WO3/KmSollE2" in TextBox3 zu schreiben?

709 Beiträge seit 2008
vor 4 Jahren

Du schaust, wenn eine neue Nachricht empfangen wurde, an welches Topic diese gesendet wurde.
Ist das Topic "WO3/KmSollE1", dann schreibst du den Inhalt in textBox2, ist das Topic "WO3/KmSollE2", dann schreibst du es in textBox3.

Das Topic gibt's als eigene Eigenschaft in den Ereignisargumenten.

S
scoobidoobi Themenstarter:in
7 Beiträge seit 2019
vor 4 Jahren

Ja das Verstehe ich. Aber wenn ich das so versuche dann steht erst der wert von Topic für 0,2sec in beiden Textboxen und dann sofort der Wert von Topic2.
Was mache ich da falsch?
hast Du vielleicht mal einen Ansatz wie ich vorgehen müsste?

709 Beiträge seit 2008
vor 4 Jahren

Wie hast du es denn bisher versucht?

S
scoobidoobi Themenstarter:in
7 Beiträge seit 2019
vor 4 Jahren

Ich stelle es morgen rein, da ich jetzt der Rechner nicht dabei habe.

S
scoobidoobi Themenstarter:in
7 Beiträge seit 2019
vor 4 Jahren

Hallo,

hier ist mein letzter Versuch.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using uPLibrary.Networking.M2Mqtt;
using uPLibrary.Networking.M2Mqtt.Messages;


namespace MQTT_002
{
    public partial class Form1 : Form
    {
        MqttClient client;
        
        string clientId;
        

        public Form1()
        {
            InitializeComponent();

            string BrokerAddress = "10.14.9.114";

            client = new MqttClient(BrokerAddress);
            
            client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;
            
            clientId = Guid.NewGuid().ToString();
            
            client.Connect(clientId);            
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string Topic = "WO3/KmSollE1";
            string Topic2 = "WO3/KmSollE2";

            // in Textbox schreiben
            client.Subscribe(new string[] { Topic, Topic2 }, new byte[] { 2, 2 });   
            textBox2.Text = "";
            textBox3.Text = "";
        }
        
        private void button1_Click(object sender, EventArgs e)
        {
            client.Disconnect();
        }

        private void client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
        {
            string ReceivedMessage = Encoding.UTF8.GetString(e.Message);
          
            {
                textBox2.Invoke((MethodInvoker)delegate
                {              
                    textBox2.Text = ReceivedMessage;
                });
            }

            string ReceivedMessage2 = Encoding.UTF8.GetString(e.Message);

            {
                textBox3.Invoke((MethodInvoker)delegate
                {
                    textBox3.Text = ReceivedMessage2;
                });
            }

        }
    }

}


709 Beiträge seit 2008
vor 4 Jahren

Hallo scoobidoobi,

du schreibst die empfangene Nachricht jedes Mal in beide TextBoxen.

client_MqttMsgPublishReceived wird jedes Mal aufgerufen, wenn eine Nachricht zu einem abonnierten Topic empfangen wurde. Der Übergabeparameter e enthält dabei die Details zu den empfangenen Daten (genauer Aufbau siehe hier).

Im Moment wandelst du den Inhalt der empfangenen Nachricht zu einem String und schreibst diesen in textBox2. Danach wandelst du den Inhalt der selben empfangenen Nachricht erneut zu einem String (unnötig, weil das hast du ja bereits gemacht) und schreibst ihn in textBox3.

Was dir fehlt, ist dass du dir das Topic der empfangenen Nachricht ansiehst und anhand des Topics entscheidest, in welche TextBox dein String geschrieben werden soll. Das Topic steht in den Ereignisargumenten (siehe Link von oben).

S
scoobidoobi Themenstarter:in
7 Beiträge seit 2019
vor 4 Jahren

Hi, habe vieles probiert aber ich kapiere das irgendwie nicht. Der Knoten in meinem Kopf ist zu groß. Hast du noch einen Ansatz wie ich das angehen soll?

1.029 Beiträge seit 2010
vor 4 Jahren

Hi,

ich hab zwar noch nie mit MQTT gearbeitet - allerdings hat pinki dir alles geliefert was es braucht...

Du erhälst innerhalb von "client_MqttMsgPublishReceived" das Argument "MqttMsgPublishEventArgs e", wobei e neben der Message eben auch noch ein Topic hat. (unter Anderem)

Je nachdem welches Topic - musst du doch jetzt nur noch per switch oder if oder oder oder die richtige Textbox aussuchen.

LG

16.806 Beiträge seit 2008
vor 4 Jahren

I.d.R. sollte man pro Subscription einen Listener erstellen, auf den man reagieren kann.
Das gilt allgemein für das Messaging; egal ob AMQP oder MQTT oder... macht den Umgang einfach um Welten einfacher.

Ich geh davon aus, dass der zu sehende Code einfach nur Wegwerf-Code darstellt;
trotzdem auch hier der Hinweis auf [Artikel] Drei-Schichten-Architektur

Sofern Messages in einer Desktop-UI angezeigt werden soll (egal ob WPF, WinForms..) lässt sich das super via Reactive Extensions kombinieren.

S
scoobidoobi Themenstarter:in
7 Beiträge seit 2019
vor 4 Jahren

Ja jetzt hab ich's auch mal gecheckt.

Vielen Dank an Alle vorallem an Pinki !!!