#c# #signalr #signalr.client
#c# #signalr #signalr.client
Вопрос:
У меня есть очень простой концентратор SignalR, который запущен и работает на моем сервере. Используя пример из Micorsoft, я создал хранилище в памяти для сопоставления пользователей из ClaimsPrincipal в словарь в памяти. Вот код:
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);
}
}
Я хочу протестировать это с помощью консольного приложения, но я не могу узнать, как создать ClaimsPrincipal в консольном приложении .net core. Вот мой код консольного приложения:
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;
};
}
}
Я пытался использовать WindowsPrincipal, но не удалось отправить имя. По-видимому, SignalR должен иметь принципал утверждений. Как отправить claimsprincial из консольного приложения?
Ответ №1:
Я смог создать объект QueryBuilder для перехвата идентификатора пользователя из опубликованного документа JSON и создания строки URI с добавлением элементов QueryBuilder. Затем в методе OnConnectedAsync концентратора я использовал метод Context.GetHttpContext для извлечения пользователя из строки запроса и добавления его в группу. Затем я сопоставляю его со словарем в памяти, чтобы сопоставить идентификатор пользователя с контекстом.Идентификатор подключения.