
FAQs about SignalR
Best way to call client methods in a Hub class
This is a common way to call a client-side method via SignalR:
public class WebHub : Hub { ... public async Task SomeMethod(string something) { //Calls CheckItOut method in all Clients and passes string parameter 'something' await Clients.All.SendAsync("CheckItOut", something); } ... }
Although, you can see such practice in many Real-time connection libraries and examples, this may lead to messing up your code with hardcoded values, duplications and missunderstanding of what a particular command should do.
There is an alternative way to call client-side methods that matches OOP design and looks simple:
Declare an interface with client side methods and pass it to generic type of Hub class.
public class WebHub : Hub<IWebInterface> { ... public async Task SomeMethod(string something) { await Clients.All.CheckItOut(something); } ... } public interface IWebInterface { public Task CheckItOut(string something); public Task Refresh(); }
How to get query parameter during client connection to Hub
Client code:
//example on js with SignalR.js library ... let player = 1; let connection = new signalR.HubConnectionBuilder() .withUrl("/web?player=" + player) .build(); ... connection.start(); ...
Server code:
public class WebHub : Hub { ... public override async Task OnConnectedAsync() { var httpContext = Context.Features.Get<IHttpContextFeature>().HttpContext; string id = httpContext.Request.Query["player"]; Console.WriteLine("Player: " + id == null ? "none" : id); ... await base.OnConnectedAsync(); } ... }
How to send message to particular user(s)?
public class WebHub : Hub<IWebInterface> { ... public async Task SomeMethod(string something) { //Call in All connected Clients await Clients.All.CheckItOut(something); //Call in current connected Client await Clients.Caller.CheckItOut(something); //Call in Others connected Clients - this means All without Caller await Clients.Others.CheckItOut(something); //Call in Client by its connection Id await Clients.Client("[connectionId]").CheckItOut(something); } ... }
How to get current client connection Id
public class WebHub : Hub<IWebInterface> { ... public async Task SomeMethod(string something) { string currentId = Context.ConnectionId; Console.WriteLine(currentId + " has called SomeMethod and passed - " + something); } ... }
How to call a method in group without current connection
public class WebHub : Hub<IWebInterface> { ... public async Task SomeMethod(string groupName) { await Clients.OthersInGroup(groupName).CheckItOut("all group participants without current client will recieve this"); } ... }
How to setup Authentication with JWT token in SignalR hub
Assume that “/web” is our Hub endpoint. Configure JWT auth in Asp Net Core application:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.RequireHttpsMetadata = true; options.TokenValidationParameters = new TokenValidationParameters { ... //your TokenValidationParameters ... }; options.Events = new JwtBearerEvents { OnMessageReceived = context => { var accessToken = context.Request.Query["access_token"]; var path = context.HttpContext.Request.Path; if (!string.IsNullOrEmpty(accessToken) && (path.StartsWithSegments("/web"))) { context.Token = accessToken; } return Task.CompletedTask; } }; });
Assume that you have an endpoint to get jwt token “/Account/token?username=[username]&password=[password]”. Take token and add it during connection to SignalR hub in client-side:
... const response = await fetch("/Account/token?username=admin&password=admin123"); let token = await response.json(); let connection = new signalR.HubConnectionBuilder() .withUrl("/web", { accessTokenFactory: () => token.access_token }) .withAutomaticReconnect() .build(); ... connection.start(); ...
Add Authorize attribute to Hub class:
[Authorize] public class WebHub : Hub<IWebInterface> ...