Packet Handlers

Read time 2 minutes
On this page

A packet handler is where your application logic lives — one method per opcode, invoked automatically when a matching packet arrives.

Basic pattern: reply on the same connection

// samples/HelloWorld/HelloWorld.Server/HelloHandlers.cs
[PacketController("HelloWorld.Greetings")]
public static class HelloHandlers
{
    [PacketOpcode(0x7001)]
    public static async ValueTask HandleHelloAsync(IPacketContext<HelloRequestPacket> context)
    {
        using PacketScope<HelloResponsePacket> lease = PacketFactory<HelloResponsePacket>.Acquire();
        HelloResponsePacket response = lease.Value;
        response.Message = 1;

        await context.Sender.ReplyAsync(response).ConfigureAwait(false);
    }
}

[PacketController("...")] marks the class ([PacketHandler] is obsolete); [PacketOpcode(0x7001)] maps one method to one opcode. IPacketContext<TPacket> gives you the deserialized packet and a Sender to reply on. Use PacketFactory<T>.Acquire() to get a pooled instance instead of allocating one — always wrap it in a using block so it’s returned to the pool.

Full source: samples/HelloWorld/HelloWorld.Server/HelloHandlers.cs

Broadcasting instead of replying

// samples/ChatRoom/ChatRoom.Server/ChatHandlers.cs
[PacketController("ChatRoom.Chat")]
public static class ChatHandlers
{
    [PacketOpcode(0x7101)]
    public static async ValueTask HandleChatAsync(IPacketContext<ChatMessagePacket> context)
    {
        ArgumentNullException.ThrowIfNull(context);

        IConnectionBroadcaster? hub = InstanceManager.Instance
            .GetExistingInstance<IConnectionBroadcaster>();

        if (hub is null)
        {
            return;
        }

        await hub.BroadcastAsync(context.Packet).ConfigureAwait(false);
    }
}

Instead of context.Sender.SendAsync(...), this handler resolves IConnectionBroadcaster and sends the packet to every connected client.

Full source: samples/ChatRoom/ChatRoom.Server/ChatHandlers.cs

Registering handlers

Both samples register their handler class the same way, on the server builder:

NetworkApplication.CreateBuilder()
    .MapHandlers(typeof(HelloHandlers))
    // ...
    .Build();

Next steps