0

I just finished one SignalR sample, the well-known Chat sample.

This sample just broadcast a chat message from one client to all the clients. What if we want to send message to only a specific client?

(I guess there should be some ID to identify each client. These IDs should be stored on server when clients subscribe to the server. And server can choose which ID to push message to. )

smwikipedia
  • 61,609
  • 92
  • 309
  • 482
  • 1
    Maybe this helps you: http://stackoverflow.com/questions/19522103/signalr-sending-a-message-to-a-specific-user-using-iuseridprovider-new-2-0 – Kr15 Jul 08 '14 at 16:32

2 Answers2

2

You have different way to map your user with a connection. You can compare the different ways in this tutorial depending on your requirements.

Another solution is to define 1 group per userId and notify the group when you want to notify a user (link). Be careful, groups are not secured.

Daniel
  • 9,312
  • 3
  • 48
  • 48
  • 1 up for the great information! One of the next things i want to implement in a MVC 5 project is secure group chat and secure personal chat. How do you mean "groups are not secured"? – Kr15 Jul 08 '14 at 17:20
  • 1
    I'm not sure if this is what Daniel is referring to, but SignalR's `groupsToken` (which is used by the server to validate the groups a client is in) does not expire. This makes it impossible to securely remove a client from a group. – halter73 Jul 08 '14 at 19:16
  • Yes that's it. And as the token is not regenerated, once the user joined the group, he can join it as long as he keeps the token. – Daniel Jul 09 '14 at 08:50
  • Thanks, but that means a secure group chat can not be done with SignalR's groupsToken? Do you have then any tips / best practice on how to implement a secure group chat? – Kr15 Jul 09 '14 at 09:23
  • 1
    @Kr15 create a chat room class that holds all users for each chat room. Store the connectionIds in them. When a user sends a message in a room iterate over all the users use `context.Clients.Client` from my answer to get the client and send the message to each client. – Anders Jul 09 '14 at 10:43
  • @Anders: Thanks! Should i implement separated chat hub classes for each group? – Kr15 Jul 09 '14 at 11:22
  • 1
    Create a ChatRoom class or similar with a list of users. Instance one of these for each room or group or what ever you call them. – Anders Jul 10 '14 at 11:02
  • @Anders: Separated room-instance for each room with a list of room-users makes sense, but do i have to create separated hubs for each room? (It has to be a secure solution!) – Kr15 Jul 10 '14 at 12:09
  • Nope, that wont make it more secure. Just one hub, but you must use the ASP.NET authorization framework to validate a persons rights to a specific "Group" you cant trust the client sending this info – Anders Jul 10 '14 at 12:19
  • 1
    You dont need to use the ASP.NET library for this, but what I am saying is that you need to authorize the user in some server side manner when he connects to a chat room/group. – Anders Jul 10 '14 at 12:22
1

Like Daniel describes you can use a group or use the hubcontext to get the context for a specific connection using the connection Id.

var client = context.Clients.Client(connectionId);

There are also several libraries that abstract SignalR, some of these comes with their own way of calling specific users.

I have made a library like this which is based on the Event aggregation pattern. It comes with a API to let you create code that determines which clients should receive a specific event

https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy/wiki/Implement-constraint-handlers

Here is also a blog post I made showing how you can achieve declarative role authorization with my library, maybe it can give you some ideas. http://andersmalmgren.com/2014/06/12/client-server-event-aggregation-with-role-authorization/

Anders
  • 17,306
  • 10
  • 76
  • 144
  • See update, I added a link to a blog post about declarative role authorization. Maybe shows more angels on how to solve SignalR message security – Anders Jul 09 '14 at 10:47