Quickstart¶
Learning Signals
- Level: Beginner
- Time: 15 minutes
- Prerequisites: Introduction
This guide walks you through building a complete Ping/Pong service using Nalix over TCP. By the end, you will have a production-grade foundation with a shared contract project, a sharded server, and a type-safe client.
🗺️ Roadmap¶
- Define Packets: Create shared data contracts.
- Identity Setup: Generate server security keys.
- Server Setup: Route packets to a handler.
- Client Connectivity: Send requests and await replies.
Step 1: Create the Solution¶
We recommend a three-project structure to keep your networking logic clean and reusable.
mkdir NalixPingPong && cd NalixPingPong
dotnet new sln
# 1. Shared Contracts
dotnet new classlib -n Contracts
dotnet add Contracts package Nalix.Abstractions
# 2. Server Host
dotnet new console -n Server
dotnet add Server reference Contracts
dotnet add Server package Nalix.Hosting
# 3. Client App
dotnet new console -n Client
dotnet add Client reference Contracts
dotnet add Client package Nalix.SDK
dotnet sln add Contracts Server Client
Step 2: Define Packets¶
Create the shared packet contracts in the Contracts project. Both server and client reference this assembly, ensuring binary alignment.
using Nalix.Codec.DataFrames;
using Nalix.Abstractions.Serialization;
namespace Contracts;
[SerializePackable]
public sealed class PingRequest : PacketBase<PingRequest>
{
public const ushort OpCodeValue = 0x1001;
public string Message { get; set; } = string.Empty;
public PingRequest() => OpCode = OpCodeValue;
}
using Nalix.Codec.DataFrames;
using Nalix.Abstractions.Serialization;
namespace Contracts;
[SerializePackable]
public sealed class PingResponse : PacketBase<PingResponse>
{
public const ushort OpCodeValue = 0x1002;
public string Message { get; set; } = string.Empty;
public PingResponse() => OpCode = OpCodeValue;
}
Layout Strategy
By default, [SerializePackable] uses SerializeLayout.Auto, which automatically orders fields for optimal packing. In production environments where binary stability is critical (e.g., cross-version compatibility), you can switch to SerializeLayout.Explicit and use [SerializeOrder(n)] to lock field positions.
Step 3: Identity Setup¶
Nalix enforces mandatory security. Before running the server, you must generate a cryptographic identity.
# Clean and run the certificate tool
dotnet run --project tools/Nalix.Certificate/Nalix.Certificate.csproj
This generates certificate.private and certificate.public in Directories.ConfigurationDirectory. The server automatically loads the default private identity during Build(). If your certificate files live somewhere else, call ConfigureCertificate(...) before Build() so the hosting builder passes that path to the handshake subsystem.
var builder = NetworkApplication.CreateBuilder()
.ConfigureCertificate("./identity/certificate.private");
using var app = builder
// Add packets, handlers, and listeners here.
.Build();
Step 4: Implement the Server¶
The server requires a Handler for logic and a Protocol bridge to the network.
using Contracts;
using Nalix.Abstractions.Networking.Packets;
[PacketController("PingHandler")]
public sealed class PingHandler
{
[PacketOpcode(PingRequest.OpCodeValue)]
public PingResponse Handle(IPacketContext<PingRequest> context)
{
return new PingResponse
{
Message = $"Pong: {context.Packet.Message}"
};
}
}
using Nalix.Abstractions.Networking;
using Nalix.Network.Protocols;
using Nalix.Runtime.Dispatching;
public sealed class PingProtocol : Protocol
{
private readonly IPacketDispatch _dispatch;
public PingProtocol(IPacketDispatch dispatch) => _dispatch = dispatch;
public override void ProcessMessage(object? sender, IConnectEventArgs args)
=> _dispatch.HandlePacket(args.Lease, args.Connection);
}
Tip
If you don't need custom protocol logic, you can use the built-in DefaultProtocol from the Nalix.Hosting namespace instead of creating your own class: .BindTcp<DefaultProtocol>().Bind()
Step 5: Connect the Client¶
Nalix SDK provides a TcpSession that handles reconnection and type-safe request correlation automatically.
using System;
using Contracts;
using Nalix.Codec.DataFrames;
using Nalix.SDK.Options;
using Nalix.SDK.Transport;
using Nalix.SDK.Transport.Extensions;
// 1. Build the packet registry (The 'Catalog')
PacketRegistryFactory factory = new();
factory.RegisterPacket<PingRequest>()
.RegisterPacket<PingResponse>();
var registry = factory.CreateCatalog();
// 2. Open the session
var options = new TransportOptions { Address = "127.0.0.1", Port = 5000 };
using var client = new TcpSession(options, registry);
await client.ConnectAsync();
await client.HandshakeAsync();
// 3. Request/Response (Type-Safe)
var response = await client.RequestAsync<PingResponse>(
new PingRequest { Message = "Hello Nalix!" });
// 4. Fire-and-forget (Optional Encryption)
await client.SendAsync(new PingRequest { Message = "Silent Ping" }, encrypt: false);
Console.WriteLine(response.Message); // "Pong: Hello Nalix!"
🛠️ Performance Architecture¶
Nalix isn't just easy to use; it's built for high-scale environments.
sequenceDiagram
participant C as Client (SDK)
participant L as Listener (Transport)
participant D as Dispatch (Sharded)
participant H as Handler (Logic)
C->>L: Binary Frame
Note over L: FramePipeline (AEAD)
L->>D: Clean Message (IBufferLease)
Note over D: Zero-Alloc Routing
D->>H: Invoke Method
H-->>C: Transmit Response
Recommended Next Steps¶
-
Architecture Deep dive into the sharded dispatch model.
-
Middleware Secure your packets with rate-limits and permissions.
-
Production Prep Checklist for high-traffic deployments.