protobuf-net / protobuf-net

Protocol Buffers library for idiomatic .NET
Other
4.69k stars 1.05k forks source link

How to Send message with a Enum (tag)? #1169

Open vanhaodev opened 2 months ago

vanhaodev commented 2 months ago
PacketTypeEnum type = PacketTypeEnum .Login;
ProtoBuf.Serializer.Serialize(streamWriter, data);
data += type; //like this
Send(streamWriter.ToArray())

thank u <3

mgravell commented 2 months ago

Sorry, can you rephrase? I'm not sure whether you're asking a question, making a suggestion, or reporting an issue! More words please?

vanhaodev commented 2 months ago

Sorry, can you rephrase? I'm not sure whether you're asking a question, making a suggestion, or reporting an issue! More words please?

sorry, How to Send message with a Enum (tag)?

vanhaodev commented 2 months ago

Sorry, can you rephrase? I'm not sure whether you're asking a question, making a suggestion, or reporting an issue! More words please?

I mean, when u Serialize a struct and send to client, so how to send with a key/tag/enum for response type?

vanhaodev commented 2 months ago

My way

   {
       lock (handleLock)
       {
           try
           {
               ProtoBuf.Serializer.Serialize(streamWriter, data);
               // Chuyển packetType thành mảng byte
               byte[] packetType = BitConverter.GetBytes((short)responseType);
               byte[] packetData = streamWriter.ToArray();

               byte[] zippedPacket = new byte[packetType.Length + packetData.Length];

               // Chèn packetType vào 2 vị trí đầu tiên
               System.Buffer.BlockCopy(packetType, 0, zippedPacket, 0, packetType.Length);
               // Chèn dataPacket vào sau packetType
               System.Buffer.BlockCopy(packetData, 0, zippedPacket, packetType.Length, packetData.Length);

               Send(zippedPacket);
           }
           catch (Exception ex)
           {
               Console.Error.WriteLine(ex.ToString());
           }
           finally
           {
               streamWriter.SetLength(0);
               streamWriter.Position = 0;
           }
       }
   }
mgravell commented 2 months ago

You seem to be asking about how to send a "discriminator" before the payload to identify the type of data being sent. If that is the case:

My preferred option here would be to use inheritance; consider:

[ProtoContract]
[ProtoInclude(typeof(Foo), 1)]
[ProtoInclude(typeof(Bar), 2)]
abstract class PacketBase { ... }

[ProtoContract]
class Foo : PacketBase { ... }

[ProtoContract]
class Bar : PacketBase { ... }

var obj = new Foo {...};
Serializer.Serialize(destination, obj);

// later...
var obj = Serializer.Deserialize<PacketBase>(source);

then: this will be written using a protobuf-compliant discriminator (via the ProtoInclude), with the object automatically being deserialized as a Foo (in this case).


If I've misunderstood and you just want the enum on the object... then do that:

[ProtoContract]
class YourType
{
    [ProtoMember(1)]
    public YourEnum YourValue {get;set;}
}

For more specific advice, it would really help to understand what you're trying to achieve, rather than how you're currently trying to do it.

vanhaodev commented 2 months ago

You seem to be asking about how to send a "discriminator" before the payload to identify the type of data being sent. If that is the case:

  • if you don't need the discriminator to be related to protobuf, the short answer would be "any way you like"
  • if you prefer the discriminator to be part of the data protocol, then that's fine; we have a few options

My preferred option here would be to use inheritance; consider:

[ProtoContract]
[ProtoInclude(typeof(Foo), 1)]
[ProtoInclude(typeof(Bar), 2)]
abstract class PacketBase { ... }

[ProtoContract]
class Foo : PacketBase { ... }

[ProtoContract]
class Bar : PacketBase { ... }

var obj = new Foo {...};
Serializer.Serialize(destination, obj);

// later...
var obj = Serializer.Deserialize<PacketBase>(source);

then: this will be written using a protobuf-compliant discriminator (via the ), with the object automatically being deserialized as a (in this case).ProtoInclude``Foo

If I've misunderstood and you just want the enum on the object... then do that:

[ProtoContract]
class YourType
{
    [ProtoMember(1)]
    public YourEnum YourValue {get;set;}
}

For more specific advice, it would really help to understand what you're trying to achieve, rather than how you're currently trying to do it.

thank u, it's so good for class, but i using struct

mgravell commented 2 months ago

There is IIRC a variant of SerializeWithLengthPrefix that allows a prefix tag to be specified on a per-call basis, and similarly a variant of the matching deserialize that takes a callback type-resolver, however I wonder if in this case it makes sense to simply specify the packet type as a header/prefix to the real payload, because presumably you'll want the deserialize to process it too.

On Thu, 15 Aug 2024, 13:34 Nguyen Van Hao, @.***> wrote:

You seem to be asking about how to send a "discriminator" before the payload to identify the type of data being sent. If that is the case:

  • if you don't need the discriminator to be related to protobuf, the short answer would be "any way you like"
  • if you prefer the discriminator to be part of the data protocol, then that's fine; we have a few options

My preferred option here would be to use inheritance; consider:

[ProtoContract] [ProtoInclude(typeof(Foo), 1)] [ProtoInclude(typeof(Bar), 2)] abstract class PacketBase { ... }

[ProtoContract] class Foo : PacketBase { ... }

[ProtoContract] class Bar : PacketBase { ... }

var obj = new Foo {...}; Serializer.Serialize(destination, obj);

// later... var obj = Serializer.Deserialize(source);

then: this will be written using a protobuf-compliant discriminator (via the ), with the object automatically being deserialized as a (in this case). ProtoInclude``Foo

If I've misunderstood and you just want the enum on the object... then do that:

[ProtoContract] class YourType { [ProtoMember(1)] public YourEnum YourValue {get;set;} }

For more specific advice, it would really help to understand what you're trying to achieve, rather than how you're currently trying to do it.

thank u, it's so good for class, but i using struct

— Reply to this email directly, view it on GitHub https://github.com/protobuf-net/protobuf-net/issues/1169#issuecomment-2291186946 or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAEHMC53MNJAJF2GVG6PVLZRSN6VBFKMF2HI4TJMJ2XIZLTSOBKK5TBNR2WLJDUOJ2WLJDOMFWWLO3UNBZGKYLEL5YGC4TUNFRWS4DBNZ2F6YLDORUXM2LUPGBKK5TBNR2WLJDUOJ2WLJDOMFWWLLTXMF2GG2C7MFRXI2LWNF2HTAVFOZQWY5LFUVUXG43VMWSG4YLNMWVXI2DSMVQWIX3UPFYGLLDTOVRGUZLDORPXI6LQMWWES43TOVSUG33NNVSW45FGORXXA2LDOOJIFJDUPFYGLKTSMVYG643JORXXE6NFOZQWY5LFVAZDAOBXHA4DAMUCUR2HS4DFUVUXG43VMWSXMYLMOVS2UMRUGYZTCMJTG42TNJ3UOJUWOZ3FOKTGG4TFMF2GK . You are receiving this email because you commented on the thread.

Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub .