SetNet 1.6.2

There is a newer version of this package available.
See the version list below for details.
dotnet add package SetNet --version 1.6.2
                    
NuGet\Install-Package SetNet -Version 1.6.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SetNet" Version="1.6.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SetNet" Version="1.6.2" />
                    
Directory.Packages.props
<PackageReference Include="SetNet" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SetNet --version 1.6.2
                    
#r "nuget: SetNet, 1.6.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SetNet@1.6.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SetNet&version=1.6.2
                    
Install as a Cake Addin
#tool nuget:?package=SetNet&version=1.6.2
                    
Install as a Cake Tool

<p align="center"> <img src="https://raw.githubusercontent.com/Povstalez/SetNet/master/assets/logo.png" alt="SetNet" width="320"> </p>

SetNet

A lightweight, high-throughput .NET networking library for client–server games and real-time apps — over TCP, UDP, or both at once.

SetNet gives you a persistent, message-oriented connection with automatic handler registration, a pluggable transport (reliable TCP, raw/reliable UDP, or both together), per-message delivery selection, strongly-typed handlers, and production-grade hardening — so you can focus on your game/app logic instead of sockets.

Why SetNet

  • 🚦 TCP / UDP / Both — one API; choose per Configuration.TransportType, pick the channel per message via DeliveryMethod.
  • 🛡️ Reliable UDP (optional) — sequence / ACK / retransmit / ordered delivery with a bounded receive window and back-pressure; multiple independent channels so a loss on one stream never head-of-line-blocks another.
  • 🤝 Emulated UDP connections — handshake + heartbeat give UDP the same OnConnected/OnDisconnected/peer lifecycle as TCP. Both mode binds a TCP lifeline and a UDP channel to one logical peer, with graceful TCP-only fallback.
  • 🔄 Lifecycle done right — intentional vs unexpected disconnects, auto-reconnect hooks, heartbeat liveness; OnDisconnected fires exactly once.
  • 🧩 Strongly-typed handlersIServerMessageHandler<T> / IClientMessageHandler<T> receive the deserialized message; the library (de)serializes for you. Auto-discovered via [MessageHandler(type)] or registered explicitly on SetNetRuntime.Handlers.
  • 🔀 Raw relay escape hatch — override OnRawFrame(type, data) + SendRawAsync to forward bytes without (de)serializing (relay/proxy), while normal handlers stay typed.
  • 📦 Pluggable serialization — the core bundles no serializer. Add SetNet.MessagePack (hardened MessagePack) or supply your own ISerializer (JSON, Protobuf, …), globally via SetNetSerializer.Use(...) or per endpoint via SetNetRuntime.
  • 🔒 Production-hardened — TLS over TCP, connection/UDP-peer caps, per-IP rate limiting, frame-size cap, back-pressure, bounded inbound queues (OOM protection), a resilient accept loop, and live NetworkMetrics.
  • Fast — ~1.6M msgs/sec on one connection with send batching; allocation-light hot paths.

Install

dotnet add package SetNet
# the core bundles no serializer — add one (or supply your own ISerializer):
dotnet add package SetNet.MessagePack

Register the serializer before connecting. For a simple app, configure the default runtime:

using SetNet.Messaging;
using SetNet.MessagePack;

SetNetSerializer.Use(new MessagePackNetSerializer());

For an isolated server/client environment in the same process, use an explicit runtime:

using SetNet;
using SetNet.Config;
using SetNet.MessagePack;

var runtime = new SetNetRuntime()
    .UseSerializer(new MessagePackNetSerializer());

runtime.Handlers.AutoDiscoverLoadedAssemblies = false;
runtime.Handlers.AddHandlersFromAssemblyOf<ChatHandler>();

var config = new Configuration { Host = "127.0.0.1", Port = 5000, Runtime = runtime };

Quick start

1. Define a message (MessagePack DTO):

public enum MsgType : ushort { Chat = 1 }

[MessagePackObject]
public class ChatMessage { [Key(0)] public string Text { get; set; } = ""; }

2. Server:

using SetNet.Core;
using SetNet.Config;

public class ChatPeer : BasePeer
{
    public ChatPeer(PeerInfo info) : base(info) { }
    protected override void OnDisconnected() { }
    protected override void OnError(string error) { }
}

public class ChatServer : BaseServer
{
    public ChatServer(Configuration config) : base(config) { }
    protected override BasePeer OnNewClient(PeerInfo info) => new ChatPeer(info);
}

