Search code examples
c#network-programmingxnalidgren

Networking flow


I'm designing a game in C#, I'm sure you get it a lot - but my question is a bit different in that I want to design something around an observer pattern to my understanding - and I can't find much information it.

All of my packets implement a basic interface, called IPacket... and I was hoping to fire off an event when a packet of a certain type was recieved; without using a massive switch.

I was perhaps hoping for something like:

networkEvents.PacketRecieved += [...]

Could anyone point me in the direction to do this?


Solution

  • What about something like this:

    public interface IPacket
    {
    
    }
    
    public class FooPacket: IPacket {}
    
    public class PacketService
    {
        private static readonly ConcurrentDictionary<Type, Action<IPacket>> _Handlers = new ConcurrentDictionary<Type, Action<IPacket>>(new Dictionary<Type, Action<IPacket>>());
    
        public static void RegisterPacket<T>(Action<T> handler)
            where T: IPacket
        {
            _Handlers[typeof (T)] = packet => handler((T) packet);
        }
    
        private void ProcessReceivedPacket(IPacket packet)
        {
            Action<IPacket> handler;
            if (!_Handlers.TryGetValue(packet.GetType(), out handler))
            {
                // Error handling here. No packet handler exists for this type of packet.
                return;
            }
            handler(packet);
        }
    }
    
    class Program
    {
        private static PacketService _PacketService = new PacketService();
        static void Main(string[] args)
        {
            PacketService.RegisterPacket<FooPacket>(HandleFooPacket);
        }
    
        public static void HandleFooPacket(FooPacket packet)
        {
            // Do something with the packet
        }
    }
    

    Each type of package you create registers a handler specific to that type of packet. Using a ConcurrentDictionary makes locking superfluous.