Session Diagnostics
On this page
Namespaces: Nalix.SDK.Transport, Nalix.SDK.Transport.Extensions, Nalix.SDK.Options
Assembly: Nalix.SDK
Nalix.SDK surfaces transport lifecycle changes, frame errors, request outcomes, and latency metrics through TransportSession events (OnConnected, OnReady, OnDisconnected, OnMessageReceived, OnError), NLogix structured logging, and non-throwing RequestOutcome<TResponse> results.
Source Mapping
src/Nalix.SDK/Transport/TransportSession.cssrc/Nalix.SDK/Transport/TcpSession.cssrc/Nalix.SDK/Transport/UdpSession.cssrc/Nalix.SDK/Transport/WebSocketSession.cssrc/Nalix.SDK/Options/RequestOutcome.cssrc/Nalix.SDK/TimeSyncCalculator.cs
1. Subscribing to Session Lifecycle & Error Events
using System;
using System.Buffers.Binary;
using Nalix.Abstractions.Memory;
using Nalix.SDK.Transport;
public static void AttachDiagnostics(TransportSession session, string name)
{
session.OnConnected += (_, _) =>
Console.WriteLine($"[{name}] Socket connected (LocalPort={session.State.LocalPort}).");
session.OnReady += (_, _) =>
Console.WriteLine($"[{name}] Session ready (Encrypted={session.State.EncryptionEnabled}, Token=0x{session.State.SessionToken:X16}).");
session.OnDisconnected += (_, ex) =>
Console.WriteLine($"[{name}] Disconnected: {ex?.Message ?? "Clean close"}");
session.OnError += (_, ex) =>
Console.Error.WriteLine($"[{name}] Transport error: {ex.GetType().Name}: {ex.Message}");
session.OnMessageReceived += (_, lease) =>
{
// IMPORTANT: Do NOT call lease.Dispose() here!
// TransportSession owns the borrowed IBufferLease and disposes it after OnMessageReceived returns.
if (lease.Length >= 6)
{
ushort opCode = BinaryPrimitives.ReadUInt16LittleEndian(lease.Span.Slice(2, 2));
Console.WriteLine($"[{name}] Inbound frame: {lease.Length} bytes, OpCode=0x{opCode:X4}");
}
};
}
2. Reconnect Lifecycle Hooks (OnResumedAsync & OnReauthenticateAsync)
When TransportOptions.AutoReconnectEnabled = true, ReconnectSupervisor recovers dropped connections in the background and invokes your hooks before signaling OnReady:
session.OnResumedAsync = async ct =>
{
Console.WriteLine("0-RTT session resumed! Server state and attributes are still intact.");
await Task.CompletedTask;
};
session.OnReauthenticateAsync = async ct =>
{
Console.WriteLine("Previous session expired; fresh X25519 handshake completed. Re-sending login...");
await session.RequestAsync<LoginResponse>(new LoginPacket { Token = savedJwt }, ct: ct);
};
3. Structured Request Diagnostics (TryRequestAsync)
Use TryRequestAsync<TResponse> to inspect RequestOutcome<TResponse> (Kind: Ok, NotConnected, TimedOut, Failed) without catching exceptions on hot paths:
using Nalix.SDK.Options;
using Nalix.SDK.Transport.Extensions;
RequestOutcome<MatchmakeResponse> outcome = await session.TryRequestAsync<MatchmakeResponse>(
new MatchmakeRequest { Mode = "Ranked" },
RequestOptions.Default.WithTimeout(3_000).WithRetry(1));
switch (outcome.Kind)
{
case RequestOutcomeKind.Ok:
Console.WriteLine($"Matched into lobby {outcome.Value.LobbyId}");
break;
case RequestOutcomeKind.NotConnected:
Console.WriteLine("Cannot send request: session is offline.");
break;
case RequestOutcomeKind.TimedOut:
Console.WriteLine("Server did not respond within timeout budget.");
break;
case RequestOutcomeKind.Failed:
Console.WriteLine($"Protocol or serialization failure: {outcome.Error?.Message}");
break;
}