BlackHole.Messaging 3.0.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package BlackHole.Messaging --version 3.0.0
                    
NuGet\Install-Package BlackHole.Messaging -Version 3.0.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="BlackHole.Messaging" Version="3.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="BlackHole.Messaging" Version="3.0.0" />
                    
Directory.Packages.props
<PackageReference Include="BlackHole.Messaging" />
                    
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 BlackHole.Messaging --version 3.0.0
                    
#r "nuget: BlackHole.Messaging, 3.0.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 BlackHole.Messaging@3.0.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=BlackHole.Messaging&version=3.0.0
                    
Install as a Cake Addin
#tool nuget:?package=BlackHole.Messaging&version=3.0.0
                    
Install as a Cake Tool

BlackHole Messaging 🕳️

NuGet .NET License CI

High-performance network messaging for .NET 10. A custom length-prefixed binary protocol over TCP with RPC, Pub/Sub, Streaming and Batching — built on System.IO.Pipelines so the steady state allocates nothing per message.

Built by Gravicode Studios, led by Kang Fadhil.

Bahasa Indonesia · English · Documentation · Benchmarks

The IoT Gateway panel with twelve devices streaming


<a name="english"></a>

🇬🇧 English

Install

dotnet add package BlackHole.Messaging

The id BlackHole was already taken on nuget.org, so the package ships as BlackHole.Messaging. The assembly and every namespace are still BlackHole.*.

Thirty seconds

using BlackHole.Hosting;

// Server
await using var server = new BlackHoleServer(5000);
server.Rpc.RegisterText("upper", text => text.ToUpperInvariant());
server.Start();

// Client
await using var client = await BlackHoleClient.ConnectAsync("127.0.0.1", 5000);
string result = await client.Rpc.CallTextAsync("upper", "halo blackhole");   // "HALO BLACKHOLE"

// Pub/Sub, with MQTT-style wildcards
client.PubSub.Received += (topic, payload) => Console.WriteLine($"{topic}: {payload.Length} B");
await client.PubSub.SubscribeAsync("sensor/+/temperature");
await client.PubSub.PublishAsync("sensor/tank-3/temperature", "28.4");

What it does

Pattern What you get
RPC Request/response with correlation, per-call deadlines, and errors that propagate as RpcException instead of hanging. Works in both directions on one socket.
Pub/Sub Topic broker with + and # wildcards. Exact topics resolve through a dictionary; wildcards are matched allocation-free.
Streaming Send a body of any size in chunks, with a descriptor, progress reporting, and an optional sink so a large upload never has to sit in memory.
Batching Pack many small messages into one frame and one socket write. Flushes on count, size, or a delay — whichever comes first.
Keepalive Ping/pong answered by the transport, never surfaced to your handlers, with a round-trip measurement per connection.

Measured on this machine

.NET 10.0.11, Windows 11, 8 logical cores, loopback TCP, both ends in one process.

RPC round trip 41 µs p50, 110 µs p99, 21,100 calls/sec sequential
RPC with 16 connections 200,800 calls/sec
Pub/Sub fan-out 69,700 deliveries/sec across 50 subscribers
Batched publishes 2.3 M messages/sec — 22× the one-send-per-message path
Streaming 520 MiB/sec at a 16 KiB chunk size
Encode a frame 41 ns, 0 bytes allocated
Decode a frame 105 ns, 0 bytes allocated

Full numbers, method, and how to reproduce them: docs/benchmarks.md.

Run it

dotnet run --project src/BlackHole.Demo          # every pattern, end to end
dotnet run --project src/BlackHole.IoTGateway    # the Avalonia gateway panel
dotnet test tests/BlackHole.Tests                # 40 tests

The IoT Gateway simulator

An Avalonia desktop panel that runs a real BlackHole gateway and attaches as many simulated sensor devices as you like — each one a genuine client on a genuine socket. Nothing in it is mocked.

dotnet run --project src/BlackHole.IoTGateway -- --demo 12

A firmware upload streaming to the gateway while telemetry keeps flowing

Every pattern in the library is operable from the panel: devices publish telemetry, the gateway calls RPC methods back down the same connection the device dialled out on, and Firmware uploads 4 MiB as a stream while the traces keep running. See docs/iot-gateway.md.

Documentation

Getting started Install, first server, first client
Architecture How the layers fit together, and why
Protocol The wire format, byte by byte
Patterns RPC, Pub/Sub, Streaming, Batching in depth
Performance Where the allocations went, and how to keep them gone
Benchmarks Full results and how to reproduce them
IoT Gateway The simulator, and what it demonstrates
Migrating from v2 What changed and why

