home / skills / stuartf303 / sorcha / signalr

signalr skill

/.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 signalr

Review the files below or copy the command above to add this skill to your agents.

Files (3)
SKILL.md
3.9 KB
---
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"

Overview

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.

How this skill works

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.

When to use it

  • Add real-time notifications for workflow or ledger events
  • Create hub endpoints that broadcast to specific subscriber groups
  • Integrate WebSocket-based event delivery into microservices
  • Test WebSocket connectivity and end-to-end notification flows
  • Scale notifications across instances with a backplane (e.g., Redis)

Best practices

  • Use strongly-typed hub interfaces for compile-time safety and discoverability
  • Keep business logic out of Hub classes; use service abstractions and IHubContext
  • Protect hub endpoints with JWT; pass tokens via the access_token query param when needed
  • Route messages via groups (wallet:, register:, tenant:) to limit broadcast scope
  • Register hubs after authentication middleware and consider a Redis backplane for horizontal scale

Example use cases

  • Notify a wallet owner when an action or transaction is confirmed using Group('wallet:{address}')
  • Subscribe clients to register events and broadcast RegisterCreated or TransactionConfirmed messages
  • Expose a hub endpoint for a UI to receive real-time workflow state changes
  • Write integration tests that start a HubConnection, subscribe, and assert messages are received
  • Broadcast tenant-wide announcements to all tenants using Group('tenant:{id}')

FAQ

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.