Send message to specific user in signalr

Mahdi.momtaheni picture Mahdi.momtaheni · Jun 30, 2015 · Viewed 21.8k times · Source

I have a signalR Server(Console Application) and a client application(Asp.net MVC5)

How I can send message to specific user in OAuth Membership.

Actually I can't resolve sender user from hub request context with.

Context.User.Identity.Name

My Hub

public class UserHub : Hub
{

    #region Hub Methods
    public void LoggedIn(string userName, string uniqueId, string ip)
    {
        Clients.All.userLoggedIn(userName, uniqueId, ip);
    }
    public void LoggedOut(string userName, string uniqueId, string ip)
    {
        var t = ClaimsPrincipal.Current.Identity.Name;
        Clients.All.userLoggedOut(userName, uniqueId, ip);
    }
    public void SendMessage(string sendFromId, string userId, string sendFromName, string userName, string message)
    {
        Clients.User(userName).sendMessage(sendFromId, userId, sendFromName, userName, message);
    }
    #endregion
}

Start hub class(Program.cs)

class Program
{
    static void Main(string[] args)
    {
        string url = string.Format("http://localhost:{0}", ConfigurationManager.AppSettings["SignalRServerPort"]);
        using (WebApp.Start(url))
        {
            Console.WriteLine("Server running on {0}", url);
            Console.ReadLine();
        }
    }
}

Answer

Anik Islam Abhi picture Anik Islam Abhi · Jun 30, 2015

Keep connectionId with userName by creating a class as we know that Signalr only have the information of connectionId of each connected peers.

Create a class UserConnection

Class UserConnection{
  public string UserName {set;get;}
  public string ConnectionID {set;get;}
}

Declare a list

List<UserConnection> uList=new List<UserConnection>();

pass user name as querystring during connecting from client side

$.connection.hub.qs = { 'username' : 'anik' };

Push user with connection to this list on connected mthod

public override Task OnConnected()
{
    var us=new UserConnection();
    us.UserName = Context.QueryString['username'];
    us.ConnectionID =Context.ConnectionId;
    uList.Add(us);
    return base.OnConnected();
}

From sending message search user name from list then retrive the user connectionid then send

var user = uList.Where(o=>o.UserName ==userName);
if(user.Any()){
   Clients.Client(user.First().ConnectionID ).sendMessage(sendFromId, userId, sendFromName, userName, message);
}

DEMO