End-to-End Sample¶
This guide shows the smallest useful Nalix TCP server flow:
- register shared services
- build a packet dispatcher
- forward frames from
Protocolinto dispatch - start a
TcpListenerBase - send one request and receive one response
The sample is intentionally small so clients can copy the structure first and optimize later.
Server¶
1. Register shared services¶
InstanceManager.Instance.Register<ILogger>(logger);
InstanceManager.Instance.Register<IPacketRegistry>(packetRegistry);
2. Create handlers¶
[PacketController("SamplePingHandlers")]
public sealed class SamplePingHandlers
{
[PacketOpcode(0x1001)]
public ValueTask<PingResponse> Ping(PingRequest request, IConnection connection)
{
PingResponse response = new()
{
Message = $"pong:{request.Message}"
};
return ValueTask.FromResult(response);
}
}
3. Build the dispatcher¶
PacketDispatchChannel dispatch = new(options =>
{
options.WithLogging(logger)
.WithHandler(() => new SamplePingHandlers());
});
dispatch.Activate();
4. Bridge protocol to dispatch¶
public sealed class SampleProtocol : Protocol
{
private readonly PacketDispatchChannel _dispatch;
public SampleProtocol(PacketDispatchChannel dispatch) => _dispatch = dispatch;
public override void ProcessMessage(object sender, IConnectEventArgs args)
=> _dispatch.HandlePacket(args.Lease, args.Connection);
}
5. Start the listener¶
public sealed class SampleTcpListener : TcpListenerBase
{
public SampleTcpListener(ushort port, IProtocol protocol) : base(port, protocol) { }
}
SampleTcpListener listener = new(57206, new SampleProtocol(dispatch));
listener.Activate();
Client¶
The transport/session abstraction can vary on your side, but the request/response pattern is:
PingRequest request = new()
{
Message = "hello"
};
await client.SendAsync(request.Serialize());
PingResponse response = await WaitForPingResponseAsync();
Console.WriteLine(response.Message); // pong:hello
Full flow¶
sequenceDiagram
participant Client
participant Listener as TcpListenerBase
participant Protocol as SampleProtocol
participant Dispatch as PacketDispatchChannel
participant Handler as SamplePingHandlers
Client->>Listener: TCP frame
Listener->>Protocol: connection message event
Protocol->>Dispatch: HandlePacket(lease, connection)
Dispatch->>Handler: Ping(request, connection)
Handler-->>Dispatch: PingResponse
Dispatch-->>Client: serialized response
What to customize next¶
- add middleware
- add packet attributes such as timeout, permission, or rate limit
- switch some handlers to
PacketContext<TPacket>when you need explicit manual sending