18

I have the following JS working:

var chat = $.connection.appHub;

My app has a single hub, AppHub, that handles two types of notifications - Chat and Other. I'm using a single hub because I need access to all connections at all times.

I need to be able to tell OnConnected which type it is via something like the following:

[Authorize]
public class AppHub : Hub {
    private readonly static ConnectionMapping<string> _chatConnections =
        new ConnectionMapping<string>();
    private readonly static ConnectionMapping<string> _navbarConnections =
        new ConnectionMapping<string>();
    public override Task OnConnected(bool isChat) { // here
        string user = Context.User.Identity.Name;
        if (isChat){
            _chatConnections.Add(user, Context.ConnectionId);
            _navbarConnections.Add(user, Context.ConnectionId);
        } else{
            _navbarConnections.Add(user, Context.ConnectionId);
        }  
    }
}

Usage would ideally be something like this:

var chat = $.connection.appHub(true);

How can I pass that parameter to the hub from javascript?

Update:

SendMessage:

 // will have another for OtherMessage
 public void SendChatMessage(string who, ChatMessageViewModel message) {
    message.HtmlContent = _compiler.Transform(message.HtmlContent);
    foreach (var connectionId in _chatConnections.GetConnections(who)) {
        Clients.Client(connectionId).addChatMessage(JsonConvert.SerializeObject(message).SanitizeData());
    }
}
RobVious
  • 12,685
  • 25
  • 99
  • 181

2 Answers2

34

I would rather add a method to the hub that you call from the client to subscribe to the type. E.g.

public void Subscribe(bool isChat) {
    string user = Context.User.Identity.Name;
    if (isChat){
        _chatConnections.Add(user, Context.ConnectionId);
    } else{
        _otherConnections.Add(user, Context.ConnectionId);
    }
}

You call this method after the hub is connected. It is more flexible in terms that it is then possible to change the notification type without having to reconnect. (Unsubscribe and Subscribe)

Alternative

If you don't want the extra roundtrip/flexibility. You can send QueryString parameters when connecting to the hub. Stackoverflow answer: Signalr persistent connection with query params.

$.connection.hub.qs = 'isChat=true';

And in OnConnected:

var isChat = bool.Parse(Context.QueryString["isChat"]);
Hallvar Helleseth
  • 1,867
  • 15
  • 17
  • I'm a little confused - I'm using Dictionaries to store connections, not Groups. I'll post my SendMessage method. – RobVious Dec 21 '13 at 23:19
  • Sorry, I took that from my own code. It should work if you change Subscribe's method body with the one in your OnConnected method – Hallvar Helleseth Dec 21 '13 at 23:21
  • I'm still a little confused - would I not override OnConnected at all then? This will also require another round-trip request to initiate, right? And - I'm not concerned about reconnections - ChatHub is for a dedicated page, and OtherHub is for navbar notifications. The user will actually be connected to both hubs when visiting Chat - I just didn't include that above. Corrected now. Thoughts? – RobVious Dec 21 '13 at 23:26
  • 1
    Yes it does require an extra a roundtrip. I found an alternative solution that is probably more what you were looking for. – Hallvar Helleseth Dec 21 '13 at 23:37
3

Hallvar's answer is useful in most cases. But sometimes you could also use headers to send data to the OnConnected method.

Code example for Asp .Net Framework:

var myParameter = HttpContext.Current.Request.Headers["HeaderName"];

For .NET 5+ you may need Dependency Injection to access HttpContext, as shown here

Ruben Martirosyan
  • 870
  • 1
  • 12
  • 23