Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SignalR C# MVC Mapping Anonymous User to Client ID

Question: How do I manage anonymous users so that multiple tabs in a single browser are all updated when the Hub sends out a response?

The scenario is as follows:

I would like to integrate SignalR into a project so that anonymous users can live chat with operators. Obviously user's that have authenticated with iIdentity are mapped via the Client.User(username) command. But currently say an anonymous user is browsing site.com/tools and site.com/notTools I can not send messages to all tabs with only a connectionID. Only one tab gathers the response.

I have tried using IWC patch but that tool doesn't account for saving chat information into a database and I think passing variables via ajax isn't a secure way to read/write to a database.

I have also looked in the following: Managing SignalR connections for Anonymous user

However creating a base such as that and using sessions seems less secure than Owin.

I had the idea to use client.user() by creating a false account each time a user connects and delete it when they disconnect. But I would rather not fill my aspnetusers db context with garbage accounts it seems unnecessary.

Is it possible to use UserHandler.ConnectedIds.Add(Context.ConnectionId); to also map a fake username? Im at a loss.

Would it make sense to use iUserId provider?

public interface IUserIdProvider
{
    string GetUserId(IRequest request);
}

Then create a database that stores IP addresses to connectionIDs and single usernames?

database:

Users: With FK to connection IDs

|userid|username|IP       |connectionIDs|
|   1  | user1  |127.0.0.1|  1          |
|   2  | user2  |127.0.0.2|  2          |

connectionIDs:

|connectionID|SignalRID|connectionIDs|
|      1     | xx.x.x.x|     1       |
|      2     | xx.xxx.x|     2       |
|      3     | xx.xxxxx|     2       |
|      4     | xxxxx.xx|     2       |

Then Possibly write logic around the connection?

public override Task OnConnected()
    {
     if(Context.Identity.UserName != null){
      //add a connection based on the currently logged in user. 
     }
    else{
     ///save new user to database?
     } 
  }

but the question still remains how would I handle multiple tabs with that when sending a command on the websocket?

update To be clear, my intent is to create a live chat/support tool that allows for in browser anonymous access at all times.

The client wants something similar to http://www.livechatinc.com

I have already created a javascript plugin that sends and receives from the hub, regardless of what domain it is on. (my client has multisites) the missing piece to the puzzle is the simplest, managing the anonymous users to allow for multi-tabbed conversations.

like image 384
Chris Avatar asked Jan 21 '16 01:01

Chris


People also ask

What is SignalR C?

SignalR provides a simple API for creating server-to-client remote procedure calls (RPC) that call JavaScript functions in client browsers (and other client platforms) from server-side . NET code.

What does SignalR stand for?

Signals are used for communication (e.g. analog and digital). R stands for real-time. Real-time web refers the ability to have server code push content to the connected clients instantly. Signal R in short refers to Real-time application communication. From Signal R - A Real-Time Application.

Is SignalR real-time?

SignalR is fast and scalable Like the rest of ASP.NET, SignalR was built for high performance and is one of the fastest real-time frameworks around. Scale out across servers with built-in support for using Redis, SQL Server, or Azure Service Bus to coordinate messages between each instance.

What is difference between SignalR and WebSocket?

WebSockets is actually the underlying transport that SignalR uses, at least most of the time. SignalR has the ability to fall back to other ways of transporting messages, such as long-polling over HTTP. This is useful in situations where you don't have WebSockets support.


1 Answers

I'm not following the false user account idea (don't know if it works), but will develop an alternative.

The goal could be achieved through a ChatSessionId cookie shared by all browser tabs and creating Groups named as this ChatSessionId.

I took basic chat tutorial from asp.net/signalr and added functionality to allow chat from multiple tabs as the same user.

1) Assign a Chat Session Id in "Chat" action to identify the user, as we don't have user credential:

    public ActionResult Chat()
    {
        ChatSessionHelper.SetChatSessionCookie();
        return View();
    }

2) Subscribe to chat session when enter the chat page

client side

    $.connection.hub.start()
        .then(function(){chat.server.joinChatSession();})
        .done(function() {
           ...

server side (hub)

public Task JoinChatSession()
{
    //get user SessionId to allow use multiple tabs
    var sessionId = ChatSessionHelper.GetChatSessionId();
    if (string.IsNullOrEmpty(sessionId)) throw new InvalidOperationException("No chat session id");

    return Groups.Add(Context.ConnectionId, sessionId);
}

3) broadcast messages to user's chat session

public void Send(string message)
{
    //get user chat session id
    var sessionId = ChatSessionHelper.GetChatSessionId();
    if (string.IsNullOrEmpty(sessionId)) throw new InvalidOperationException("No chat session id");

    //now message will appear in all tabs
    Clients.Group(sessionId).addNewMessageToPage(message);
}

Finally, the (simple) ChatSessionHelper class

public static class ChatSessionHelper
{
    public static void SetChatSessionCookie()
    {
        var context = HttpContext.Current;
        HttpCookie cookie = context.Request.Cookies.Get("Session") ?? new HttpCookie("Session", GenerateChatSessionId());

        context.Response.Cookies.Add(cookie);
    }

    public static string GetChatSessionId()
    {
        return HttpContext.Current.Request.Cookies.Get("Session")?.Value;
    }

    public static string GenerateChatSessionId()
    {
        return Guid.NewGuid().ToString();
    }
}
like image 78
tede24 Avatar answered Sep 22 '22 17:09

tede24