I have a very simple SignalR hub that is up and running on my server. Using the example from Micorsoft, I created an in memory storage to map users from a ClaimsPrincipal to an in memory dictionary. Here is the code:
public class NotificationHub : Hub
{
private readonly static ConnectionMapping<string> _connections = new ConnectionMapping<string>();
public void SendNotification(string who, NotificationData message)
{
string name = Context.User.Identity.Name;
foreach(var connectionId in _connections.GetConnections(who))
{
Clients.Client(connectionId).SendAsync("Notification", message);
}
}
public override Task OnConnectedAsync()
{
string name = Context.UserIdentifier;
_connections.Add(name, Context.ConnectionId);
return base.OnConnectedAsync();
}
public override Task OnDisconnectedAsync(System.Exception exception)
{
string name = Context.User.Identity.Name;
_connections.Remove(name, Context.ConnectionId);
return base.OnDisconnectedAsync(exception);
}
}
I want to test this with a console application, but I cannot find out how to create a ClaimsPrincipal in .net core console app. Here is my console app code:
class Program
{
static async Task Main(string[] args)
{
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal)
Console.WriteLine("Press a key to start listening");
Console.ReadKey();
Console.WriteLine("Client Listening!");
var connection = new HubConnectionBuilder()
.WithUrl("https://localhost:44375/Notify")
.WithAutomaticReconnect(new[] { TimeSpan.Zero, TimeSpan.Zero, TimeSpan.FromSeconds(10) })
//.ConfigureLogging(logging =>
//{
// logging.AddConsole();
// logging.SetMinimumLevel(LogLevel.Debug);
//})
.Build();
connection.On<NotificationData>("Notification", (notificationData) =>
Console.WriteLine($"Somebody connected: {notificationData.ClientId}"));
connection.StartAsync().GetAwaiter().GetResult();
while(Console.ReadKey().Key == ConsoleKey.S)
{
var msg = new NotificationData { ClientId = Guid.NewGuid().ToString(), Notifications = null };
await connection.SendAsync("SendNotification", msg);
}
Console.WriteLine("Listening. Press a key to quit");
Console.ReadKey();
connection.Reconnecting += error =>
{
Console.WriteLine("Reconnecting...");
return Task.CompletedTask;
};
}
}
I tried to use the WindowsPrincipal but did not succeed in sending over the name. Apparently SignalR needs to have a claims principal. How do you send a claimsprincial from a console application?
I was able to create a QueryBuilder object to intercept the userId from a posted JSON doc and create a URI string with the QueryBuilder items appended. Then on the Hub's OnConnectedAsync method, I used the Context.GetHttpContext method to pull the user from the querystring and add it to a group. I then map it to an in memory dictionary to map the userId to the Context.ConnectionId.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.