SignalR-отправка сообщения конкретному пользователю с помощью (IUserIdProvider) *NEW 2.0.0*
в последней версии Asp.Net SignalR, был добавлен новый способ отправки сообщения конкретному пользователю, используя интерфейс "IUserIdProvider".
public interface IUserIdProvider
{
string GetUserId(IRequest request);
}
public class MyHub : Hub
{
public void Send(string userId, string message)
{
Clients.User(userId).send(message);
}
}
мой вопрос: Как узнать, кому я отправляю свое сообщение? Объяснение этого нового метода очень поверхностно. А проект заявления SignalR 2.0.0 с этим багом так и не компилируется. Кто-нибудь реализовал эту функцию?
Подробнее : http://www.asp.net/signalr/overview/signalr-20/hubs-api/mapping-users-to-connections#IUserIdProvider
объятия.
4 ответов
SignalR обеспечивает ConnectionId для каждого соединения. Чтобы найти, какое соединение принадлежит кому (пользователю), нам нужно создать сопоставление между соединением и пользователем. Это зависит от того, как вы идентифицируете пользователя в своем приложении.
в SignalR 2.0 это делается с помощью встроенного IPrincipal.Identity.Name
, который является зарегистрированным идентификатором пользователя, установленным во время ASP.NET аутентификация.
однако вам может потребоваться сопоставить соединение с пользователем, используя другой идентификатор вместо использования идентификатора.Имя. Для этой цели этот новый поставщик может использоваться с пользовательской реализацией для сопоставления пользователя с подключением.
пример сопоставления пользователей SignalR с подключениями с помощью IUserIdProvider
предположим, что наше приложение использует userId
для идентификации каждого пользователя. Теперь нам нужно отправить сообщение конкретному пользователю. У нас есть userId
и message
, но SignalR также должен знать отображение между нашим идентификатором пользователя и соединение.
чтобы добиться этого, сначала нам нужно создать новый класс, который реализует IUserIdProvider
:
public class CustomUserIdProvider : IUserIdProvider
{
public string GetUserId(IRequest request)
{
// your logic to fetch a user identifier goes here.
// for example:
var userId = MyCustomUserClass.FindUserId(request.User.Identity.Name);
return userId.ToString();
}
}
второй шаг-сказать SignalR использовать наш CustomUserIdProvider
вместо реализации по умолчанию. Это можно сделать при запуске.cs при инициализации конфигурации концентратора:
public class Startup
{
public void Configuration(IAppBuilder app)
{
var idProvider = new CustomUserIdProvider();
GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider), () => idProvider);
// Any connection or hub wire up and configuration should go here
app.MapSignalR();
}
}
теперь, вы можете отправить сообщение конкретному пользователю, используя его userId
как указано в документации, например:
public class MyHub : Hub
{
public void Send(string userId, string message)
{
Clients.User(userId).send(message);
}
}
надеюсь, что это помогает.
вот начало.. Открыт для предложений/улучшений.
сервер
public class ChatHub : Hub
{
public void SendChatMessage(string who, string message)
{
string name = Context.User.Identity.Name;
Clients.Group(name).addChatMessage(name, message);
Clients.Group("2@2.com").addChatMessage(name, message);
}
public override Task OnConnected()
{
string name = Context.User.Identity.Name;
Groups.Add(Context.ConnectionId, name);
return base.OnConnected();
}
}
JavaScript
(обратите внимание, как addChatMessage
и sendChatMessage
также являются методами в коде сервера выше)
$(function () {
// Declare a proxy to reference the hub.
var chat = $.connection.chatHub;
// Create a function that the hub can call to broadcast messages.
chat.client.addChatMessage = function (who, message) {
// Html encode display name and message.
var encodedName = $('<div />').text(who).html();
var encodedMsg = $('<div />').text(message).html();
// Add the message to the page.
$('#chat').append('<li><strong>' + encodedName
+ '</strong>: ' + encodedMsg + '</li>');
};
// Start the connection.
$.connection.hub.start().done(function () {
$('#sendmessage').click(function () {
// Call the Send method on the hub.
chat.server.sendChatMessage($('#displayname').val(), $('#message').val());
// Clear text box and reset focus for next comment.
$('#message').val('').focus();
});
});
});
тестирование
посмотреть SignalR Тесты для функции.
тест "SendToUser" автоматически принимает идентификатор пользователя, переданный с помощью обычной библиотеки аутентификации owin.
сценарий у вас есть пользователь, который подключился из нескольких устройств / браузеров, и вы хотите нажать сообщение на все его активные соединения.
вот как использовать SignarR для целевого пользователя (без использования какого-либо поставщика):
private static ConcurrentDictionary<string, string> clients = new ConcurrentDictionary<string, string>();
public string Login(string username)
{
clients.TryAdd(Context.ConnectionId, username);
return username;
}
// The variable 'contextIdClient' is equal to Context.ConnectionId of the user,
// once logged in. You have to store that 'id' inside a dictionaty for example.
Clients.Client(contextIdClient).send("Hello!");