简体   繁体   中英

Connecting to a SignalR hub from console using ClaimsPrincial

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM