C# MQTT Class aanroepen await probleem

Pagina: 1
Acties:

Onderwerpen

Vraag


Acties:
  • 0 Henk 'm!

  • dreamer76
  • Registratie: Juli 2021
  • Laatst online: 29-10-2024
Ik ben hier nieuw op het forum en hoop dat ik hier goed zit om mijn vraag te stellen.

Ik heb in het verleden redelijk wat gedaan met PHP maar ben nu bezig met een projectje in C#.
Ik probeer een MQTT class uit te voeren in een bestaand project.
Het toevoegen van de .cs in het project gaat goed alleen nu wil ik dat de MQTT topic gestuurd wordt maar ik weet niet hoe/krijg foutmeldingen.
Als eerste hieronder de MQTT class die netjes in een apparte .cs staat.

code:
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
64
65
66
67
68
69
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Options;


namespace Test.Publisher
{
    public class Publisher
    {


        public static async Task Main(string[] args)
        {
            var mqttFactory = new MqttFactory();
            IMqttClient client = mqttFactory.CreateMqttClient();
            var options = new MqttClientOptionsBuilder()
            .WithClientId(Guid.NewGuid().ToString())
            .WithTcpServer("192.168.1.200", 1883)
            .WithCleanSession()
            .Build();

            client.UseConnectedHandler(e =>
            {
                Console.WriteLine("Connecterd to the broker succesfully");
            });

            client.UseDisconnectedHandler(e =>
            {
                Console.WriteLine("Disconnected from the  broker successfully");
            });

            await client.ConnectAsync(options);

            //Console.WriteLine("Please press a key to publish the message");

            //Console.ReadLine();

            await PublishmessageAsync(client);

            await client.DisconnectAsync();

        }

        public static void awesomeMethod()
        {
            throw new NotImplementedException();
        }

        public static async Task PublishmessageAsync(IMqttClient client)
        {
            string messagePayload = "Hello!";
            var message = new MqttApplicationMessageBuilder()
                .WithTopic("RishabhRharma")
                .WithPayload(messagePayload)
                .WithAtLeastOnceQoS()
                .Build();
            if (client.IsConnected)
            {
                await client.PublishAsync(message);

            }
        }
    }
}


Nu wil ik de client.PublisAsync(message);
Uit laten voeren in onderstaande script als if of else.
Maar ik weet niet precies hoe en als ik bij de if await client.PublishAsync(message);
probeer uit te voeren krijg ik de volgende melding.
The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task' vanuit Visual Studio

