TurboModbus 0.1.0

dotnet add package TurboModbus --version 0.1.0
                    
NuGet\Install-Package TurboModbus -Version 0.1.0
                    
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="TurboModbus" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="TurboModbus" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="TurboModbus" />
                    
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 TurboModbus --version 0.1.0
                    
#r "nuget: TurboModbus, 0.1.0"
                    
#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 TurboModbus@0.1.0
                    
#: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=TurboModbus&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=TurboModbus&version=0.1.0
                    
Install as a Cake Tool

TurboModbus

turboModbus

High-performance Modbus TCP client built on Akka.Streams. Clean async API for simple use cases, raw stream access for reactive pipelines.

Install

dotnet add package TurboModbus

Quick Start

using Akka.Actor;
using TurboModbus;

var system = ActorSystem.Create("my-app");
var client = new ModbusClient(system, new ModbusClientOptions
{
    Host = "192.168.1.100",
    Port = 502,
    UnitId = 1,
});

client.Connect();

// Read
ushort[] registers = await client.ReadAsync(1000, 4);
ushort[] inputRegs = await client.ReadAsync(4122, 2, inputRegister: true);

// Write
await client.WriteAsync(1005, 1);          // single register
await client.WriteAsync(1032, 0x00, 0x2E); // multiple registers

client.Dispose();

Polling with Change Detection

Subscribe to register changes with a fluent polling API:

Source<RegisterResponse, UniqueKillSwitch> source = client.Poll(
    TimeSpan.FromSeconds(10),
    poll => poll
        .Registers(1000, 4)
        .Registers(1050, 2)
        .Registers(4122, 2, inputRegister: true));

// Compose into any Akka.Streams pipeline
var killSwitch = source
    .RunForEach(r => Console.WriteLine($"[{r.Address}] = {r.Registers[0]}"), materializer);

The source emits RegisterResponse on every poll. Apply the built-in ChangeDetectionStage to only get changes:

source
    .Via(new ChangeDetectionStage())
    .RunForEach(r => Console.WriteLine($"Changed: [{r.Address}]"), materializer);

Architecture

ModbusClient (public API)
  -> StreamOwnerActor (owns stream lifecycle)
      -> Source.Queue -> ModbusCodec BidiFlow -> TCP -> MbapFramingStage -> Response correlation
  • Akka.Streams TCP transport with proper backpressure
  • MBAP framing via custom GraphStage (length-based, no delimiter parsing)
  • Transaction ID correlation handled internally (never exposed in public API)
  • DeathWatch on the stream owner -- client.IsConnected reflects actual connection state
  • Disconnected event fires when the TCP connection drops

Connection Lifecycle

client.Connect();               // creates StreamOwnerActor, materializes TCP stream
Console.WriteLine(client.IsConnected); // true

client.Disconnected += () => Console.WriteLine("Connection lost");

client.Dispose();               // stops actors, cleans up
Console.WriteLine(client.IsConnected); // false

The stream owner actor is supervised by the ActorSystem. Killing the stream does not kill the ActorSystem.

Raw Stream Access

For full control, use ModbusCodec directly:

// Get a Flow<ReadRequest, RegisterResponse> connected to a device
var readFlow = ModbusCodec.ReadFlow(system, "192.168.1.100", 502, unitId: 1);
Product Compatible and additional computed target framework versions.
.NET 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.0 0 5/22/2026