Postpartum-genushyacinthus29/dotnet-skills/skills/dotnet-signalr/SKILL.md
dotnet-signalr
Implement or review SignalR hubs, streaming, reconnection, transport, and real-time delivery patterns in ASP.NET Core applications.
- Source repository stars
- 9
- Declared platforms
- 0
- Static risk flags
- 1
- Last source update
- 2026-08-26
- Source checked
- 2026-08-28
Decision brief
What it does: where it fits
Implement or review SignalR hubs, streaming, reconnection, transport, and real-time delivery patterns in ASP. NET Core applications.
Not for
- Tasks that require unconfirmed production actions or broad system permissions.
- Environments where the pinned source and install steps cannot be inspected.
Compatibility matrix
Platform support, with evidence labels
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
Inspect first. Install second.
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/Postpartum-genushyacinthus29/dotnet-skills --skill "skills/dotnet-signalr"Inspect the Agent Skill "dotnet-signalr" from https://github.com/Postpartum-genushyacinthus29/dotnet-skills/blob/e520b1e9a27485d8b5f3ec0b71dfcd85ab371a40/skills/dotnet-signalr/SKILL.md at commit e520b1e9a27485d8b5f3ec0b71dfcd85ab371a40. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
What the source asks the agent to do
- 01
Workflow
1. Use SignalR for broadcast-style or connection-oriented real-time features; do not force gRPC into hub-style fan-out scenarios. 2. Model hub contracts intentionally and keep hub methods thin, delegating durable work elsewhere. 3. Plan for reconnection, backpressure, auth, and…
Use SignalR for broadcast-style or connection-oriented real-time features; do not force gRPC into hub-style fan-out scenarios.Model hub contracts intentionally and keep hub methods thin, delegating durable work elsewhere.Plan for reconnection, backpressure, auth, and fan-out costs instead of treating real-time messaging as stateless request/response. - 02
Trigger On
building chat, notification, collaboration, or live-update features
building chat, notification, collaboration, or live-update featuresdebugging hub lifetime, connection state, or transport issuesdeciding whether SignalR or another transport better fits the scenario - 03
Documentation
ASP.NET Core SignalR Overview
ASP.NET Core SignalR OverviewSignalR HubsSignalR API Design Considerations - 04
Hub Patterns
Review the “Hub Patterns” section in the pinned source before continuing.
Review and apply the “Hub Patterns” source section. - 05
Strongly-Typed Hub (Recommended)
Review the “Strongly-Typed Hub (Recommended)” section in the pinned source before continuing.
Review and apply the “Strongly-Typed Hub (Recommended)” source section.
Permission review
Static risk signals and limitations
Network access
The documentation includes network, browsing, or remote request actions.
.WithUrl("https://localhost:5001/chatHub", options =>Evidence record
Why each signal appears
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 93/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 9 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Provenance and original SKILL.md
- Repository
- Postpartum-genushyacinthus29/dotnet-skills
- Skill path
- skills/dotnet-signalr/SKILL.md
- Commit
- e520b1e9a27485d8b5f3ec0b71dfcd85ab371a40
- License
- MIT
- Collected
- 2026-08-28
- Default branch
- main
View the original SKILL.md
SignalR
Trigger On
- building chat, notification, collaboration, or live-update features
- debugging hub lifetime, connection state, or transport issues
- deciding whether SignalR or another transport better fits the scenario
- implementing real-time broadcasting to groups of connected clients
- scaling SignalR across multiple servers
Documentation
- ASP.NET Core SignalR Overview
- SignalR Hubs
- SignalR API Design Considerations
- SignalR Production Hosting and Scaling
- SignalR Configuration
References
- patterns.md - Detailed hub patterns, streaming, groups, presence, and advanced messaging techniques
- anti-patterns.md - Common SignalR mistakes and how to avoid them
Workflow
- Use SignalR for broadcast-style or connection-oriented real-time features; do not force gRPC into hub-style fan-out scenarios.
- Model hub contracts intentionally and keep hub methods thin, delegating durable work elsewhere.
- Plan for reconnection, backpressure, auth, and fan-out costs instead of treating real-time messaging as stateless request/response.
- Use groups, presence, and connection metadata deliberately so scale-out behavior is understandable.
- If Native AOT or trimming is in play, validate supported protocols and serialization choices explicitly.
- Test connection behavior and failure modes, not just happy-path message delivery.
Hub Patterns
Strongly-Typed Hub (Recommended)
// Define the client interface
public interface IChatClient
{
Task ReceiveMessage(string user, string message);
Task UserJoined(string user);
Task UserLeft(string user);
}
// Implement the strongly-typed hub
public class ChatHub : Hub<IChatClient>
{
public async Task SendMessage(string user, string message)
{
// Compiler checks client method calls
await Clients.All.ReceiveMessage(user, message);
}
public override async Task OnConnectedAsync()
{
await Clients.Others.UserJoined(Context.User?.Identity?.Name ?? "Anonymous");
await base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception? exception)
{
await Clients.Others.UserLeft(Context.User?.Identity?.Name ?? "Anonymous");
await base.OnDisconnectedAsync(exception);
}
}
Using Groups for Targeted Messaging
public class NotificationHub : Hub<INotificationClient>
{
public async Task JoinGroup(string groupName)
{
await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
await Clients.Group(groupName).UserJoined(Context.User?.Identity?.Name);
}
public async Task LeaveGroup(string groupName)
{
await Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);
}
public async Task SendToGroup(string groupName, string message)
{
await Clients.Group(groupName).ReceiveNotification(message);
}
}
Hub Method with Custom Object Parameters (API Versioning)
// Use custom objects to avoid breaking changes
public class SendMessageRequest
{
public string Message { get; set; } = string.Empty;
public string? Recipient { get; set; } // Added later without breaking clients
public int? Priority { get; set; } // Added later without breaking clients
}
public class ChatHub : Hub<IChatClient>
{
public async Task SendMessage(SendMessageRequest request)
{
// Handle both old and new clients
if (request.Recipient != null)
{
await Clients.User(request.Recipient).ReceiveMessage(request.Message);
}
else
{
await Clients.All.ReceiveMessage(request.Message);
}
}
}
Client Patterns
JavaScript Client with Automatic Reconnection
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chatHub")
.withAutomaticReconnect([0, 2000, 5000, 10000, 30000]) // Retry delays
.configureLogging(signalR.LogLevel.Information)
.build();
// Handle reconnection events
connection.onreconnecting(error => {
console.log("Reconnecting...", error);
updateUIForReconnecting();
});
connection.onreconnected(connectionId => {
console.log("Reconnected with ID:", connectionId);
// Rejoin groups - reconnection does not restore group membership
rejoinGroups();
updateUIForConnected();
});
connection.onclose(error => {
console.log("Connection closed", error);
updateUIForDisconnected();
});
async function start() {
try {
await connection.start();
console.log("SignalR Connected");
} catch (err) {
console.log(err);
setTimeout(start, 5000);
}
}
start();
.NET Client with Reconnection
var connection = new HubConnectionBuilder()
.WithUrl("https://localhost:5001/chatHub", options =>
{
options.AccessTokenProvider = () => Task.FromResult(GetAccessToken());
})
.WithAutomaticReconnect()
.Build();
connection.Reconnecting += error =>
{
_logger.LogWarning("Connection lost. Reconnecting: {Error}", error?.Message);
return Task.CompletedTask;
};
connection.Reconnected += connectionId =>
{
_logger.LogInformation("Reconnected with ID: {ConnectionId}", connectionId);
// Rejoin groups after reconnection
return RejoinGroupsAsync();
};
connection.Closed += async error =>
{
_logger.LogError("Connection closed: {Error}", error?.Message);
await Task.Delay(Random.Shared.Next(0, 5) * 1000);
await connection.StartAsync();
};
await connection.StartAsync();
Server Configuration
Hub Registration with Authentication
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSignalR(options =>
{
options.EnableDetailedErrors = builder.Environment.IsDevelopment();
options.MaximumReceiveMessageSize = 64 * 1024; // 64 KB
options.StreamBufferCapacity = 10;
options.KeepAliveInterval = TimeSpan.FromSeconds(15);
options.ClientTimeoutInterval = TimeSpan.FromSeconds(30);
})
.AddMessagePackProtocol(); // Binary protocol for performance
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
// Read token from query string for WebSocket connections
var accessToken = context.Request.Query["access_token"];
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) && path.StartsWithSegments("/hubs"))
{
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
});
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.MapHub<ChatHub>("/hubs/chat");
Sending Messages from Outside a Hub
public class NotificationService
{
private readonly IHubContext<NotificationHub, INotificationClient> _hubContext;
public NotificationService(IHubContext<NotificationHub, INotificationClient> hubContext)
{
_hubContext = hubContext;
}
public async Task NotifyAllAsync(string message)
{
await _hubContext.Clients.All.ReceiveNotification(message);
}
public async Task NotifyUserAsync(string userId, string message)
{
await _hubContext.Clients.User(userId).ReceiveNotification(message);
}
public async Task NotifyGroupAsync(string groupName, string message)
{
await _hubContext.Clients.Group(groupName).ReceiveNotification(message);
}
}
Scaling with Redis Backplane
builder.Services.AddSignalR()
.AddStackExchangeRedis(connectionString, options =>
{
options.Configuration.ChannelPrefix = RedisChannel.Literal("MyApp");
});
Anti-Patterns to Avoid
| Anti-Pattern | Why It's Bad | Better Approach |
|---|---|---|
| Storing state in Hub properties | Hub instances are created per method call | Use IMemoryCache, database, or external store |
| Instantiating Hub directly | Bypasses SignalR infrastructure | Use IHubContext<THub> for external messaging |
Not awaiting SendAsync calls | Messages may not be sent before hub method completes | Always await async hub calls |
| Adding method parameters without versioning | Breaking change for existing clients | Use custom object parameters |
| Ignoring reconnection group loss | Clients lose group membership on reconnect | Re-add to groups in OnConnectedAsync or client reconnect handler |
| Large payloads over SignalR | Memory pressure, bandwidth issues | Use REST/gRPC for bulk data, SignalR for notifications |
| Missing backplane in multi-server | Messages only reach clients on same server | Use Redis backplane or Azure SignalR Service |
| Exposing ORM entities directly | May serialize sensitive data | Use DTOs with explicit properties |
| Not validating incoming messages | Security risk after initial auth | Validate every hub method input |
Best Practices
Connection Management
- Enable automatic reconnection with exponential backoff delays
- Handle group rejoining explicitly after reconnection (connection ID changes)
- Implement heartbeat monitoring on the client to detect stale connections
- Use sticky sessions when scaling across multiple servers (unless using Azure SignalR Service)
Performance
- Use MessagePack protocol for smaller message sizes and faster serialization
- Throttle high-frequency events like typing indicators or mouse movements
- Batch messages when possible instead of many small sends
- Set appropriate buffer sizes based on expected message throughput
Security
- Authenticate at connection time using JWT tokens via query string
- Authorize hub methods using
[Authorize]attribute - Validate all incoming messages even after authentication
- Use HTTPS for all SignalR connections
API Design
- Use strongly-typed hubs to catch client method name typos at compile time
- Use custom object parameters to enable backward-compatible API evolution
- Version hub names (e.g.,
ChatHubV2) for breaking changes - Keep hub methods thin and delegate business logic to services
Observability
- Log connection events (connect, disconnect, reconnect)
- Track transport type used by each connection
- Monitor message delivery latency and failure rates
- Integrate with Application Insights or other APM tools
Deliver
- clear hub contracts and connection behavior
- real-time delivery that matches the product scenario
- validation for reconnection and authorization flows
- appropriate scale-out strategy for multi-server deployments
Validate
- SignalR is the correct transport for the use case
- hub methods remain orchestration-oriented
- group and auth behavior are explicit and tested
- reconnection and group membership are handled correctly
- backplane is configured for multi-server scenarios
- message validation is implemented in hub methods
Frequently asked questions
What to verify before installation and use
What does the dotnet-signalr source document cover?
Implement or review SignalR hubs, streaming, reconnection, transport, and real-time delivery patterns in ASP. NET Core applications.
How do I install dotnet-signalr?
The source record exposes this install command: npx skills add https://github.com/Postpartum-genushyacinthus29/dotnet-skills --skill "skills/dotnet-signalr". Inspect the command and pinned source before running it.
Which permission-related actions were detected?
Static rules flagged network in the source; the page lists the matching lines and excerpts.
Alternatives
Compare before choosing
oaustegard/claude-skills
featuring
Generate hierarchical _FEATURES.md files that describe what a codebase DOES from a user/consumer perspective, anchored to source symbols via tree-sitting. Supports large complex codebases through feature-driven decomposition into sub-feature files. Uses a multi-pass synthesis: orientation → detail → overview rewrite. Use when someone says "what does this do", "document features", "feature inventory", "_FEATURES.md", or needs to understand a codebase's purpose before modifying it. Complements tre
NintendaDev/unikit-ai
unikit-docs
Generate and maintain the project's TECHNICAL documentation from its codebase — scans the project structure, tech stack, and module boundaries, then writes a lean README landing page plus detailed topic pages (architecture, modules, setup, build, APIs), only the docs that are relevant. Use whenever the user wants to create, update, or validate documentation of the CODE or the project itself, e.g. "generate documentation", "create docs", "write the README", "update the project docs", "document th
mgiovani/cc-arsenal
team-review
Multi-agent review team: architecture, security, performance, testing, style, docs/UX, plus an adversary that cross-examines the other 6, for security-sensitive, architectural, or large PRs (15+ files) where a single-agent pass risks missing cross-cutting issues. Use for auth/payments/PII changes, schema/pattern changes, compliance sign-off, or when asked to 'get the review team on this' / 'multi-agent review' / 'thorough review before merge'. For a standard PR or a quick pre-merge check, use /r
open-edge-platform/edge-ai-libraries
chatqna-helm-deploy
Deploy Chat Question-and-Answer Core to Kubernetes using Helm (OpenVINO CPU, OpenVINO GPU, or Ollama), including values.yaml configuration, helm install/upgrade, deployment verification, uninstall, and translation from Docker Compose setup_env.sh variables into Helm override values. Use this skill when the user says "deploy chatqna core to kubernetes", "helm install chatqna-core", "configure values.yaml", "convert compose config to helm", or "translate setup_env.sh to chart values".