Jump to content

Packet Handling Patterns


Oddly

Recommended Posts

So, I'm trying to find a good design pattern for managing my packet handlers once a network packet comes in.

Basically the flow is
TCP Packet Received -> Deserialize packet into object -> Handle Packet based on the Packet's Type received in the first bytes


The thing is I don't want a bunch of switch case statements, I thought about using the subscriber pattern but than i thought that I'd need a list of a bunch subscribe(PacketType, Function Pointer) which is just as bad as the switch cases.

Anyone know a good pattern for this?

Link to comment
Share on other sites

My brain is half fried so I'll take a look again after I get some sleep, but you basically have three options, listed from worst-to-best:

  1. Switch block -- literally horrible, please don't do this. It's infinitely better than an if-block or something super stupid but it's still going to be literal spaghetti hell.
  2. Reflection -- really only needs to be done at start-up and it automatically subscribes, but you'll need extra code to pre-define or smart-sort opcodes so they don't change from build-to-build. Also since I'm pretty sure you're using C++, I'm not really sure this is even possible.
  3. Subscriber pattern -- Sure it's annoying because you have a subscription block, but it's still better than a switch-block (which is either all of the handlers shoved into a block, or an expanded and not at all faster version of the subscriber block), it's more reliable with less code than reflection, and it works in every language I know of.

I can't really think of any other patterns, and quite frankly I'm not sure they exist. I think when it boils down to it you have a spectrum of options between "automated" and "efficient" packet registration and handling, and reflection is the (reasonable) limit of automation and a variant of the subscriber method is the most efficient if you're looking at the protocol layer or below. There's just a limit to how little code you can write for this stuff.

Link to comment
Share on other sites

6 hours ago, panda said:

My brain is half fried so I'll take a look again after I get some sleep, but you basically have three options, listed from worst-to-best:

  1. Switch block -- literally horrible, please don't do this. It's infinitely better than an if-block or something super stupid but it's still going to be literal spaghetti hell.
  2. Reflection -- really only needs to be done at start-up and it automatically subscribes, but you'll need extra code to pre-define or smart-sort opcodes so they don't change from build-to-build. Also since I'm pretty sure you're using C++, I'm not really sure this is even possible.
  3. Subscriber pattern -- Sure it's annoying because you have a subscription block, but it's still better than a switch-block (which is either all of the handlers shoved into a block, or an expanded and not at all faster version of the subscriber block), it's more reliable with less code than reflection, and it works in every language I know of.

I can't really think of any other patterns, and quite frankly I'm not sure they exist. I think when it boils down to it you have a spectrum of options between "automated" and "efficient" packet registration and handling, and reflection is the (reasonable) limit of automation and a variant of the subscriber method is the most efficient if you're looking at the protocol layer or below. There's just a limit to how little code you can write for this stuff.

Ha that's funny, the guy one stack overflow said "There's nothing wrong with using a switch statement, it's perfectly acceptable and readable on first look. Also check out rpc, that's a thing too".

Yeah, i figured it was gonna come down to the subscriber pattern...

Link to comment
Share on other sites

Not sure if it's .Net, or if whatever your language of choice is.. But wouldn't collections work? You can sort of ''subscribe'' a method into that through packet IDs, and they're relatively easy to deal with. (ie Dictionaries in the .Net Framework)

They're not too gross to look at and should you expose them to other code it might be fairly extensible allowing people to add their own packet IDs.

 

e.g.: (taken from something I wrote up ages ago)

private static Dictionary<Packets.Client, Action<NetIncomingMessage>> handler = new Dictionary<Packets.Client, Action<NetIncomingMessage>>() {
    { Packets.Client.AuthenticateClient, HandleAuthenticateClient }
};

 

private static void HandleData(NetIncomingMessage msg) {
    // Retrieve our data and pass it on to the designated handler.
    Action<NetIncomingMessage> exec;
    if (handler.TryGetValue((Packets.Client)msg.ReadInt32(), out exec)) exec(msg);
}
Link to comment
Share on other sites

1 hour ago, Joyce said:

Not sure if it's .Net, or if whatever your language of choice is.. But wouldn't collections work? You can sort of ''subscribe'' a method into that through packet IDs, and they're relatively easy to deal with. (ie Dictionaries in the .Net Framework)

They're not too gross to look at and should you expose them to other code it might be fairly extensible allowing people to add their own packet IDs.

 

e.g.: (taken from something I wrote up ages ago)


private static Dictionary<Packets.Client, Action<NetIncomingMessage>> handler = new Dictionary<Packets.Client, Action<NetIncomingMessage>>() {
    { Packets.Client.AuthenticateClient, HandleAuthenticateClient }
};

 

private static void HandleData(NetIncomingMessage msg) {
    // Retrieve our data and pass it on to the designated handler.
    Action<NetIncomingMessage> exec;
    if (handler.TryGetValue((Packets.Client)msg.ReadInt32(), out exec)) exec(msg);
}

 

C++, collections is not an option, i think i decided to go with the observer/subscriber pattern because it now works with my game scene system.

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...