Bahasa Indonesia: docs/id/.


<a name="bahasa-indonesia"></a>

🇮🇩 Bahasa Indonesia

Instalasi

dotnet add package BlackHole.Messaging

Nama BlackHole sudah dipakai orang lain di nuget.org, jadi paket ini bernama BlackHole.Messaging. Nama assembly dan seluruh namespace tetap BlackHole.*.

Tiga puluh detik

using BlackHole.Hosting;

// Server
await using var server = new BlackHoleServer(5000);
server.Rpc.RegisterText("upper", text => text.ToUpperInvariant());
server.Start();

// Client
await using var client = await BlackHoleClient.ConnectAsync("127.0.0.1", 5000);
string hasil = await client.Rpc.CallTextAsync("upper", "halo blackhole");   // "HALO BLACKHOLE"

// Pub/Sub, dengan wildcard ala MQTT
client.PubSub.Received += (topik, isi) => Console.WriteLine($"{topik}: {isi.Length} B");
await client.PubSub.SubscribeAsync("sensor/+/temperature");
await client.PubSub.PublishAsync("sensor/tank-3/temperature", "28.4");

Apa saja yang tersedia

Pola Yang Anda dapat
RPC Request/response dengan korelasi, batas waktu per panggilan, dan kegagalan yang muncul sebagai RpcException — bukan menggantung selamanya. Bisa dua arah di satu soket.
Pub/Sub Broker topik dengan wildcard + dan #. Topik persis dicari lewat dictionary; wildcard dicocokkan tanpa alokasi.
Streaming Kirim data sebesar apa pun dalam potongan, lengkap dengan deskriptor, laporan progres, dan sink opsional supaya unggahan besar tidak perlu menumpuk di memori.
Batching Gabungkan banyak pesan kecil jadi satu frame dan satu tulisan soket. Dikirim saat jumlah, ukuran, atau jeda tercapai — mana yang lebih dulu.
Keepalive Ping/pong dijawab oleh transport sendiri, tidak pernah sampai ke handler Anda, sekaligus mengukur waktu bolak-balik tiap koneksi.

Hasil pengukuran di mesin ini

.NET 10.0.11, Windows 11, 8 core logis, TCP loopback, kedua sisi dalam satu proses.

Bolak-balik RPC 41 µs p50, 110 µs p99, 21.100 panggilan/detik berurutan
RPC dengan 16 koneksi 200.800 panggilan/detik
Sebaran Pub/Sub 69.700 pengiriman/detik ke 50 pelanggan
Publish ter-batch 2,3 juta pesan/detik — 22× lebih cepat daripada kirim satu per satu
Streaming 520 MiB/detik dengan potongan 16 KiB
Menyusun satu frame 41 ns, 0 byte dialokasikan
Membaca satu frame 105 ns, 0 byte dialokasikan

Angka lengkap, metode pengukuran, dan cara mengulanginya: docs/benchmarks.md.

Menjalankannya

dotnet run --project src/BlackHole.Demo          # semua pola, dari ujung ke ujung
dotnet run --project src/BlackHole.IoTGateway    # panel gateway Avalonia
dotnet test tests/BlackHole.Tests                # 40 tes

Simulator IoT Gateway

Panel desktop Avalonia yang menjalankan gateway BlackHole sungguhan dan menyambungkan sebanyak apa pun perangkat sensor simulasi — masing-masing klien sungguhan di atas soket sungguhan. Tidak ada bagian yang dipalsukan.

dotnet run --project src/BlackHole.IoTGateway -- --demo 12

Semua pola di pustaka ini bisa dioperasikan dari panel: perangkat mengirim telemetri, gateway memanggil metode RPC balik lewat koneksi yang sama yang tadi dibuka perangkat, dan tombol Firmware mengunggah 4 MiB sebagai stream sementara grafiknya tetap berjalan. Lihat docs/id/iot-gateway.md.

Dokumentasi

Dokumentasi berbahasa Indonesia ada di docs/id/: Panduan awal · Arsitektur · Protokol · Pola · Performa · IoT Gateway


License

MIT. See LICENSE.

Built by Gravicode Studios, led by Kang Fadhil.

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.
  • net10.0

    • No dependencies.

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
3.1.0 100 9/2/2026
3.0.0 99 9/2/2026

v3.0.0 - Rewritten on System.IO.Pipelines: zero-allocation steady-state framing, pooled buffers, async message router, RPC timeouts and error propagation, keepalive, auto-flush batching, and connection statistics. Targets .NET 10.