SignalR-wysyłanie wiadomości do konkretnego użytkownika za pomocą (IUSERIDPROVIDER) *NEW 2.0.0*
W najnowszej wersji Asp.Net SignalR, dodano nowy sposób wysyłania wiadomości do konkretnego użytkownika, za pomocą interfejsu "IUserIdProvider".
public interface IUserIdProvider
{
string GetUserId(IRequest request);
}
public class MyHub : Hub
{
public void Send(string userId, string message)
{
Clients.User(userId).send(message);
}
}
Moje pytanie brzmi: skąd mam wiedzieć, do kogo wysyłam wiadomość? Wyjaśnienie tej nowej metody jest bardzo powierzchowne. I szkic Oświadczenia SignalR 2.0.0 z tym błędem i nie kompiluje. Czy ktoś zaimplementował tę funkcję?
Więcej Informacji : http://www.asp.net/signalr/overview/signalr-20/hubs-api/mapping-users-to-connections#IUserIdProvider
Uściski.4 answers
SignalR zapewnia ConnectionId dla każdego połączenia. Aby dowiedzieć się, które połączenie należy do kogo (użytkownika), musimy utworzyć mapowanie między połączeniem a użytkownikiem. Zależy to od sposobu identyfikacji użytkownika w aplikacji.
W SignalR 2.0 odbywa się to za pomocą wbudowanego IPrincipal.Identity.Name
, który jest identyfikatorem zalogowanego użytkownika ustawionym podczas ASP.NET uwierzytelnianie.
Może być jednak konieczne mapowanie połączenia z użytkownikiem za pomocą innego identyfikatora z wykorzystaniem Identity.Name. w tym celu nowy dostawca może być używany z niestandardową implementacją do mapowania użytkownika z połączeniem.
Przykład mapowania użytkowników SignalR do połączeń przy użyciu IUserIdProviderZałóżmy, że nasza aplikacja używa userId
do identyfikacji każdego użytkownika. Teraz musimy wysłać wiadomość do konkretnego użytkownika. Mamy userId
i message
, ale SignalR musi również znać mapowanie między naszym userId a połączeniem.
Aby to osiągnąć, najpierw trzeba utworzyć nową klasę, która implementuje 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();
}
}
Drugim krokiem jest nakazanie SignalR używania naszej CustomUserIdProvider
zamiast domyślnej implementacji. Można to zrobić podczas uruchamiania.cs podczas inicjalizacji konfiguracji huba:
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();
}
}
Teraz możesz wysłać wiadomość do konkretnego użytkownika za pomocą jego userId
, Jak wspomniano w dokumentacji, na przykład:
public class MyHub : Hub
{
public void Send(string userId, string message)
{
Clients.User(userId).send(message);
}
}
Mam nadzieję, że to pomoże.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-25 19:47:09
Na początek.. Otwarty na sugestie/ulepszenia.
Serwer
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("[email protected]").addChatMessage(name, message);
}
public override Task OnConnected()
{
string name = Context.User.Identity.Name;
Groups.Add(Context.ConnectionId, name);
return base.OnConnected();
}
}
JavaScript
(zauważ, że addChatMessage
i sendChatMessage
są również metodami w powyższym kodzie serwera)
$(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();
});
});
});
Testowanie
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-19 20:36:52
Spójrz na testy SignalR dla funkcji.
Test "Sendtouser" pobiera automatycznie tożsamość użytkownika przekazaną za pomocą zwykłej biblioteki uwierzytelniania owin.
Scenariusz jest taki, że masz użytkownika, który połączył się z wielu urządzeń / przeglądarek i chcesz wysłać wiadomość do wszystkich jego aktywnych połączeń.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-22 16:10:13
Oto jak używać SignarR w celu skierowania konkretnego użytkownika (bez użycia żadnego dostawcy):
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!");
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-05 15:30:15