AgentSkillsCN

signalr

实现实时 WebSocket 通信与 SignalR 集线器订阅。 适用于:添加实时更新、广播状态变化、实现客户端订阅,或在 Blazor WASM 中配置 WebSocket 连接时使用。

SKILL.md
--- frontmatter
name: signalr
description: |
  Implements real-time WebSocket communication and SignalR hub subscriptions.
  Use when: Adding real-time updates, broadcasting state changes, implementing client subscriptions, or configuring WebSocket connections in Blazor WASM.
allowed-tools: Read, Edit, Write, Glob, Grep, Bash

SignalR Skill

Real-time communication in VanDaemon uses SignalR for WebSocket-based updates between the .NET API and Blazor WASM frontend. The hub at /hubs/telemetry broadcasts tank levels, control states, and alerts to subscribed client groups. Background services poll hardware every 5 seconds and push changes via IHubContext.

Quick Start

Server Hub Definition

csharp
// src/Backend/VanDaemon.Api/Hubs/TelemetryHub.cs
public class TelemetryHub : Hub
{
    public async Task SubscribeToTanks()
    {
        await Groups.AddToGroupAsync(Context.ConnectionId, "tanks");
    }

    public async Task SubscribeToControls()
    {
        await Groups.AddToGroupAsync(Context.ConnectionId, "controls");
    }

    public async Task SubscribeToAlerts()
    {
        await Groups.AddToGroupAsync(Context.ConnectionId, "alerts");
    }
}

Broadcasting from Background Service

csharp
// Inject IHubContext<TelemetryHub> in background service
await _hubContext.Clients.Group("tanks").SendAsync(
    "TankLevelUpdated", tankId, currentLevel, tankName, cancellationToken);

Blazor Client Connection

csharp
// In Blazor component
_hubConnection = new HubConnectionBuilder()
    .WithUrl($"{_apiBaseUrl}/hubs/telemetry")
    .WithAutomaticReconnect()
    .Build();

_hubConnection.On<Guid, double, string>("TankLevelUpdated", (id, level, name) =>
{
    // Update UI state
    InvokeAsync(StateHasChanged);
});

await _hubConnection.StartAsync();
await _hubConnection.InvokeAsync("SubscribeToTanks");

Key Concepts

ConceptUsageExample
HubServer endpoint for connectionsTelemetryHub : Hub
GroupsBroadcast to subset of clientsGroups.AddToGroupAsync(connectionId, "tanks")
IHubContextBroadcast from services_hubContext.Clients.Group("tanks").SendAsync(...)
On<T>Client-side event handler_hubConnection.On<Guid, double>("TankLevelUpdated", ...)
WithAutomaticReconnectResilient connections.WithAutomaticReconnect()

Common Patterns

Group-Based Subscriptions

When: Different clients need different update types.

csharp
// Client subscribes only to what it needs
await _hubConnection.InvokeAsync("SubscribeToTanks");
await _hubConnection.InvokeAsync("SubscribeToControls");

// Server broadcasts to specific group
await _hubContext.Clients.Group("controls").SendAsync(
    "ControlStateChanged", controlId, newState, controlName);

Connection State Handling

When: UI needs to reflect connection status.

csharp
_hubConnection.Closed += async (error) =>
{
    _isConnected = false;
    await InvokeAsync(StateHasChanged);
};

_hubConnection.Reconnected += async (connectionId) =>
{
    _isConnected = true;
    await _hubConnection.InvokeAsync("SubscribeToTanks");
    await InvokeAsync(StateHasChanged);
};

See Also

  • patterns - Server and client implementation patterns
  • workflows - Setup, testing, and deployment workflows

Related Skills

  • See the aspnet-core skill for API and DI configuration
  • See the blazor skill for frontend integration patterns
  • See the docker skill for nginx WebSocket proxy configuration