Cocoar.SignalARRR.ProxyGenerator
4.0.0-beta.8
dotnet add package Cocoar.SignalARRR.ProxyGenerator --version 4.0.0-beta.8
NuGet\Install-Package Cocoar.SignalARRR.ProxyGenerator -Version 4.0.0-beta.8
<PackageReference Include="Cocoar.SignalARRR.ProxyGenerator" Version="4.0.0-beta.8" />
<PackageVersion Include="Cocoar.SignalARRR.ProxyGenerator" Version="4.0.0-beta.8" />
<PackageReference Include="Cocoar.SignalARRR.ProxyGenerator" />
paket add Cocoar.SignalARRR.ProxyGenerator --version 4.0.0-beta.8
#r "nuget: Cocoar.SignalARRR.ProxyGenerator, 4.0.0-beta.8"
#:package Cocoar.SignalARRR.ProxyGenerator@4.0.0-beta.8
#addin nuget:?package=Cocoar.SignalARRR.ProxyGenerator&version=4.0.0-beta.8&prerelease
#tool nuget:?package=Cocoar.SignalARRR.ProxyGenerator&version=4.0.0-beta.8&prerelease
SignalARRR
Typed bidirectional RPC over ASP.NET Core SignalR.
Both server and client can call each other's methods through shared interfaces, with compile-time proxy generation, streaming, cancellation propagation, and ASP.NET Core authorization.
Features
- Typed bidirectional RPC — server calls client methods, client calls server methods, both through shared interfaces
- Compile-time proxy generation — Roslyn source generator produces proxies from
[SignalARRRContract]interfaces (zero reflection) - Organized hub methods — split hub logic across multiple
ServerMethods<T>classes with full DI support - Streaming —
IAsyncEnumerable<T>,IObservable<T>, andChannelReader<T>in both directions - CancellationToken propagation — server can cancel client operations remotely
- Authorization — method-level, class-level, and hub-level
[Authorize]with automatic inheritance - Server-to-client calls from anywhere — inject
ClientManagerin controllers, background services, etc. - TypeScript / JavaScript client —
@cocoar/signalarrrnpm package with full v4 protocol support - Optional runtime proxy fallback —
DispatchProxy-based package for plugin/dynamic scenarios
Packages
.NET
| Package | Purpose |
|---|---|
Cocoar.SignalARRR.Contracts |
[SignalARRRContract] attribute + source generator — reference from shared interface projects |
Cocoar.SignalARRR.Server |
Server-side: HARRR hub, ServerMethods, authorization, ClientManager |
Cocoar.SignalARRR.Client |
Client-side: HARRRConnection, typed proxies, event handlers |
Cocoar.SignalARRR.DynamicProxy |
Opt-in runtime proxy fallback via DispatchProxy |
JavaScript / TypeScript
| Package | Purpose |
|---|---|
@cocoar/signalarrr |
TypeScript/JavaScript client: HARRRConnection, invoke, send, stream, onServerMethod |
Quick Start
1. Define shared interfaces
In your shared project, reference Cocoar.SignalARRR.Contracts:
[SignalARRRContract]
public interface IChatHub {
Task SendMessage(string user, string message);
Task<List<string>> GetHistory();
IAsyncEnumerable<string> StreamMessages(CancellationToken ct);
}
[SignalARRRContract]
public interface IChatClient {
void ReceiveMessage(string user, string message);
Task<string> GetClientName();
}
2. Server setup
// Program.cs
builder.Services.AddSignalR();
builder.Services.AddSignalARRR(options => options
.AddServerMethodsFrom(typeof(Program).Assembly));
app.UseRouting();
app.MapHARRRController<ChatHub>("/chathub");
// Hub (can be empty — methods go in ServerMethods classes)
public class ChatHub : HARRR {
public ChatHub(IServiceProvider sp) : base(sp) { }
}
// Server methods (auto-discovered, DI works)
public class ChatMethods : ServerMethods<ChatHub>, IChatHub {
public Task SendMessage(string user, string message) { ... }
public Task<List<string>> GetHistory() { ... }
public async IAsyncEnumerable<string> StreamMessages(
[EnumeratorCancellation] CancellationToken ct) {
while (!ct.IsCancellationRequested) {
yield return $"msg-{DateTime.Now:ss}";
await Task.Delay(1000, ct);
}
}
}
3. .NET client setup
var connection = HARRRConnection.Create(builder => {
builder.WithUrl("https://localhost:5001/chathub");
});
await connection.StartAsync();
// Typed calls
var chat = connection.GetTypedMethods<IChatHub>();
await chat.SendMessage("Alice", "Hello!");
var history = await chat.GetHistory();
// Streaming
await foreach (var msg in chat.StreamMessages(cancellationToken)) {
Console.WriteLine(msg);
}
4. TypeScript / JavaScript client setup
npm install @cocoar/signalarrr
import { HARRRConnection } from '@cocoar/signalarrr';
const connection = HARRRConnection.create(builder => {
builder.withUrl('https://localhost:5001/chathub');
builder.withAutomaticReconnect();
});
await connection.start();
// Invoke with return value
const history = await connection.invoke<string[]>('ChatMethods.GetHistory');
// Fire-and-forget
await connection.send('ChatMethods.SendMessage', 'Alice', 'Hello!');
// Stream
connection.stream<string>('ChatMethods.StreamMessages').subscribe({
next: msg => console.log(msg),
complete: () => console.log('done'),
});
// Handle server-to-client calls
connection.onServerMethod('GetClientName', () => navigator.userAgent);
5. Server-to-client calls
// Inside ServerMethods — use ClientContext
var client = ClientContext.GetTypedMethods<IChatClient>();
var name = await client.GetClientName();
// Outside hub context — inject ClientManager
public class NotificationService {
private readonly ClientManager _clients;
public NotificationService(ClientManager clients) => _clients = clients;
public void Notify(string connectionId) {
var client = _clients.GetTypedMethods<IChatClient>(connectionId);
client.ReceiveMessage("System", "Hello from server!");
}
}
Framework Support
| Target | Version |
|---|---|
| .NET (server + client) | .NET 10 |
| TypeScript / JavaScript | @microsoft/signalr v10, Node.js 22 / modern browsers |
Building from Source
# .NET
dotnet build src/Cocoar.SignalARRR.slnx
dotnet test src/Cocoar.SignalARRR.slnx
# TypeScript
cd src/Cocoar.SignalARRR.Typescript
npm install && npm run build
Documentation
- Getting Started
- Server API
- Client API — .NET and TypeScript
- Streaming
- Authorization
- Proxy Generation
- Migration from v2.x
License
MIT License — see LICENSE for details.
Contributing
See CONTRIBUTING.md for guidelines.
Maintainer: Bernhard Windisch
| 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
- System.Reactive.Linq (>= 6.1.0)
NuGet packages (4)
Showing the top 4 NuGet packages that depend on Cocoar.SignalARRR.ProxyGenerator:
| Package | Downloads |
|---|---|
|
Cocoar.SignalARRR.Contracts
Contracts, attributes and source generator for SignalARRR proxy generation. Reference this package from any project that defines [SignalARRRContract] interfaces. |
|
|
Cocoar.SignalARRR.DynamicProxy
Dynamic proxy fallback for Cocoar.SignalARRR — uses DispatchProxy for runtime interface proxy generation. Opt-in package for scenarios where compile-time source generation is not available. |
|
|
Cocoar.SignalARRR.Server
SignalARRR server library — typed bidirectional RPC over SignalR with authorization, streaming, server-to-client calls, and ServerMethods organization. |
|
|
Cocoar.SignalARRR.Client
SignalARRR client library — typed bidirectional RPC over SignalR with streaming, cancellation, and source-generated proxies. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 4.0.0-beta.8 | 36 | 3/3/2026 |
| 4.0.0-beta.6 | 35 | 3/3/2026 |
| 4.0.0-beta.2 | 38 | 3/3/2026 |
| 0.1.0-beta.85 | 44 | 2/28/2026 |