Dignus.ActorServer
1.2.3
dotnet add package Dignus.ActorServer --version 1.2.3
NuGet\Install-Package Dignus.ActorServer -Version 1.2.3
<PackageReference Include="Dignus.ActorServer" Version="1.2.3" />
<PackageVersion Include="Dignus.ActorServer" Version="1.2.3" />
<PackageReference Include="Dignus.ActorServer" />
paket add Dignus.ActorServer --version 1.2.3
#r "nuget: Dignus.ActorServer, 1.2.3"
#:package Dignus.ActorServer@1.2.3
#addin nuget:?package=Dignus.ActorServer&version=1.2.3
#tool nuget:?package=Dignus.ActorServer&version=1.2.3
Dignus.ActorServer
High-performance Actor-based network server framework.
Performance
Benchmark Environment
- CPU: Intel Core i5-12400F (12th Gen)
- Cores / Threads: 6 / 12
- Max Turbo Frequency: 4.40 GHz
- Memory: 32 GB
- Architecture: x64
- Operating System: Windows 64-bit
- Runtime: .NET 10 (Release x64)
Round-Trip Benchmark (Plain TCP)
This benchmark measures full round-trip throughput:
Client send → Server-side processing → Response return
<p align="center"> <img src="Benchmark/Result/tcp-round-trip.png" width="600" /> </p>
Test Conditions
- Server address: 127.0.0.1
- Server port: 5000
- Protocol: Plain TCP (no TLS)
- Working clients: 1
- In-flight messages per client: 1000
- Message size: 32 bytes
- Benchmark duration: 10 seconds
Result
Total Time: 10.008 seconds
Total Client: 1
Total Bytes: 3,269,163,360
Total Data: 3.04 GiB
Total Message: 102,161,355
Data Throughput: 311.53 MiB/s
Message Throughput: 10,208,278 msg/s
TCP Fan-out Benchmark (100 clients)
Send pattern: Server broadcasts identical payload to all connected clients
<p align="center"> <img src="Benchmark/Result/tcp-fan-out-100.png" width="600" /> </p>
Test Conditions
- Server address: 127.0.0.1
- Server port: 5000
- Protocol: Plain TCP (no TLS)
- Working clients: 100
- Message size: 32 bytes
- Benchmark duration: 10 seconds
Result
Total Time: 10.008 seconds
Total Client: 100
Total Bytes: 4,909,594,848
Total Data: 4.57 GiB
Total Message: 153,424,839
Data Throughput: 467.83 MiB/s
Message Throughput: 15,329,728 msg/s
TLS Round-Trip Benchmark
This benchmark measures full round-trip throughput:
Client send → Server-side processing → Response return
<p align="center"> <img src="Benchmark/Result/tls-round-trip.png" width="600" /> </p>
Test Conditions
- Server address: 127.0.0.1
- Server port: 5000
- Protocol: TLS over TCP
- Working clients: 1
- In-flight messages per client: 1000
- Message size: 32 bytes
- Benchmark duration: 10 seconds
Result
Total Time: 10.002 seconds
Total Client: 1
Total Bytes: 2,482,299,424
Total Data: 2.31 GiB
Total Message: 77,571,857
Data Throughput: 236.68 MiB/s
Message Throughput: 7,755,636 msg/s
Tls Fan-out Benchmark (100 clients)
Send pattern: Server broadcasts identical payload to all connected clients
<p align="center"> <img src="Benchmark/Result/tls-fan-out-100.png" width="600" /> </p>
Test Conditions
- Server address: 127.0.0.1
- Server port: 5000
- Protocol: TLS over TCP
- Working clients: 100
- Message size: 32 bytes
- Benchmark duration: 10 seconds
Result
Total Time: 10.052 seconds
Total Client: 100
Total Bytes: 4,852,865,632
Total Data: 4.52 GiB
Total Message: 151,652,051
Data Throughput: 460.42 MiB/s
Message Throughput: 15,087,042 msg/s
Performance Highlights
- Over 10 million round-trip messages per second
- Sustained throughput above 300 MiB/sec
- Full end-to-end measurement (decode → actor execution → encode → send)
- Execution confined to dedicated dispatcher threads
- No ThreadPool scheduling for actor logic
Design Goals
- Strict separation of session logic and network I/O
- Single-threaded execution guarantee per actor
- Partition-based dispatcher scheduling
- Async/await support with dispatcher-context enforcement
- Message-driven concurrency model
Core Architecture
ActorSystem
ActorSystem manages:
- Multiple
ActorDispatcherinstances - Actor lifecycle
- Partition-based distribution
Actors are distributed using:
dispatcherIndex = actorId % dispatcherCount
Each actor executes through an ActorRunner.
ActorDispatcher
Each dispatcher:
- Owns a dedicated worker thread
- Maintains a lock-free scheduling queue
- Uses SemaphoreSlim for wake-up signaling
- Enforces dispatcher-thread execution context
Guarantees:
- An actor always executes on the same thread
- Async continuations resume on the dispatcher thread
- No ThreadPool execution for actor logic
ActorRunner
Execution engine of an actor.
Responsibilities:
- Mailbox processing
- Lifecycle management
- ValueTask-based async handling
- Continuation rescheduling
Execution model:
- Dequeue message
- Execute OnReceive
- If async incomplete → schedule continuation
- Resume on dispatcher thread
This guarantees logical single-threaded execution per actor.
Network Layer
TcpServerBase / TlsServerBase
|
v
ActorPacketProcessor
|
v
SessionActor
|
v
NetworkSession
Concurrency Model
- Single-threaded execution per actor
- Dedicated dispatcher threads
- No shared mutable state across actors
- Message-passing communication model
- Lock-free mailbox scheduling
Lifecycle Model
Kill flow:
- sessionRef.Kill()
- ActorRunner transitions to killing state
- Finalization executed on dispatcher thread
- Mailbox cleared
- Actor removed from ActorSystem
- TransportActor disposes underlying session
Protocol Pipeline Flow
Dignus.ActorServer protocol pipeline works in two phases:
- Registration phase
- Runtime execution phase
1. Registration phase
At startup, protocol handlers are scanned and bound to the pipeline.
ActorProtocolPipeline.Register<TProtocol>()
↓
Protocol method scan
↓
Protocol name binding
↓
Body type extraction
↓
Middleware registration
↓
Compiled protocol invoker build
During registration the framework performs the following steps:
- Protocol handler methods are discovered
- Protocol names are mapped to handler methods
- Handler parameter body types are extracted and cached
- Middleware is registered per handler method
- Dispatch delegates are compiled for runtime execution
Example registration:
ActorProtocolPipeline<ClientPipelineContext>.Register<CLSProtocol>((method, pipeline) =>
{
var filters = method.GetCustomAttributes<ActionAttribute>();
var orderedFilters = filters.OrderBy(r => r.Order).ToList();
var middleware = new ProtocolActionMiddleware(orderedFilters);
pipeline.Use(middleware);
});
2. Runtime execution phase
When a TCP packet arrives, the protocol pipeline executes the following flow.
TCP packet received
↓
PacketFramer.Deserialize
↓
Protocol number extracted
↓
Protocol validation
↓
Body type resolved from registered protocol metadata
↓
JSON body deserialization
↓
Actor message creation
↓
Actor mailbox post
↓
PlayerActor.OnReceive
↓
Pipeline execution
↓
Middleware execution
↓
Protocol handler invocation
↓
Actor state processing
Decode stage (Network layer)
Incoming packets are decoded and transformed into actor messages.
public IActorMessage Deserialize(ReadOnlySpan<byte> packet)
{
int protocol = BitConverter.ToUInt16(packet[..ProtocolSize]);
if (ActorProtocolPipeline<ClientPipelineContext>.ValidateProtocol(protocol) == false)
{
LogHelper.Error($"not found protocol : {protocol}");
return null;
}
var bodyString = Encoding.UTF8.GetString(packet[ProtocolSize..]);
var bodyType = ActorProtocolPipeline<ClientPipelineContext>.GetBodyType(protocol);
var bodyPacketObject = JsonSerializer.Deserialize(bodyString, bodyType);
async Task lambdaMessage(PlayerActor actor)
{
var context = new ClientPipelineContext()
{
Body = bodyPacketObject,
Handler = clientPacketHandler,
Protocol = protocol,
State = actor
};
await ActorProtocolPipeline<ClientPipelineContext>.ExecuteAsync(ref context);
}
return new InBoundLambdaMessage(lambdaMessage);
}
Actor execution stage
The actor receives the decoded message and executes the protocol pipeline.
protected override async ValueTask OnReceive(IActorMessage message, IActorRef sender)
{
if (message is InBoundLambdaMessage inBoundLambdaMessage)
{
inBoundLambdaMessage.Invoke(this);
}
}
Final handler execution
The pipeline eventually invokes the protocol handler.
[ProtocolName("Login")]
public async Task Process(PlayerActor actor, Login packet)
{
var currentState = actor.GetCurrentState();
await currentState.HandlePacketAsync(packet);
}
Execution Summary
Register
→ Protocol binding
→ Body type extraction
→ Middleware registration
Receive packet
→ Decode packet
→ Resolve BodyType
→ Deserialize body
→ Create actor message
→ Post to actor mailbox
→ Execute pipeline
→ Run middleware
→ Invoke handler
→ Actor state logic
Key Characteristics
- Packet decoding happens before actor execution
- Actor logic remains lightweight
- Middleware executes inside the actor context
- No shared state across actors
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. 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 is compatible. 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 is compatible. 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. |
-
net10.0
- Dignus.Sockets (>= 1.6.1)
-
net8.0
- Dignus.Sockets (>= 1.6.1)
-
net9.0
- Dignus.Sockets (>= 1.6.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Dignus.ActorServer:
| Package | Downloads |
|---|---|
|
Dignus.Commands
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.2.3 | 0 | 3/19/2026 |
| 1.2.2 | 33 | 3/18/2026 |
| 1.2.1 | 106 | 3/15/2026 |
| 1.2.0 | 80 | 3/14/2026 |
| 1.1.12 | 83 | 3/14/2026 |
| 1.1.11 | 76 | 3/14/2026 |
| 1.1.10 | 78 | 3/14/2026 |
| 1.1.9 | 114 | 3/14/2026 |
| 1.1.8 | 114 | 3/11/2026 |
| 1.1.7 | 123 | 3/8/2026 |
| 1.1.6 | 83 | 2/28/2026 |
| 1.1.5 | 85 | 2/24/2026 |
| 1.1.4 | 86 | 2/22/2026 |
| 1.1.3 | 88 | 2/21/2026 |
| 1.1.2 | 100 | 2/21/2026 |
| 1.1.1 | 83 | 2/21/2026 |
| 1.1.0 | 87 | 2/19/2026 |
| 1.0.0 | 93 | 2/15/2026 |