Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Tobiking

1x Rätselkönig

  • Private Nachricht senden

21

15.07.2014, 05:49

Vom Prinzip wie unter https://developers.google.com/protocol-b…ocs/proto#other.

Quellcode

1
2
3
4
5
6
7
8
message PersonDatensatz {
  required MessageHeader header = 1;
  // Person Daten
}

message MessageHeader{
  required int32 id = 1;
}


Und damit du nicht jedes mal MessageHeader neu definieren musst, kommt das in eine extra Datei und wird per import (direkt der nächste Abschnitt in dem Link oben) eingebunden. Hat auch den schönen Vorteil, dass wenn du irgendwann vielleicht einen Timestamp im Header haben möchtest, dies nur eine Änderung bedarf und damit alle Nachrichten betrifft.

ERROR

Alter Hase

  • »ERROR« ist der Autor dieses Themas

Beiträge: 417

Wohnort: Paderborn

Beruf: Informatik Student

  • Private Nachricht senden

22

20.07.2014, 01:27

Ich stehe jetzt irgendwie ziemlich auf dem Schlauch. Ich habe hinbekommen, dass beides super kommuniziert und alles klappt, bis auf das mit den Headern.
Wenn eine Nachricht ankommt, weiss ich ja noch nicht welchen Typ sie hat. Allerdings muss ich sie ja erstmal irgendwie speichern, bevor ich den Header auslesen kann. Ich würde gerne eine Function haben, welche den String (Also die Nachricht) übergeben bekommt und daraus die ProtobufMessage macht. Aber als Return Value kann ich ja keinen genauen Typ nehmen, da ich noch nicht weiss welcher es ist.

Geht das überhapt? Wenn ja wie?
Antwort in C# und /oder C++ wäre super :)

Toemsel

Treue Seele

Beiträge: 310

Wohnort: OÖ

Beruf: Student und Programmierer

  • Private Nachricht senden

23

20.07.2014, 02:26

Ich kenn die Lib nicht, vielleicht hilft dir jedoch dieser Ansatz.

Damit du weißt welches Paket (Typ) ankommt, sollte ein Teil des Headers das Paket beschreiben. (1 Byte, 2 Byte,.. je nach Gesamtpaket Anzahl)
Wenn du diese Bytes ausgelesen hast, weißt du welches Paket die folgenden Daten (Bytestream) erhält.
Das ganze kannst du einfach mit einem if, else, switch, case lösen. Oder elegant mit Reflection. (C#)
Jedes "Paket" wird durch eine Klasse dargestellt. Jede Klasse erhält ein Klassenattribut mit dem Pakettyp.
(Damit per Reflection während der Laufzeit alle KlassenAttribute mit dem Pakettyp verglichen werden können. Anschließend wird automatisch die richtige Klasseninstanz geliefert)
Durch eine Vererbungsstruktur z.B Message -> RequestPacket -> Packet können Methoden wie "ReadPacket" und "WritePacket" verallgemeinert und im Sohn "Message" realisiert werden.

Ich hoffe ich konnte mich verständlich ausdrücken und dir weiterhelfen :rolleyes:

Tobiking

1x Rätselkönig

  • Private Nachricht senden

24

20.07.2014, 04:34

Ah, jetzt versteh ich das Problem. Protobuf gibt natürlich immer nur einen festen Typ zurück. Du brauchst dann eine Wrapper Message, die entsprechend die anderen Messages enthalten kann. Siehe https://developers.google.com/protocol-b…echniques#union

Ist vom Prinzip her das was Toemsel beschrieben hat, nur in die Protobuf Message integriert. Der im letzten Satz beschriebene Ansatz über ListFields könnte auch ganz interessant sein. Mit der Funktion kannst du über die gesetzten Felder iterieren und statt einen Nachrichten Typ eine beliebige Kombination implementieren.

ERROR

Alter Hase

  • »ERROR« ist der Autor dieses Themas

Beiträge: 417

Wohnort: Paderborn

Beruf: Informatik Student

  • Private Nachricht senden

25

29.07.2014, 13:02

Das ist langsam zum Verzweifeln. Vielleicht weiss ja von euch noch Jemand Rat: Stackoverflow

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

26

29.07.2014, 13:11

Wieso machst Du aus einem Byte-Buffer einen String? Wie lang ist die serialisierte Login-Message?

Statt dem:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
MainMessage message = new MainMessage
        {
            Header = new MessageHeader
            {
                Id = 1,
            },

        };
        MessageLogin login = new MessageLogin
        {
            Username = username,
            Password = password,
        };
        Extensible.AppendValue<MessageLogin>(message, 101, login);
hätte ich das gemacht:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
MainMessage message = new MainMessage
        {
            Header = new MessageHeader
            {
                Id = 1,
            },
            Login = new MessageLogin
        {
            Username = username,
            Password = password,
        };
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

ERROR

Alter Hase

  • »ERROR« ist der Autor dieses Themas

Beiträge: 417

Wohnort: Paderborn

Beruf: Informatik Student

  • Private Nachricht senden

27

29.07.2014, 13:31

Das geht leider nicht, weil Login ja nur eine extension von MainMessage ist. Deswegen muss es so hinzugefügt werden.
Den string erstelle ich, damit ich ihn per NetMQ (ZeroMQ C# Version) versenden kann.


Hmm, serialisiere ich dir MainMessage, sieht sie so aus:

"\n\b?\v\nerrorpw\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" (error ist der eingegeben username und pw das passwort)

Das sieht ja schon irgendwie sehr merkwürdig aus oder?

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

28

29.07.2014, 14:06

Laut C# Code sollte es aber gehen. Oder wird dann nichts serialisiert?
Der String da sieht ziemlich merkwürdig aus mit den vielen Nullen.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

ERROR

Alter Hase

  • »ERROR« ist der Autor dieses Themas

Beiträge: 417

Wohnort: Paderborn

Beruf: Informatik Student

  • Private Nachricht senden

29

29.07.2014, 14:10

"PA_Client_CS.MainMessage' enthält keine Definition für 'Login'." kommt dann als Fehlermeldung.

Wäre Login keine extension, würe es gehen, aber da es eine extension ist, geht dies eben nicht.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

30

29.07.2014, 15:40

Das sollte doch aber die C# Property null interessieren. Oder wo genau bekommst du diese Fehlermeldung?

PS: Hast du die C# Klassen-Definition wieder aus Stackoverflow rausgelöscht?
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Werbeanzeige