Koushik Sarkar
Koushik Sarkar

Reputation: 498

Getting Connection Id of the client from a Controller class in MVC

I am building a chat application in MVC using signalR. I know how to get the client's ConnectionID from the Hub. But is it possible to get the same connectionID from a Controller?

I tried using HttpContext and OwinContext but from the several properties I couldn't find the ConnectionId property. Not even in the Request property of the HttpContext.

Can anyone give any idea?

In this post_ How to obtain connection ID of signalR client on the server side?

_the first answer advises you to have the Hub invoke the external method.

I am aware of the design where we keep a Dictionary that maps each userId to several ConnectionIds for several devices.

But Let's say there is a UserController which has a LogIn and LogOut Action. It would be easier if I could get the connectionId of the user who just logged in. Then I would simply get its userID from the DbContext and store it the previously mentioned Dictionary, which can later be used by the Hub.

Upvotes: 3

Views: 5829

Answers (1)

Luke
Luke

Reputation: 23690

You can use $.connection.hub.id within your JavaScript on the client side and Context.connectionId within your SignalR hub (see here) to get the connection ID of the user.

You can then do whatever you want with it, you could post it from the client side via AJAX to a controller or from the server side to your client from your SignalR hub.

If you need to retrieve the SignalR connection ID that hasn't already been persisted in some form (sessions, database) from within a controller - that sounds like a code smell to me.

You should be performing anything that you need to do from within your SignalR hub. Whether it be some processing, or sending your client ID to the database for later use by your controller.

If the problem is that the code you want to execute already exists within your Controller and you want to use that and you don't want it to exist in two places, you should move this code into a service layer (business layer) and add it as a dependency to your Controller and to your SignalR hub.

In terms of mapping your connection ID to the logged in user, this is performed as default functionality when you establish a connection to a SignalR hub, as long as your user is already logged in.

Within the hubs, you can get the ID of the user that makes the call to your hub and return a message back to them by their username or user id:

public MyHub : Hub
{
    public void FirstMethod()
    {
        // Invoke method to the current caller to the hub
        Clients.Client(connectionId).clientMethod();
    }

    public void SecondMethod()
    {
        // Get user id of the person making the call
        var userId = this.User.Identity.GetUserId();

        // Invoke method on the client side
        Clients.User(userId).clientMethod();
    }
}

Upvotes: 1

Related Questions