Shiny.BluetoothLE.Hubs 1.0.0-alpha-0004-gbc068ff52e

Prefix Reserved
This is a prerelease version of Shiny.BluetoothLE.Hubs.
dotnet add package Shiny.BluetoothLE.Hubs --version 1.0.0-alpha-0004-gbc068ff52e
                    
NuGet\Install-Package Shiny.BluetoothLE.Hubs -Version 1.0.0-alpha-0004-gbc068ff52e
                    
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="Shiny.BluetoothLE.Hubs" Version="1.0.0-alpha-0004-gbc068ff52e" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Shiny.BluetoothLE.Hubs" Version="1.0.0-alpha-0004-gbc068ff52e" />
                    
Directory.Packages.props
<PackageReference Include="Shiny.BluetoothLE.Hubs" />
                    
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 Shiny.BluetoothLE.Hubs --version 1.0.0-alpha-0004-gbc068ff52e
                    
#r "nuget: Shiny.BluetoothLE.Hubs, 1.0.0-alpha-0004-gbc068ff52e"
                    
#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 Shiny.BluetoothLE.Hubs@1.0.0-alpha-0004-gbc068ff52e
                    
#: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=Shiny.BluetoothLE.Hubs&version=1.0.0-alpha-0004-gbc068ff52e&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Shiny.BluetoothLE.Hubs&version=1.0.0-alpha-0004-gbc068ff52e&prerelease
                    
Install as a Cake Tool

Shiny.BluetoothLE.Hubs

Shiny.BluetoothLE.Hubs gives you SignalR-style hubs over Bluetooth LE. One device hosts a hub, and nearby devices discover it, connect, and call it through a source-generated, strongly typed proxy. The host pushes events back to everyone, to some clients, or to groups. Files move over L2CAP, a faster direct channel between the devices.

It's built on Shiny.BluetoothLE and Shiny.BluetoothLE.Hosting, and it is AOT- and trim-safe with no reflection.

// shared contract
[BleHubClient]
public interface IGameHub
{
    Task<MoveResult> MakeMove(int cell);                          // client -> host
    IAsyncEnumerable<int> Countdown(int from, CancellationToken ct);
    event Action<GameState> StateChanged;                         // host -> clients
}

// host
public class GameHub(GameEngine engine) : BleHub<IGameHub>
{
    public async Task<MoveResult> MakeMove(int cell)
    {
        // Context.Client, Context.Abort(), Groups, OnConnectedAsync/OnDisconnectedAsync
        await Clients.All.StateChanged(engine.Snapshot());        // generated typed push
        return new MoveResult(true, null);
    }
    ...
}

// client - GameHubClient is generated
client.Hub.StateChanged += state => ...;
await client.Connect(host, new BleHubConnectOptions("Allan"));
var result = await client.Hub.MakeMove(4);
await client.UploadFile(path, "avatar.jpg");                      // L2CAP

Packages

Project Purpose
Shiny.BluetoothLE.Hubs Wire protocol (framing, chunking, reassembly), argument codec, serializer, [BleHubClient]. Ships the source generator
Shiny.BluetoothLE.Hubs.Host BleHub<T>, IBleHubHost, IHubContext<THub>, groups, L2CAP file server
Shiny.BluetoothLE.Hubs.Client BleHubClient (base of the generated proxies), discovery, shared connections, file upload and download

Setup

Json.AddContext(MyJsonContext.Default);     // hub arguments/results are AOT-safe JSON by default

// host
services.AddBluetoothLeHosting();
services.AddBleHub<GameHub>(ServiceUuid, CharacteristicUuid, o => o.MaxClients = 6);
services.ConfigureBleHubHost(o => o.EnableFileTransfers(Path.Combine(FileSystem.AppDataDirectory, "files")));
await serviceProvider.GetRequiredService<IBleHubHost>().Start();

// client
services.AddBluetoothLE();
services.AddBleHubClient<IGameHub>(ServiceUuid, CharacteristicUuid);   // inject IBleHubClient<IGameHub>, GameHubClient or IGameHub
  • Contract: hub methods return Task, Task<T> or IAsyncEnumerable<T>. A trailing CancellationToken is passed through to the host. Events are Action / Action<T1..T4>. Compile errors are reported as SBH001–SBH006.
  • Hubs: a new hub instance runs, in its own DI scope, for every call, like SignalR. The hub may take the contract's CancellationToken or leave it out.
  • Outside a hub: inject IHubContext<GameHub> and call context.Clients.All.StateChanged(state). Clients is a generated C# 14 extension property.
  • Start/stop:
    • IBleHubHost.Start() / Stop() start or stop every hub.
    • IHubContext<THub>.Start() / Stop(reason) control one hub. A stopped hub disconnects its clients and refuses new ones.
    • A GATT service shared by several hubs stays up while any of them is running.
    • The advertisement follows the running hubs.
  • Disconnect is cooperative, because iOS peripherals can't drop a central. Context.Abort() and IHubContext.Disconnect() ask the client to leave. The client library does so and raises Disconnected with the reason.
  • Multiple hubs: each hub needs its own characteristic. Sharing one service UUID is recommended so the advertisement holds only one 128-bit UUID. Hub clients on the same device share one BLE connection.

See PLAN.md for the wire protocol, the design decisions and the roadmap.

Sample: Tic Tac Toe

samples/TicTacToe is a .NET MAUI app for iOS and Android that uses Shiny.Maui.Shell.

  • One phone taps Host a game and plays X.
  • The next phone to tap Join a game plays O. Later phones join the spectators group.
  • Moves are hub calls, and board updates and emotes are hub pushes.
  • Avatars are uploaded and downloaded over L2CAP.

BLE needs two physical devices: simulators and emulators have no usable Bluetooth.

dotnet build samples/TicTacToe -f net10.0-android -t:Run
dotnet build samples/TicTacToe -f net10.0-ios -t:Run

Tests

dotnet test tests/Shiny.BluetoothLE.Hubs.Tests

The tests run the generated hub dispatcher and the generated client proxy against each other through an in-memory "radio", plus diagnostic tests for the generator. No hardware is needed.

Documentation and release notes: https://shinylib.net/blehubs/

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 (2)

Showing the top 2 NuGet packages that depend on Shiny.BluetoothLE.Hubs:

Package Downloads
Shiny.BluetoothLE.Hubs.Client

Shiny.BluetoothLE.Hubs client - discovers BLE hub hosts and calls them through generated, strongly typed proxies

Shiny.BluetoothLE.Hubs.Host

Shiny.BluetoothLE.Hubs host - SignalR style hubs served over a BLE GATT server, plus L2CAP file transfers

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0-alpha-0004-gbc068ff52e 28 10/3/2026
1.0.0-alpha-0004 27 10/3/2026