Skip to main content

add-signalr-realtime

Add real-time SignalR features to an ABP app via the Volo.Abp.AspNetCore.SignalR module — creating hubs, wiring conventional hub routes/authorization, reading CurrentUser in a hub, and connecting from a JS or Blazor/.NET client. USE FOR: installing the SignalR module, deriving from `AbpHub` (optionally strongly-typed with a client interface), the conventional `/signalr-hubs/...` route and `HubRoute` override, `[Authorize]` + `AbpSignalRUserIdProvider`/`Clients.User`, opting out of auto DI with `[DisableConventionalRegistration]` and auto hub mapping with `[DisableAutoHubMap]` (then configuring manually via `AbpSignalROptions`), and JS/Blazor client connection code. DO NOT USE FOR: distributed cache/lock or event-bus-based messaging (use distributed-caching-and-locking / background-jobs-and-events); Dapr pub/sub or inter-service communication (use integrate-dapr-services / design-module-and-service-communication); non-realtime HTTP endpoints (use expose-http-apis).

Aller à l'installation

Informations de source

Dépôt
abpframework/abp-skills
Dernière activité de la source
20 juillet 2026 à 03:24
Langue détectée de SKILL.md
anglais
Étoiles
18
Forks
0

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
add-signalr-realtime
description
Add real-time SignalR features to an ABP app via the Volo.Abp.AspNetCore.SignalR module — creating hubs, wiring conventional hub routes/authorization, reading CurrentUser in a hub, and connecting from a JS or Blazor/.NET client. USE FOR: installing the SignalR module, deriving from `AbpHub` (optionally strongly-typed with a client interface), the conventional `/signalr-hubs/...` route and `HubRoute` override, `[Authorize]` + `AbpSignalRUserIdProvider`/`Clients.User`, opting out of auto DI with `[DisableConventionalRegistration]` and auto hub mapping with `[DisableAutoHubMap]` (then configuring manually via `AbpSignalROptions`), and JS/Blazor client connection code. DO NOT USE FOR: distributed cache/lock or event-bus-based messaging (use distributed-caching-and-locking / background-jobs-and-events); Dapr pub/sub or inter-service communication (use integrate-dapr-services / design-module-and-service-communication); non-realtime HTTP endpoints (use expose-http-apis).
license
MIT
# Add SignalR Real-Time to an ABP App ABP's `Volo.Abp.AspNetCore.SignalR` module wraps ASP.NET Core SignalR so you don't have to call `services.AddSignalR()` or map hub endpoints manually — ABP auto-registers every hub in DI (as transient) and maps its endpoint conventionally. ## When to Use - Adding server-push / real-time messaging (chat, notifications, live updates) to an ABP app. - Creating a hub that needs ABP's `CurrentUser` / `CurrentTenant` / localization. - Securing a hub with `[Authorize]` and targeting connected users by id. - Connecting to a hub from a JavaScript (MVC/Razor) or Blazor/.NET client. ## When Not to Use - **Cross-instance/background messaging that isn't client-facing** — use **background-jobs-and-events** (distributed event bus). - **Dapr pub/sub or inter-microservice messaging** — use **integrate-dapr-services** / **design-module-and-service-communication**. - **Plain request/response HTTP endpoints** — use **expose-http-apis**. - Note: hosting/scaling/Redis-backplane/Azure SignalR concerns are standard ASP.NET Core (Microsoft's SignalR docs), not ABP-specific. ## 1. Install the module Add the package to the web/API layer that hosts your hubs: ```bash abp add-package Volo.Abp.AspNetCore.SignalR ``` Or add the NuGet package `Volo.Abp.AspNetCore.SignalR` and depend on the module: ```csharp [DependsOn( typeof(AbpAspNetCoreSignalRModule) )] public class MyWebModule : AbpModule { } ``` You do **not** need `services.AddSignalR()` or a manual `MapHub<T>(...)` — the module calls `AddSignalR()` and registers each hub's mapping into `AbpEndpointRouterOptions`. It does **not** call `UseEndpoints` itself, though: your host's request pipeline must include `app.UseConfiguredEndpoints()` (the startup templates already have it), which is where ABP runs those hub mappings. If that call is missing, no hub endpoints get mapped. ## 2. Create a hub Derive from `AbpHub` (or `AbpHub<TClient>` for a strongly-typed client) instead of the plain `Hub` / `Hub<T>`. `AbpHub` adds useful base members: `CurrentUser`, `CurrentTenant`, `Logger`, `Clock`, `AuthorizationService`, and localization via `L`. ```csharp using Microsoft.AspNetCore.Authorization; using Volo.Abp; using Volo.Abp.AspNetCore.SignalR; [Authorize] // require an authenticated user before any hub method runs public class MessagingHub : AbpHub { // SignalR invokes hub methods by their literal name (it does NOT strip an `Async` // suffix), so keep the name the client will call. public async Task SendMessage(Guid targetUserId, string message) { Check.NotNullOrWhiteSpace(message, nameof(message)); // validate untrusted input // A real app should also authorize the recipient (contact/room membership, tenant, // block lists) — an authenticated user shouldn't be able to message anyone at will. var senderUserName = CurrentUser.UserName; // current (authenticated) user Logger.LogInformation("Message from {User}", senderUserName); // Deliver only to the target user's connections — don't broadcast arbitrary // user input to everyone with Clients.All. await Clients.User(targetUserId.ToString()) .SendAsync("ReceiveMessage", senderUserName, message); } } ``` Strongly-typed client variant: ```csharp public interface IChatClient { Task ReceiveMessage(string user, string message); } [Authorize] // the strongly-typed variant needs the same guard as the plain hub public class ChatHub : AbpHub<IChatClient> { public Task SendMessage(string message) { Check.NotNullOrWhiteSpace(message, nameof(message)); // validate untrusted input // Clients.All sends to EVERY connection of this hub — it is NOT a room/group. In a // shared or multi-tenant host that reaches all users (including other tenants), so // only broadcast to everyone when that is genuinely intended; for a real chat room, // scope with Clients.Group(...) / Groups. return Clients.All.ReceiveMessage(CurrentUser.UserName!, message); } } ``` > A plain `Hub` also works with ABP's auto-registration; `AbpHub` just gives you the > extra base properties without constructor injection. ## 3. Hub route (URL) ABP maps the endpoint conventionally. For a hub named `MessagingHub` the route is: ```text /signalr-hubs/messaging ``` Rule (from `HubRouteAttribute.GetRoutePattern`): prefix `/signalr-hubs/`, then the hub type name with the `Hub` suffix removed, converted to **kebab-case**. Override the route with the `HubRoute` attribute: ```csharp [HubRoute("/my-messaging-hub")] public class MessagingHub : AbpHub { } ``` ## 4. Authorization and CurrentUser Because ABP registers `IUserIdProvider` (`AbpSignalRUserIdProvider`) from `ICurrentUser`, the hub is integrated with your app's authentication. Protect a hub with the standard `[Authorize]` attribute: ```csharp using Microsoft.AspNetCore.Authorization; [Authorize] public class MessagingHub : AbpHub { public async Task SendPrivate(string toUserId, string message) { Check.NotNullOrWhiteSpace(message, nameof(message)); // A real app should also authorize the recipient (block lists, contact/room // membership) — an authenticated user shouldn't be able to message anyone at will. // Clients.User(...) works because AbpSignalRUserIdProvider maps to ICurrentUser.Id await Clients.User(toUserId).SendAsync("ReceiveMessage", CurrentUser.UserName, message); } } ``` Inside a hub, `CurrentUser` reflects the authenticated connection: - `CurrentUser.IsAuthenticated` - `CurrentUser.Id` (a `Guid?`) - `CurrentUser.UserName` - `CurrentUser.TenantId` (also available via `CurrentTenant`) For permission checks you can use the base `AuthorizationService` or an `[Authorize("MyPermission")]` policy on the hub/method. ## 5. Manual registration / mapping (optional) Auto DI registration + auto mapping is the default. To opt out of auto DI registration, put `[DisableConventionalRegistration]` on the hub, then register it yourself: ```csharp context.Services.AddTransient<MessagingHub>(); ``` To keep DI registration but do the endpoint mapping yourself, add `[DisableAutoHubMap]` and configure via `AbpSignalROptions`: ```csharp Configure<AbpSignalROptions>(options => { options.Hubs.Add( new HubConfig( typeof(MessagingHub), "/my-messaging/route", hubOptions => { hubOptions.LongPolling.PollTimeout = TimeSpan.FromSeconds(30); } ) ); }); ``` To tweak a hub defined in a depended module you don't own, use `options.Hubs.AddOrUpdate(...)` with a `config` lambda that sets `config.RoutePattern` and adds to `config.ConfigureActions`. ## 6. Connect from a client ### JavaScript (MVC / Razor Pages) Add the client package and include the script: ```bash abp add-package @abp/signalr # run in the web project root abp install-libs ``` Include the script in your page/view (requires `@using Volo.Abp.AspNetCore.Mvc.UI.Packages.SignalR`): ```xml @section scripts { <abp-script type="typeof(SignalRBrowserScriptContributor)" /> } ``` Then use the standard SignalR JS client: ```js const connection = new signalR.HubConnectionBuilder() .withUrl("/signalr-hubs/messaging") .build(); connection.on("ReceiveMessage", (user, message) => { /* ... */ }); await connection.start(); await connection.invoke("SendMessage", "3fa85f64-5717-4562-b3fc-2c963f66afa6", "Hello"); ``` ### Blazor / .NET client Use the standard `HubConnectionBuilder` from `Microsoft.AspNetCore.SignalR.Client`, pointing at the conventional route: ```csharp var connection = new HubConnectionBuilder() .WithUrl(NavigationManager.ToAbsoluteUri("/signalr-hubs/messaging")) .Build(); connection.On<string, string>("ReceiveMessage", (user, message) => { /* ... */ }); await connection.StartAsync(); ``` For an authenticated hub, pass the access token on the client via `options.AccessTokenProvider` in `WithUrl` per the standard Microsoft SignalR client docs. ### Sending from outside a hub To send from outside a hub (e.g. an app service), inject `IHubContext<MessagingHub>` (standard ASP.NET Core) and call `hubContext.Clients...SendAsync(...)`. ## Validation - Confirm the hub endpoint is reachable at its conventional route (`/signalr-hubs/<kebab-name-without-Hub-suffix>`, or the `HubRoute` override). - Verify the host pipeline includes `app.UseConfiguredEndpoints()` — without it no hub endpoints are mapped. - Start a client (`connection.start()` / `StartAsync()`) and confirm messages round-trip via the registered `on`/`On` handler. - For an `[Authorize]` hub, confirm `CurrentUser.IsAuthenticated`/`CurrentUser.Id` reflect the connection and `Clients.User(id)` delivers to that user. ## Common Pitfalls - **Missing `app.UseConfiguredEndpoints()`.** The module registers hub mappings but does not call `UseEndpoints` itself — if that pipeline call is absent, no hub endpoints get mapped (startup templates include it). - **Manually calling `AddSignalR()` / `MapHub<T>()`.** The module already does both; hubs are auto-registered (transient) and mapped conventionally. - **Wrong route.** The conventional route strips the `Hub` suffix and kebab-cases the name (`MessagingHub` → `/signalr-hubs/messaging`); override with `[HubRoute]`. - **Opting out incorrectly.** Use `[DisableConventionalRegistration]` to skip auto DI (then register yourself), or `[DisableAutoHubMap]` + `AbpSignalROptions` to map yourself — they control different things. - **Treating hosting/scaling as ABP-specific.** Redis backplane, Azure SignalR, and scale-out follow standard ASP.NET Core SignalR guidance, not this skill.
Voir sur GitHub