RhpV2.Client
0.2.2
dotnet add package RhpV2.Client --version 0.2.2
NuGet\Install-Package RhpV2.Client -Version 0.2.2
<PackageReference Include="RhpV2.Client" Version="0.2.2" />
<PackageVersion Include="RhpV2.Client" Version="0.2.2" />
<PackageReference Include="RhpV2.Client" />
paket add RhpV2.Client --version 0.2.2
#r "nuget: RhpV2.Client, 0.2.2"
#:package RhpV2.Client@0.2.2
#addin nuget:?package=RhpV2.Client&version=0.2.2
#tool nuget:?package=RhpV2.Client&version=0.2.2
rhp2lib-net
A C# client library (multi-targets .NET 8 and .NET 10), test harness, and command-line toolkit for RHPv2 โ the JSON-over-TCP "Remote Host Protocol" used by XRouter to expose its multi-protocol packet engine to applications.
๐ Full documentation: https://rhp2lib.pages.dev/
๐ฆ Install: dotnet add package RhpV2.Client ยท
self-contained rhp CLI binaries for Linux / Windows / macOS at
GitHub Releases.
The protocol is described in PWP-0222 and PWP-0245 (Paula Dowie, G8PZT et al., June 2023).
Layout
src/RhpV2.Client/ reusable client library + in-process mock server
src/RhpV2.Tools/ `rhp` CLI (chat, mon, send, probe, serve)
tests/RhpV2.Client.Tests/ xunit suite (framing, codecs, mock-driven)
tests/RhpV2.Client.IntegrationTests/ Testcontainers suite โ drives ghcr.io/packethacking/xrouter
The library
using RhpV2.Client;
using RhpV2.Client.Protocol;
await using var rhp = await RhpClient.ConnectAsync("xrouter.local");
await rhp.AuthenticateAsync("g8pzt", "secret");
rhp.Received += (_, e) =>
Console.WriteLine($"<- {e.Message.Data}");
var handle = await rhp.OpenAsync(
ProtocolFamily.Ax25, SocketMode.Stream,
port: "1", local: "G8PZT", remote: "GB7PZT",
flags: OpenFlags.Active);
await rhp.SendOnHandleAsync(handle, "hello\r");
Highlights:
- Length-prefixed (2-byte big-endian) framing, exact to spec.
- Strongly-typed messages (
AuthMessage,OpenMessage,RecvMessage, โฆ). - Async request/reply correlation via auto-assigned
idfield. - Asynchronous notifications surfaced as events (
Received,Accepted,StatusChanged,Closed,UnknownReceived,Disconnected). - Tolerates spec quirks (
errCodeon AUTHREPLY,ConnectReplyPascalCase). - Forward-compatible: unknown message types arrive as
UnknownMessage.
CLI (rhp)
rhp probe --host xrouter.local --port 9000 --user g8pzt --pass โฆ
rhp chat --pfam ax25 --radio 1 --local G8PZT --remote GB7PZT
rhp mon --pfam ax25 --radio 1 # TRACE-mode monitor
rhp send --pfam ax25 --radio 1 --local G8PZT --remote G8PZT-1 "Hi"
rhp serve --port 9000 # local mock for dev
All commands share a common --host/--port/--user/--pass vocabulary.
Tests / harness
The MockRhpServer (in RhpV2.Client.Testing) is shipped with the library
itself so downstream applications can write integration tests without
spinning up a real XRouter:
await using var server = new MockRhpServer();
server.Start();
await using var client =
await RhpClient.ConnectAsync("127.0.0.1", server.Endpoint.Port);
// ... drive any sequence you like; assert against server.ReceivedFrames.
The same mock backs rhp serve, so the CLI doubles as a self-test driver.
Build & test
dotnet build
dotnet test
- Unit suite (49 tests; runs everywhere): framing, codec, polymorphic JSON dispatch, correlated request/reply, server-pushed notifications, transport teardown.
- Integration suite (36 tests; requires Docker): pulls
ghcr.io/packethacking/xroutervia Testcontainers and pins the client against the real RHP server. A two-container fixture links the nodes by AXUDP and seeds the NetRom routing table so routing works on first boot. Coverage spans: AX.25 stream connect / send / recv / close (real SABM/UA/I/RR); passive listener accepting an inbound peer connection; peer-initiated close firingClosed; TRACE-mode frame capture (frametype,srce/dest,ctrl,pid,ptcl); RAW-mode complete on-the-wire frames; DGRAM (UI frame)sendtowith binary-byte round-trip; NetRom stream connect through to the peer's command processor;pfam=inetstream GET to xrouter's HTTP server with server-initiated close;seqpkt/customsocket allocation; connect-to-unreachable lifecycle (FRACK retries โ status=0 โ close); BUSY flag insendReply.statuson large writes;Duplicate socketon duplicate listen; handle namespace global across connections. The fixture fails loudly if Docker isn't reachable โ there's no silent skip, so a green run actually means the integration paths were exercised.
| 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 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 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
- No dependencies.
-
net8.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 |
|---|---|---|
| 0.2.2 | 364 | 5/4/2026 |