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.
Author: Igor, 2013-10-22

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 IUserIdProvider

Załóż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.
 121
Author: Sumant,
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>:&nbsp;&nbsp;' + 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 Tutaj wpisz opis obrazka

 29
Author: The Muffin Man,
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ń.

 2
Author: Gustavo Armenta,
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!");
 0
Author: Matteo Gariglio,
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