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

Prefix Reserved
This is a prerelease version of Shiny.BluetoothLE.Hubs.Host.
dotnet add package Shiny.BluetoothLE.Hubs.Host --version 1.0.0-alpha-0004-gbc068ff52e
                    
NuGet\Install-Package Shiny.BluetoothLE.Hubs.Host -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.Host" 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.Host" Version="1.0.0-alpha-0004-gbc068ff52e" />
                    
Directory.Packages.props
<PackageReference Include="Shiny.BluetoothLE.Hubs.Host" />
                    
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.Host --version 1.0.0-alpha-0004-gbc068ff52e
                    
#r "nuget: Shiny.BluetoothLE.Hubs.Host, 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.Host@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.Host&version=1.0.0-alpha-0004-gbc068ff52e&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Shiny.BluetoothLE.Hubs.Host&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

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
1.0.0-alpha-0004-gbc068ff52e 0 10/3/2026
1.0.0-alpha-0004 0 10/3/2026