Mahdi.momtaheni
Mahdi.momtaheni

Reputation: 113

Send message to specific user in signalr

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

Upvotes: 10

Views: 26980

Answers (4)

waqar iftikhar
waqar iftikhar

Reputation: 95

In ChatHub Class Use This for Spacific User

public Task SendMessageToGroup(string groupName, string message)
    {

        return Clients.Group(groupName).SendAsync("Send", $"{Context.ConnectionId}: {message}");
    }

    public async Task AddToGroup(string groupName)
    {
        await Groups.AddToGroupAsync(Context.ConnectionId, groupName);

        await Clients.Group(groupName).SendAsync("Send", $"{Context.ConnectionId} has joined the group {groupName}.");
    }

    public async Task RemoveFromGroup(string groupName)
    {
        await Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);

        await Clients.Group(groupName).SendAsync("Send", $"{Context.ConnectionId} has left the group {groupName}.");
    }

Upvotes: 1

Illidan
Illidan

Reputation: 4237

In order to be able to get "Context.User.identity.Name", you supposed to integrate your authentication into OWIN pipeline.

More info can be found in this SO answer: https://stackoverflow.com/a/52811043/861018

Upvotes: 1

Anik Islam Abhi
Anik Islam Abhi

Reputation: 25352

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

Upvotes: 30

Bob Quinn
Bob Quinn

Reputation: 139

All of these answers are unnecessarily complex. I simply override "OnConnected()", grab the unique Context.ConnectionId, and then immediately broadcast it back to the client javascript for the client to store and send with subsequent calls to the hub server.

public class MyHub : Hub
{
    public override Task OnConnected()
    {
        signalConnectionId(this.Context.ConnectionId);
        return base.OnConnected();
    }

    private void signalConnectionId(string signalConnectionId)
    {
        Clients.Client(signalConnectionId).signalConnectionId(signalConnectionId);
    }
}

In the javascript:

$(document).ready(function () {

    // Reference the auto-generated proxy for the SignalR hub. 
    var myHub = $.connection.myHub;

    // The callback function returning the connection id from the hub
    myHub.client.signalConnectionId = function (data) {
        signalConnectionId = data;
    }

    // Start the connection.
    $.connection.hub.start().done(function () {
        // load event definitions here for sending to the hub
    });

});

Upvotes: 11

Related Questions