code:
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
  private void Completed(IAsyncResult ar)
        {



           

            Action completed = ar.AsyncState as Action;
              try
            {
          
 
        

                // Program.Log(PublishAsync(message));
                var result = new ZoneStat(this.Panel.EndSend(ar));


               
                
                
                
                if (GetZoneStat(result) == "False1")
                {
                   await client.PublishAsync(message);
                    Console.WriteLine("Good day.");

                }
                else
                {
                    Console.WriteLine("Good evening.");
                }



Ik gebruik visual studio
Helaas kan ik van de code waarin de de MQTT wil laten uitvoeren niet teveel laten zien omdat het om een SDK kit gaat waarvoor ik getekend heb dat deze niet zo openbaar mag worden.

Kan iemand mij hier iets verder mee helplen.
Aangezien dat ik nog niet zoveel met C# heb gedaan een beetje gemakkelijke uitleg :)

Alle reacties


Acties:
  • +1 Henk 'm!

  • Josk79
  • Registratie: September 2013
  • Laatst online: 18:38
Je zult even moeten zoeken naar 'c# async await', bijvoorbeeld: https://docs.microsoft.co...ing-guide/concepts/async/

Acties:
  • 0 Henk 'm!

  • dreamer76
  • Registratie: Juli 2021
  • Laatst online: 29-10-2024
Dankjewel voor de reactie.
Ben al wel een stukje verder.
Ik wil alleen de payload vullen met de waarde/string van result en dat lukt nog niet.
Ik kan nu wet een MQTT message versturen met de waarde die ik in mqtt.cs heb staan dus ben al wat verder.

Acties:
  • 0 Henk 'm!

  • dreamer76
  • Registratie: Juli 2021
  • Laatst online: 29-10-2024
Ik wil nu graag result1 door mqtt laten publishen.

code:
1
var result1 = new ZoneStat(this.Panel.EndSend(ar));

Alleen krijg ik de foutmelding result1 is not null here.
als ik onderstaande gebruik
Kan iemand mij vertellen hoe ik result1 kan laten publishen via mqtt
code:
1
2
3
4
5
6
7
8
9
10
11
string messagePayload = result1;
                var message = new MqttApplicationMessageBuilder()
                    .WithTopic("TOPIC")
                    .WithPayload(messagePayload)
                    .WithAtLeastOnceQoS()
                    .Build();
                if (client.IsConnected)
                {
                    await client.PublishAsync(message);

                }

[ Voor 3% gewijzigd door dreamer76 op 19-07-2022 13:10 ]


Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 10-07 11:07

Haan

dotnetter

Een foutmelding die zegt 'not null' lijkt me sowieso vreemd.

Ik zie dat result1 een object van type ZoneStat is, vervolgens wil je dat assignen aan de string messagePayload. Dat kan in theorie wel, maar erg gebruikelijk is dat niet. Ik gok dan ook dat daar het probleem zit.

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

  • Rensjuh
  • Registratie: Juli 2007
  • Laatst online: 22:41
code:
1
public static async Task PublishmessageAsync(IMqttClient client)


vs

code:
1
await client.PublishAsync(message);


Je functie word aangemaakt als PublishmessageAsync maar aangeroepen als PublishAsync.

PV Output


Acties:
  • +1 Henk 'm!

  • x86dev
  • Registratie: December 2012
  • Laatst online: 23-06 20:36
Rensjuh schreef op dinsdag 19 juli 2022 @ 14:27:
code:
1
public static async Task PublishmessageAsync(IMqttClient client)


vs

code:
1
await client.PublishAsync(message);


Je functie word aangemaakt als PublishmessageAsync maar aangeroepen als PublishAsync.
client.PublishAsync is in deze context aan aanroep richting de IMqttClient class.

@TS: Wellicht advies om Visual Studio 2022 Community te gebruiken, die geeft al vaak goeie fixes/aanwijzingen.

Acties:
  • 0 Henk 'm!

  • dreamer76
  • Registratie: Juli 2021
  • Laatst online: 29-10-2024
Oke dank voor de reacties.
Zoals Haan aangeeft zou het dus anders moeten.
Aangezien dat ik nog niet heel lang bezig ben met C# en ik momenteel alleen een MQTT bericht wil laten sturen wat er opgehaald wordt uit zonestat zou iemand mij dan kunnen vertellen hoe ik dit anders(beter) kan doen?
Visual Studio 2022 Community kijk ik ook zeker naar alleen ben ik zowel Visual Studio en de rest nog aan het leren.

.

Acties:
  • +1 Henk 'm!

  • P-Storm
  • Registratie: September 2006
  • Laatst online: 22:40
Het is voor ons heel erg glazen bol kijken wat je precies allemaal wilt doen.

Wat ik zie is iets over `this.Panel` , dat lijkt over Winforms te gaan. Verder snappen we dat je MQTT wilt gebruiken, maar de vraag is wat gaat er mis. Wat precies lukt je niet, en kan je de code in een klein projectje nabootsen waar het mis gaat? Door dit te doen heb je relevante code die voor ons na te spelen is.

Ook zie ik ergens in je code dat je gebruikt maakt van IAsyncResult: Dat wordt voor nieuwe code afgeraden.

Tenslotte lijk je een class of iets die richting in te gebruiken wat "ZoneStat" heet. Dit heeft geen hits op Nuget, dus ik ga ervan uit dat dit onderdeel van je NDA is of iets wat je zelf hebt gemaakt. De reden hiervoor dat dit niet wensenlijk is lijkt @Haan uit te leggen.

Mijn advies wat ook @x86dev aangeeft, gebruik je IDE om de fouten te snappen. Wanneer de code een exception gooit, en je die niet snapt, deel dan heel deze foutmelding. Zelf adviseer ik ook altijd om de beginner guide voor debugging door te nemen

Voor de foutmelding, een blinde gok: Je gebruikt dotnet 6 waar nullable standaard op true staat in je .csproj file en de waarde van een string niet null mag bevatten

Probeer het op te knippen in kleine deelproblemen. Kan je aangeven wat al wel lukt en wat niet. Bijvoorbeeld:
  1. Het lukt mij om een connectie te maken met de de MQTT server.
  2. Het lukt mij om een statisch bericht op de MQTT server te zetten.
  3. Het lukt mij niet om een bericht met een variabele erin te zetten.
  4. Het lukt mij niet om op een bericht te subscriben waardoor ik berichten kan inlezen.
En bij de delen waar het niet lukt, wat lukt er niet, krijg je een foutmelding, komt hij niet als logica daar of wat anders?

offtopic:
Het is wellicht veel meer dan je vraagt, maar door naar deze aspecten te kijken kan je zelf beter vinden wat je moet doen, en als je tegen fouten aanloopt kunnen wij precieser helpen. Zie het dan ook vooral als positieve feedback :)

Acties:
  • 0 Henk 'm!

  • dreamer76
  • Registratie: Juli 2021
  • Laatst online: 29-10-2024
Dank weer voor de reactie.

Het lukt mij om een connectie te maken met de de MQTT server.
Het lukt mij om een statisch bericht op de MQTT server te zetten.
Dit bovenste lukt allemaal ik heb de code die bovenaan in mijn topic staat van het net afgehaald.
Als ik statisch in messagePayload b.v. "Hello" zet zoals hieronder dan kan ik deze naar de mqtt servert sturen en ook zien met b.v. mqtt explorer.
code:
1
2
3
4
5
6
string messagePayload = "Hello!";
            var message = new MqttApplicationMessageBuilder()
                .WithTopic("RishabhRharma")
                .WithPayload(messagePayload)
                .WithAtLeastOnceQoS()
                .Build();

Het lukt mij niet om een bericht met een variabele erin te zetten.zoals hieronder b.v. result1
code:
1
var result1 = new ZoneStat(this.Panel.EndSend(ar));

Ik krijg dan een foutmelding zoals op de afbeelding die ik probeer toe te voegen.
Het lukt mij niet om op een bericht te subscriben waardoor ik berichten kan inlezen.

Afbeeldingslocatie: https://tweakers.net/i/i_Bebhr_psUQQhU4YyulaovRvVQ=/800x/filters:strip_exif()/f/image/EU3sKP0Ldtk9OlaCZaKNKnrc.png?f=fotoalbum_large

Acties:
  • 0 Henk 'm!

  • P-Storm
  • Registratie: September 2006
  • Laatst online: 22:40
De regel met CS1503 geeft hier de fout aan. Dit is een link waar je ook op kan klikken. (of zoek de fout op in Google)

Om je te helpen, dit gaat om datatypes. De with payload regel verwacht een byte[] (en vermoedelijk heeft het een overload voor een string). Je stopt een type ZoneStat erin, en daar zit het punt.

Aangezien wij de type ZoneStat niet kennen, is hier een stuk wat je zult moeten uitzoeken. Succes!

Acties:
  • 0 Henk 'm!

  • dreamer76
  • Registratie: Juli 2021
  • Laatst online: 29-10-2024
P-Storm

Dankjewel weer voor de reactie.
Ik had idd wel iets gevonden over byte dus ga hier even verder naar zoeken/kijken.
Helaas gaat het om een SDK (voorbeeld) waarin ik iets wil verzenden via mqtt waarvoor wij een agreement hebben moeten tekenen vandaar dat ik niet de volledige code kan poosten.

Acties:
  • 0 Henk 'm!

  • P-Storm
  • Registratie: September 2006
  • Laatst online: 22:40
dreamer76 schreef op dinsdag 19 juli 2022 @ 19:37:
Dank weer voor de reactie.
...
Als ik statisch in messagePayload b.v. "Hello" zet zoals hieronder dan kan ik deze naar de mqtt servert sturen en ook zien met b.v. mqtt explorer.
code:
1
2
3
4
5
6
string messagePayload = "Hello!";
            var message = new MqttApplicationMessageBuilder()
                .WithTopic("RishabhRharma")
                .WithPayload(messagePayload)
                .WithAtLeastOnceQoS()
                .Build();

Het lukt mij niet om een bericht met een variabele erin te zetten.zoals hieronder b.v. result1
code:
1
var result1 = new ZoneStat(this.Panel.EndSend(ar));
C# is een type strict language. Om een stukje duidelijker te zijn, je payload die je wilt sturen is van de type string (byte[] kan ook maar laten we even buiten beschouwing).

code:
1
2
3
4
String a = "pietje puk";
var b = "pietje puk";
String c = a;
String d =b;


Var is dus implicit typed string. Een string is een text representatie, en var kijkt naar wat het zou moeten zijn. Visual Studio laat het ook zien als je met je muis erboven hangt.

Nu probeer je hetvolgende (iets anders dan precies jou oplossing.

code:
1
2
3
var a = 1;
int b =a;
String message = a; //error op deze lijn


De reden is dat a van het type int is, en dotnet niet weet hoe je dit naar een string om moet zetten. Dit voorbeeld kan je oplossen door .ToString() te gebruiken (want dit geeft een type string, kijk als je dit intoetst naar wat Visual Studio je verteld.

Nu heb je een class (of een struct) van het type ZoneStat. Nu wil je hiervan een string hiervan hebben, maar wat vraag je aan de code? Wil je "ZoneStat" hebben? Wil je hier een waarde uit halen? Wil je hiervan een xml of yml of json van hebben? Dit kunnen we niet invullen voor je, omdat je niets verder (kan) vertellen over de ZoneStat.

Kortom, een string vraagt om een string, een ZoneStat is geen string, maar heeft wellicht eigenschappen die een string zijn. Zie 'https://www.w3schools.com/cs/cs_classes.php' (of andere voorbeelden wat een class is).

Weer mijn glazen bol, maar ik vermoed dat je iets van serialization wilt hebben, maar dat wordt niet in je verhaal duidelijk.

Nu nog het deel van string vs string?. In c# bestaat het concept van 'null'. Dit is een waarde dat eigenlijk 'niets' voor moet stellen. Doordat hoe je project (vermoedelijk, zie mijn vorige post) is opgesteld is dat wanneer je string gebruikt impliciet een not null die hij verwacht.

Acties:
  • 0 Henk 'm!

  • dreamer76
  • Registratie: Juli 2021
  • Laatst online: 29-10-2024
Oke ik ging er dus al vanuit dat ik met een string werkte en deze bij messagePayload kon gebruiken omdat
er bij GetZoneStat volgens mij al een string aangemaakt wordt.


code:
1
2
3
4
5
6
7
8
9
10
11
internal static string GetZoneStat(ZoneStat info)

        {
            return new StringBuilder()

                .AppendFormat("{0}", info.Xxxxx)
                .AppendFormat("{0}", info.Yyyyy)

   
                .ToString();
                  }

Hierboven een stukje code voor
code:
1
var result1 = new ZoneStat(this.Panel.EndSend(ar));

Acties:
  • 0 Henk 'm!

  • P-Storm
  • Registratie: September 2006
  • Laatst online: 22:40
Ik denk dat je bijna de puzzelstukjes bij elkaar hebt als ik het zo zie. Je hebt nu de type ZoneStat, en moet die door middel van de functie die je getoont hebt in een string laten veranderen. Heb je nu nog een concrete vraag?

offtopic:
Zoals je nu AppensFormat gebruikt zou je net zo goed Append kunnen gebruiken, maar wellicht dat je daar nog meer doet
Pagina: 1