C# Academy · Lektion

Stærkt typede hubs

Definér typede hub-grænseflader for at opnå compile-time-sikkerhed og IntelliSense ved kald af klientmetoder.

Lektion 3 af 412 trin

Stærkt typede hubs er en gratis C# Academy-lektion på CoddyKit. Dette er lektion 3 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i C# Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. C# Academy-kurset indeholder 4 lektioner i alt.

Problemet med metodnavne som strenge

Standardkald til SignalR bruger SendAsync("MethodName", ...) med magiske strenge. En stavefejl i metodenavnet medfører en lydløs fejl — klienten modtager ganske enkelt aldrig meddelelsen. Stærkt typede hubs løser dette.

Definition af klientgrænsefladen

Opret en grænseflade, der erklærer alle metoder, serveren kan kalde på klienten. Metodenavnene og parametertyperne udgør din kontrakt.

// INotificationClient.cs
public interface INotificationClient
{
    Task ReceiveMessage(string user, string message);
    Task OrderShipped(int orderId, string trackingNumber);
    Task UserJoined(string username);
    Task UserLeft(string username);
    Task SystemAlert(string message);
}

Oprettelse af en stærkt typet hub

Nedarv fra Hub<T>, hvor T er din klientgrænseflade. Egenskaben Clients er nu typet — IntelliSense viser de tilgængelige metoder, og stavefejl bliver kompileringsfejl.

public class ChatHub : Hub<INotificationClient>
{
    public async Task SendMessage(string message)
    {
        var user = Context.User!.Identity!.Name ?? "Anonymous";

        // Compile-time safety — no magic strings!
        await Clients.All.ReceiveMessage(user, message);
        await Clients.Others.UserJoined(user); // IntelliSense works
    }
}

Målretning mod bestemte klienter med en typet hub

Alle standardmetoder til målretning fungerer på den typede hub: Clients.User, Clients.Group, Clients.Caller, Clients.Client — alle returnerer den typede grænseflade.

public async Task NotifyOrderShipped(int orderId, string customerId)
{
    await Clients.User(customerId)
                 .OrderShipped(orderId, "TRK-12345");

    await Clients.Group("admins")
                 .SystemAlert($"Order {orderId} shipped to {customerId}");

    await Clients.Caller.ReceiveMessage("System", "Notification sent");
}

Typet IHubContext

Indsæt IHubContext<THub, TClient> i tjenester for at opnå den samme sikkerhed ved kompileringstidspunktet, når der sendes meddelelser fra områder uden for hubben.

public class ShipmentService
{
    private readonly IHubContext<ChatHub, INotificationClient> _hub;

    public ShipmentService(
        IHubContext<ChatHub, INotificationClient> hub) => _hub = hub;

    public async Task ProcessShipmentAsync(int orderId, string customerId)
    {
        // Fully typed — no magic strings
        await _hub.Clients.User(customerId)
                  .OrderShipped(orderId, "TRK-99999");
    }
}

Regler for klientgrænsefladen

Metoder i klientgrænsefladen skal returnere Task og ikke Task<T>. SignalR starter klientkald uden at vente på resultatet — klienten returnerer ingen værdi til serveren.

// CORRECT
public interface IMyClient
{
    Task ReceiveMessage(string msg);         // OK
    Task UpdateProgress(int percent);        // OK
    Task<string> GetUserInput();            // NOT SUPPORTED
}
// Return types other than Task are not supported in hub client interfaces
// For request-response patterns, use client-callable hub methods instead

Kombination af typede hubs og grupper

Typede grupper fungerer på samme måde som utypede grupper — API'et er det samme, blot med metodenavne, der kontrolleres ved kompilering.

public class RoomHub : Hub<IRoomClient>
{
    public async Task JoinRoom(string room)
    {
        await Groups.AddToGroupAsync(Context.ConnectionId, room);
        await Clients.Group(room).UserJoined(Context.User!.Identity!.Name!);
    }

    public async Task BroadcastToRoom(string room, string message)
    {
        var user = Context.User!.Identity!.Name!;
        await Clients.Group(room).ReceiveMessage(user, message);
    }
}

Test af stærkt typede hubs

Da klientkald går gennem en grænseflade, kan du mocke klienten i enhedstests for at kontrollere, at de korrekte metoder blev kaldt med de rigtige argumenter.

// NSubstitute test
var mockClients = Substitute.For<IHubCallerClients<INotificationClient>>();
var mockAllClients = Substitute.For<INotificationClient>();
mockClients.All.Returns(mockAllClients);

var hub = new ChatHub { Clients = mockClients };
await hub.SendMessage("Hello!");

await mockAllClients.Received(1).ReceiveMessage("System", "Hello!");

Flere hubs pr. applikation

En applikation kan have flere hubslutpunkter til forskellige realtidsfunktioner, hver med sin egen typede klientgrænseflade.

// Three separate hubs
app.MapHub<ChatHub>("/hubs/chat");
app.MapHub<NotificationHub>("/hubs/notifications");
app.MapHub<DashboardHub>("/hubs/dashboard");

// Each with its own client interface:
// Hub<IChatClient>, Hub<INotificationClient>, Hub<IDashboardClient>

Afsendelse af strukturerede data

Metoder i klientgrænsefladen kan modtage komplekse DTO'er. SignalR serialiserer dem automatisk til JSON — sørg for, at dine typer kan serialiseres.

public interface IOrderClient
{
    Task OrderUpdated(OrderStatusDto status);
}

public record OrderStatusDto(
    int OrderId,
    string Status,
    decimal Total,
    DateTime UpdatedAt);

// Usage in hub:
await Clients.User(customerId).OrderUpdated(
    new OrderStatusDto(order.Id, order.Status.ToString(),
                       order.Total, DateTime.UtcNow));

Hurtigt tjek

Hvilken begrænsning gælder for returtypen for metoder i en SignalR-hubklientgrænseflade?

Opsamling: Stærkt typede hubs

Vigtigste pointer:

  • Definer en grænseflade (IMyClient), der angiver alle metoder, serveren kan kalde på klienter
  • Nedarv fra Hub<IMyClient> — egenskaben Clients bliver fuldt typet
  • Indsæt IHubContext<THub, TClient> for typede meddelelser fra områder uden for hubben
  • Metoder i klientgrænsefladen skal returnere Task, ikke Task<T>
  • Grænsefladebaserede klienter kan mockes — stærkt typede hubs er nemmere at teste
Gratis at komme i gang

Lær C# med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
93
Lektioner
346

Ofte stillede spørgsmål

Er lektionen “Stærkt typede hubs” gratis?

Ja — hele teksten til “Stærkt typede hubs” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af C# Academy-kurset, skal du opgradere til CoddyKit PRO. C# Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Stærkt typede hubs”?

Definér typede hub-grænseflader for at opnå compile-time-sikkerhed og IntelliSense ved kald af klientmetoder. Du øver dig i C# Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på C# Academy?

Der kræves ingen tidligere erfaring. C# Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 3 af 4.

Hvor lang tid tager lektionen “Stærkt typede hubs”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne C# Academy-lektion?

Ja. Alle C# Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. SignalR-hubs og forbindelser
  2. Grupper, brugere og forbindelseshåndtering
  3. Stærkt typede hubs
  4. Skalering med Redis-backplane
← Tilbage til C# Academy