Guest
Guest

Reputation: 275

SignalR send message to specific user

I created a SignalR project. Want an application like basic whatsapp. I can send message to all clients with SignalR, but I can't send message to a specific user.

Here is what I tried.

Server side

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.MapSignalR();
    }
}

public class ChatHub : Hub
{
    public static string UserName = "";
    public void Send(string User, string Message)
    {
        //It doesn't works
        Clients.User(UserName).sendMessage(Message);
        //It works
        Clients.All.sendMessage(Message);
    }
    public override Task OnConnected()
    {
        //It works I get the UserName
        UserName = Context.QueryString["UserName"];
        return base.OnConnected();
    }
}

Client Side

protected override async void OnAppearing()
{
    chatHubConnection = new HubConnection("http://192.168.2.2:80/", new Dictionary<string, string>{
        { "UserName", myUser }
     });
    chatHubProxy = chatHubConnection.CreateHubProxy("ChatHub");
    chatHubProxy.On<string>("sendMessage", (k) => {
        Messages.Add(string.Format("Msg:{0}", k));
    });
    await chatHubConnection.Start();
}
private async void SendButton_Clicked(object sender, EventArgs e)
{
    await chatHubProxy.Invoke<string>("Send", recieverEntry.Text, messageEntry.Text);
}

Upvotes: 3

Views: 15176

Answers (1)

Kaushal
Kaushal

Reputation: 1359

Use ConnectionId to send message to specific client. UserId and UserName are different things, for more detail - https://learn.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/mapping-users-to-connections

Change your code to following (Ideally this Connections dictionary should be extracted as separate class to handle Username to Connection mapping)

public class ChatHub : Hub
{
    public static ConcurrentDictionary<string, string> Connections = new ConcurrentDictionary<string, string>();
    public void Send(string username, string message)
    {
        string connectionToSendMessage;
        Connections.TryGetValue(username, out connectionToSendMessage);

        if (!string.IsNullOrWhiteSpace(connectionToSendMessage))
        {
            Clients.Client(connectionToSendMessage).SendMessage(message);
        }
    }
    public override Task OnConnected()
    {
        if (!Connections.ContainsKey(Context.ConnectionId))
        {
            Connections.TryAdd(Context.QueryString["UserName"], Context.ConnectionId);
        }

        return base.OnConnected();
    }
}

Upvotes: 6

Related Questions