2
votes

I have a uwp client application which needs to do following 3 scenarios for chat feature.

  1. chat with everyone connected to the signal R hub ( public )
  2. chat with MyGroup only : each user will be part of a group.
  3. private chat ( 1v1 chat with other users )

I have following hub code where I somehow manage to do public and group feature.

public class ChatHub : Hub
{
    public Task SendPrivateTweet(string user, string message)
    {
        return Clients.User(user).SendAsync("ReceiveTweet", user, message);
    }

    public async Task SendTweet(string user, string message)
    {
        await Clients.All.SendAsync("ReceiveTweet", user, message);
    }


    public async Task SendTweetGroup(string groupName, string user, string message)
    {
        await Clients.Group(groupName).SendAsync("ReceiveTweet", user, message);
    }

    public async Task AddToGroup(string user, string groupName)
    {
        await Groups.AddToGroupAsync(Context.ConnectionId, groupName);

        await Clients.Group(groupName).SendAsync("EnteredOrLeft", $"{user} has joined the group {groupName}.");
    }

    public async Task RemoveFromGroup(string user, string groupName)
    {
        await Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);

        await Clients.Group(groupName).SendAsync("EnteredOrLeft", $"{user} has left the group {groupName}.");
    }
}

I have a db with users info in it and each user has a group name linked to it based on that I add each connection to their respective group.

await hubConnection.InvokeAsync("AddToGroup", user.Name, user.GroupName);

I have to do this because I do not have users logged into signalR so I cannot match their userIds with the one in my db, and that is exactly why I cannot send private message to a specific user because for that the context must have user info which it doesn't at the moment, according to docs there is some complex token bearer stuff going on and I don't know the api to popup Microsoft login for the user ( which would be ideal ).

Is there any other way how I can retain the user ids in the hub so that I can easily send a private message from client by sending the receiver user id?

I mean, can I assign a user Id from each connection at the time of connecting to the hub? which can be later on used for querying within the hub?

I can see how to do identity in a web app but can't find tutorial for doing the same in a native app like uwp: https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity?view=aspnetcore-2.2&tabs=visual-studio

1
Was the Context.User.Identity.Name you want? I saw this from here: docs.microsoft.com/en-us/aspnet/signalr/overview/security/…Bite

1 Answers

1
votes

You need to store the ConnectionId with your custom usernames. It's found as Context.ConnectionId. You'll have to handle connecting and disconnecting because the id will change between sessions.

There's an example here. Don't worry about the Identity. You can use your custom ids stored in the database. I assume since no one is logging in, you're not worried about people pretending to be someone else.

https://docs.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/mapping-users-to-connections#inmemory

To be honest, your question is confusing. I'm assuming you're making users type their name into a dialog box every time they connect, right? Then, just store the ConnectionId.