LAN.Lib
1.1.51
See the version list below for details.
dotnet add package LAN.Lib --version 1.1.51
NuGet\Install-Package LAN.Lib -Version 1.1.51
<PackageReference Include="LAN.Lib" Version="1.1.51" />
<PackageVersion Include="LAN.Lib" Version="1.1.51" />
<PackageReference Include="LAN.Lib" />
paket add LAN.Lib --version 1.1.51
#r "nuget: LAN.Lib, 1.1.51"
#:package LAN.Lib@1.1.51
#addin nuget:?package=LAN.Lib&version=1.1.51
#tool nuget:?package=LAN.Lib&version=1.1.51
LAN.Lib
Zero-dependency LAN peer discovery for .NET: a symmetric UDP announce beacon plus a
self-expiring peer table, over a single shared broadcast domain, filtered by service name.
TimeProvider-driven (so beacon cadence and expiry are deterministic in tests), AOT/trim
friendly, with a one-line DI extension for the .NET generic host.
Extracted and generalised from the LAN-play discovery in the chess project.
What it does
- Symmetric discovery. Every node broadcasts a small ASCII announce beacon (1 s) and
listens for everyone else's, keeping a live table of peers that self-expires (5 s) when a
node goes quiet. Both cadences run off an injected
TimeProvider. - One shared broadcast domain. All apps broadcast on one UDP port (
52821) with one magic prefix; a consumer filters to the service it cares about (IPeerTable.PeersOf("...")).ReuseAddresslets several apps share the port on one host — no port-per-app. - Stable node identity. A node can mint a persisted node id once (
StableNodeIdPath) and advertise it in every beacon, so a consumer can bind to a node and recognise it across restarts even as its address changes. Separate from the per-process peer id, which exists only to filter a node's own beacon echo. - Extensible. The announce carries an open
key=valueproperty bag (URL-encoded values), so an app can advertise extra facts — a version, a capability flag — with no wire-format bump. - Foreign-datagram safe. A magic + version prefix means a datagram that isn't ours (or is malformed) is ignored, never misparsed — the shared port coexists with anything else on it.
Discovery is UDP-only by design: its whole job is to tell an app which address:port to open a session/control channel to (TCP, WebSocket, HTTP, …). That channel is the app's concern.
Usage
using LAN.Lib;
// On a node that others discover and bind to (e.g. a headless server):
services.AddLanDiscovery(o =>
{
o.ServiceName = "tianwen-server"; // announced + filtered on
o.ServicePort = 1888; // the port peers should reach us at
o.NodeName = Environment.MachineName; // human display name
o.StableNodeIdPath = Path.Combine(appData, "node-id.txt"); // mint-once, persisted
});
// On a consumer that only wants to see who's out there (never appears itself):
services.AddLanDiscovery(o =>
{
o.ServiceName = "tianwen-gui";
o.Announce = false; // listen-only
});
// Anywhere, read the live peer list (a fresh snapshot each call; Changed hints when to re-read):
IPeerTable peers = provider.GetRequiredService<IPeerTable>();
foreach (var peer in peers.PeersOf("tianwen-server"))
Console.WriteLine($"{peer.DisplayName} @ {peer.EndPoint} (node {peer.NodeId})");
AddLanDiscovery registers ILanTransport (via TryAdd, so a bespoke/fake transport can be
registered first), the LanDiscovery beacon + peer table (as IPeerTable), and a hosted
service that runs them for the host's lifetime (sending a polite bye on shutdown).
Testing
LanDiscovery needs no host and no real sockets: construct it directly with an in-memory
ILanTransport and a FakeTimeProvider, then Advance the clock to drive beacon cadence and
expiry deterministically. See src/LAN.Lib.Tests.
License
MIT — see LICENSE.
| Product | Versions 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. |
-
net10.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.