home / skills / stuartf303 / sorcha / signalr
/.claude/skills/signalr
This skill enables real-time client-server communication with SignalR, broadcasting notifications and register events to groups with JWT authentication.
npx playbooks add skill stuartf303/sorcha --skill signalrReview the files below or copy the command above to add this skill to your agents.
---
name: signalr
description: |
Implements real-time WebSocket communication using SignalR for action notifications and register events.
Use when: Adding real-time notifications, creating hub endpoints, broadcasting to groups, or testing WebSocket communication.
allowed-tools: Read, Edit, Write, Glob, Grep, Bash, mcp__context7__resolve-library-id, mcp__context7__query-docs
---
# SignalR Skill
ASP.NET Core SignalR implementation for real-time client-server communication. Sorcha uses two hubs: `ActionsHub` (Blueprint Service) for workflow notifications and `RegisterHub` (Register Service) for ledger events. Both use group-based broadcasting with JWT authentication via query parameters.
## Quick Start
### Hub Implementation
```csharp
// Strongly-typed hub with client interface
public class RegisterHub : Hub<IRegisterHubClient>
{
public async Task SubscribeToRegister(string registerId)
{
await Groups.AddToGroupAsync(Context.ConnectionId, $"register:{registerId}");
}
}
public interface IRegisterHubClient
{
Task RegisterCreated(string registerId, string name);
Task TransactionConfirmed(string registerId, string transactionId);
}
```
### Sending from Services
```csharp
public class NotificationService
{
private readonly IHubContext<ActionsHub> _hubContext;
public async Task NotifyActionConfirmedAsync(ActionNotification notification, CancellationToken ct)
{
await _hubContext.Clients
.Group($"wallet:{notification.WalletAddress}")
.SendAsync("ActionConfirmed", notification, ct);
}
}
```
### Client Connection (Testing)
```csharp
var connection = new HubConnectionBuilder()
.WithUrl($"{baseUrl}/actionshub?access_token={jwt}")
.Build();
connection.On<ActionNotification>("ActionConfirmed", notification => { /* handle */ });
await connection.StartAsync();
await connection.InvokeAsync("SubscribeToWallet", walletAddress);
```
## Key Concepts
| Concept | Usage | Example |
|---------|-------|---------|
| Groups | Route messages to subscribers | `wallet:{address}`, `register:{id}`, `tenant:{id}` |
| Typed Hubs | Compile-time safety | `Hub<IRegisterHubClient>` |
| IHubContext | Send from services | Inject `IHubContext<THub>` |
| JWT Auth | Query parameter auth | `?access_token={jwt}` |
## Common Patterns
### Service Abstraction Over Hub
**When:** Decoupling business logic from SignalR implementation
```csharp
// Interface in Services/Interfaces/
public interface INotificationService
{
Task NotifyActionAvailableAsync(ActionNotification notification, CancellationToken ct = default);
}
// Register in DI
builder.Services.AddScoped<INotificationService, NotificationService>();
```
### Hub Registration in Program.cs
```csharp
builder.Services.AddSignalR();
// Map after authentication middleware
app.MapHub<ActionsHub>("/actionshub");
app.MapHub<RegisterHub>("/hubs/register");
```
## See Also
- [patterns](references/patterns.md) - Hub patterns, group routing, typed clients
- [workflows](references/workflows.md) - Testing, scaling, authentication setup
## Related Skills
- **aspire** - Service orchestration and configuration
- **jwt** - Authentication token setup for hub connections
- **redis** - Backplane configuration for scaling
- **xunit** - Integration testing patterns
- **fluent-assertions** - Test assertions for hub tests
## Documentation Resources
> Fetch latest SignalR documentation with Context7.
**How to use Context7:**
1. Use `mcp__context7__resolve-library-id` to search for "signalr aspnetcore"
2. **Prefer website documentation** (IDs starting with `/websites/`) over source code
3. Query with `mcp__context7__query-docs` using the resolved library ID
**Library ID:** `/websites/learn_microsoft_en-us_aspnet_core` _(ASP.NET Core docs including SignalR)_
**Recommended Queries:**
- "SignalR hub groups authentication"
- "SignalR Redis backplane scaling"
- "SignalR strongly typed hubs"This skill implements real-time WebSocket communication using ASP.NET Core SignalR to deliver action notifications and register events. It provides two typed hubs (ActionsHub and RegisterHub) with group-based broadcasting and JWT-based authentication via query parameters. Use it to add low-latency notifications, hub endpoints, and group-targeted broadcasts within a C# service architecture.
The skill exposes typed Hub classes (e.g., Hub<IRegisterHubClient>) so server code can push strongly-typed messages to connected clients. Clients connect with a URL containing an access_token query parameter and subscribe to groups (wallet:{address}, register:{id}, tenant:{id}). Server-side services inject IHubContext<THub> to send messages to groups or individual connections, decoupling business logic from SignalR wiring.
How do clients authenticate to hubs?
Clients include a JWT in the access_token query parameter when building the HubConnection URL; server-side middleware validates the token.
How can services send messages without a Hub instance?
Inject IHubContext<THub> into services and use Clients.Group/Clients.User to send messages from background services or controllers.