await new ChatServer(new Configuration { Host = "0.0.0.0", Port = 5000 }).StartAsync();

3. Client:

public class ChatClient : BaseClient
{
    public ChatClient(Configuration config) : base(config) { }
    protected override void OnConnected()    => Console.WriteLine("connected");
    protected override void OnDisconnected() { }
    protected override void OnError(string error) { }
    public Task SayAsync(string text) => SendAsync((ushort)MsgType.Chat, new ChatMessage { Text = text });
}

var client = new ChatClient(new Configuration { Host = "127.0.0.1", Port = 5000 });
await client.ConnectAsync();
await client.SayAsync("hello");

4. Handle messages (auto-discovered or explicitly registered, strongly typed — the library deserializes for you):

[MessageHandler((ushort)MsgType.Chat)]
public class ChatHandler : IServerMessageHandler<ChatMessage>
{
    public Task HandleAsync(BasePeer peer, ChatMessage msg)
    {
        Console.WriteLine(msg.Text);
        return Task.CompletedTask;
    }
}

Transport selection

Set Configuration.TransportType (default Tcp):

TransportType DeliveryMethod Carried over
Tcp any TCP
Udp Reliable UDP reliability layer (needs UdpReliabilityEnabled)
Udp Unreliable raw UDP datagram
Both Reliable TCP
Both Unreliable UDP (falls back to TCP until the UDP channel attaches)

Compatibility

  • .NET Standard 2.1 — consumable from .NET Core 3.0+/.NET 5–8, Unity (2021+), Mono, MAUI. Not .NET Framework.
  • Unity: handlers run on background threads (marshal to the main thread before touching the Unity API); IL2CPP/AOT needs pre-generated MessagePack formatters (or an AOT-friendly serializer); WebGL is not supported (no threads/sockets).

Notes

  • Authentication is left to your application — validate inside OnNewClient/handlers.
  • UDP datagrams have no per-packet encryption — route sensitive traffic over TLS-over-TCP (or Both with reliable delivery).
  • The core is not an HTTP framework, but it now includes the unified SetNet.Protocol envelope used by companion packages for request/reply and push events. RPC, DI, hosting, WebSocket, and browser/engine-specific transports live in optional packages.

Documentation & source

License

MIT

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.1

    • No dependencies.

NuGet packages (76)

Showing the top 5 NuGet packages that depend on SetNet:

Package Downloads
SetNet.MessagePack

MessagePack serializer for SetNet. Provides MessagePackNetSerializer (an ISerializer) hardened with the MessagePack UntrustedData security profile. Register it once at startup: SetNetSerializer.Use(new MessagePackNetSerializer());

SetNet.StateSync

Server-authoritative entity replication for SetNet: fixed-rate, delta-compressed world snapshots over the unreliable channel with reliable spawns/despawns, client-side interpolation, interest management, and an input channel for client prediction. Engine-agnostic core (headless dedicated server + any .NET client); the Unity binding (SetNet.StateSync.Unity) adds NetworkObject/NetworkTransform/NetworkAnimator/NetworkRigidbody. Composition, no base class. Depends only on SetNet.

SetNet.Rooms

Rooms / lobbies for SetNet, by composition (no base class). Create and join rooms by code, broadcast within a room, and get player-joined/left events — on a dedicated server (server is the hub; no relay needed). Pluggable room store (default in-memory), auto-leave on disconnect. Serializer-agnostic; depends only on SetNet.

SetNet.Inventory

Server-authoritative player inventory for SetNet: game logic grants/revokes stackable items by player key (server.UseInventory()), connected clients read + subscribe to changes (client.UseInventory()). Atomic TryRevoke primitive backs trades and mail claims; pluggable IInventoryStore (memory default, swap for Redis/DB). Depends only on SetNet.

SetNet.Auth

Authentication and sessions for SetNet, by composition (no base class). Enforced gate: until a peer authenticates, its application frames (regular messages and RPC) are dropped; you validate a token via IAuthenticator. Includes session store with TTL, multi-session policy, and automatic reconnect-resume. Serializer-agnostic; depends only on SetNet. Use over TLS.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.6.3 51 8/23/2026
1.6.2 53 8/23/2026
1.6.1 61 8/20/2026
1.3.0 161 8/14/2026
1.2.0 1,856 8/5/2026
1.1.0 1,822 7/2/2026
1.0.1 112 6/30/2026
1.0.0 109 6/30/2026