Question

I'm somewhat new to SignalR. I understand hubs to a limited degree, but I don't understand how two users can share a connection while excluding others.

My scenario is that I want an unauthenticated public website user to be able to initiate a private (not necessarily secure) chat session with a customer service user.

Is there an example or resource that my point me in the right direction?

I've looked at a few resources, including http://www.asp.net/signalr/overview/signalr-20/hubs-api/mapping-users-to-connections but haven't found the right scenario.

Was it helpful?

Solution

You can create groups, so add some methods to your hub (a subscribe method should return a Task as they are asynchronous...)

public Task SubscribeToGroup(string groupName)
{
     return Groups.Add(Context.ConnectionId, groupName);
}

Then you publish notifications to users of that group as normal but via the groups collection...

public void BroadcastMessageToGroup(string groupName, string message)
{
    Clients.Group(groupName).onCaptionReceived(message);
}

Now only subscribers of that particular group will get the message!

Hope this helps.

You can find a tutorial here for SignalR Groups.

http://www.asp.net/signalr/overview/signalr-20/hubs-api/working-with-groups

OTHER TIPS

You can create a group in Hub's API, in this method each user is a member of that group. And they send a message to that group ( via the server), and because they are only 2 members they are the only one's who see the messages ( privatly)

You can also message a group member directly by connection ID. This requires your app to keep track of connection IDs of users as they connect and disconnect, but this isn't too difficult:

//Users: stores connection ID and user name
public static ConcurrentDictionary Users = new ConcurrentDictionary();

public override System.Threading.Tasks.Task OnConnected()
{
    //Add user to Users; user will supply their name later. Also give them the list of users already connected
    Users.TryAdd(Context.ConnectionId, "New User");
    SendUserList();
    return base.OnConnected();
}

//Send everyone the list of users (don't send the userids to the clients)
public void SendUserList()
{
    Clients.All.UpdateUserList(Users.Values);
}

//Clients will call this when their user name is known. The server will then update all the other clients
public void GiveUserName(string name)
{
    Users.AddOrUpdate(Context.ConnectionId, name, (key, oldvalue) => name);
    SendUserList();
}

//Let people know when you leave (not necessarily immediate if they just close the browser)
public override System.Threading.Tasks.Task OnDisconnected()
{
    string user;
    Users.TryRemove(Context.ConnectionId, out user);
    SendUserList();
    return base.OnDisconnected();
}

//Ok, now we can finally send to one user by username
public void SendToUser(string from, string to, string message)
{
    //Send to every match in the dictionary, so users with multiple connections and the same name receive the message in all browsers
    foreach(KeyValuePair user in Users)
    {
        if (user.Value.Equals(to))
        {
            Clients.Client(user.Key).sendMessage(from, message);
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top