source

SignalR - (IUserIdProvider) *NEW 2.0.0*을 사용하여 특정 사용자에게 메시지 보내기

manysource 2023. 4. 20. 21:35

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

포옹.

SignalR은 각 연결에 ConnectionId를 제공합니다.어떤 접속이 누구(사용자)에게 속하는지 확인하려면 접속과 사용자 사이에 매핑을 작성해야 합니다.이것은, 애플리케이션의 유저를 식별하는 방법에 의해서 다릅니다.

2.된 SignalR 2.0을 .IPrincipal.Identity.NameASP 아이디NET 증 net

단, Identity를 사용하는 대신 다른 ID를 사용하여 사용자와의 연결을 매핑해야 할 수 있습니다.이름. 이 새 공급자를 사용자 지정 구현과 함께 사용하여 사용자를 연결과 매핑할 수 있습니다.

IUserIdProvider를 사용한 Connection에 대한 SignalR 사용자의 매핑 예시

에서 「」를 하고 있다고 .userId을 사용하다이제 특정 사용자에게 메시지를 보내야 합니다.우리는 가지고 있다.userId ★★★★★★★★★★★★★★★★★」message, 합니다.SignalR' userId connection 이 、 id , , , 。

위해서는 먼저 를 만들어야 .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 에서 할 수 .Startup.cs Startup.cs Startup.cs 、 Startup.csStartup.csStartup.csStartup.csStartup.csStartup.csStartup.csStartup.csStartup.csStartup.csStartup.csStartup.csStartup.csStartup.csStartup.csStartup.csStartup.csStartup.csStartup.csStartup.csStartup.csStartup.csStartup.csStartup.csStartup.csStartup.csStartup.csStartup.csStartup.csStartup.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();
    }
}

자바스크립트

)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>:&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();
        });
    });
});

여기에 이미지 설명 입력

(프로바이더를 사용하지 않고) 특정 사용자를 대상으로 하기 위해 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!");

asp.net core에서 이 작업을 수행하려는 모든 사용자에게 적합합니다.클레임을 사용할 수 있습니다.

public class CustomEmailProvider : IUserIdProvider
{
    public virtual string GetUserId(HubConnectionContext connection)
    {
        return connection.User?.FindFirst(ClaimTypes.Email)?.Value;
    }
}

모든 식별자를 사용할 수 있지만 고유해야 합니다.예를 들어 이름 ID를 사용하는 경우 수신인과 이름이 같은 사용자가 여러 명 있는 경우에도 메시지가 배달됨을 의미합니다.메일은 사용자마다 고유하기 때문에 선택하게 되었습니다.

그런 다음 서비스를 스타트업 클래스에 등록합니다.

services.AddSingleton<IUserIdProvider, CustomEmailProvider>();

다음. 사용자 등록 시 클레임을 추가합니다.

var result = await _userManager.CreateAsync(user, Model.Password);
if (result.Succeeded)
{
    await _userManager.AddClaimAsync(user, new Claim(ClaimTypes.Email, Model.Email));
}

특정 사용자에게 메시지를 보냅니다.

public class ChatHub : Hub
{
    public async Task SendMessage(string receiver, string message)
    {
        await Clients.User(receiver).SendAsync("ReceiveMessage", message);
    }
}

참고: 메시지 발송인에게 메시지가 발송되었음을 알리지 않습니다.발신측에서 통지를 받고 싶은 경우.를 변경하다SendMessage방법을 선택합니다.

public async Task SendMessage(string sender, string receiver, string message)
{
    await Clients.Users(sender, receiver).SendAsync("ReceiveMessage", message);
}

이러한 절차는 기본 식별자를 변경해야 하는 경우에만 필요합니다.그렇지 않으면 userId 또는 connectionIds를 전달하여 메시지를 발송할 수 있는 마지막 단계로 넘어갑니다.SendMessage자세한 것은 이쪽

기능에 대해서는, SignalR Tests 를 참조해 주세요.

"SendToUser" 테스트는 일반 OWIN 인증 라이브러리를 사용하여 전달된 사용자 ID를 자동으로 가져옵니다.

시나리오에서는 여러 디바이스/브라우저에서 접속한 사용자가 모든 활성 접속에 메시지를 푸시하려고 합니다.

오래된 스레드지만 샘플에서 우연히 발견한 것입니다.

services.AddSignalR()
            .AddAzureSignalR(options =>
        {
            options.ClaimsProvider = context => new[]
            {
                new Claim(ClaimTypes.NameIdentifier, context.Request.Query["username"])
            };
        });

언급URL : https://stackoverflow.com/questions/19522103/signalr-sending-a-message-to-a-specific-user-using-iuseridprovider-new-2-0