Home > database >  Why I can't get the HubCallerContext user with web sockets connections?
Why I can't get the HubCallerContext user with web sockets connections?

Time:12-08

when I use the WebSockets I Can't get the userId on the server

Client code:

    HubConnection = new HubConnectionBuilder().WithUrl(Config.BaseUrl   ApplicationConstants.SignalR.HubUrl, options =>
    {
        options.Transports = Microsoft.AspNetCore.Http.Connections.HttpTransportType.WebSockets;
        options.Headers.Add("Authorization", $"Bearer {NPCompletApp.Token}");
        options.AccessTokenProvider = async () => await Task.FromResult(NPCompletApp.Token);
    }).WithAutomaticReconnect().Build();

Server code:

public override async Task<Task> OnConnectedAsync()
        {

            ConnectedUserModel connectedUserModel = new ConnectedUserModel() 
            { 
                ConnectionId = Context.ConnectionId, UserId = _userManager.GetUserId(Context.User)
            };

            UserHandler.connectedUsers.Add(connectedUserModel);

            var temp = new List<string>();

            foreach(ConnectedUserModel connectedUser in UserHandler.connectedUsers)
            {
                if (!String.IsNullOrEmpty(connectedUserModel.UserId) && temp.Find(x=> x == connectedUserModel.UserId) == null)
                {
                    temp.Add(connectedUserModel.UserId);
                    await OnConnectAsync(connectedUserModel.UserId);

                }
            }

            
            

            return base.OnConnectedAsync();
        }

The good thing is that I can catch if the user Disconnected, but still can't know who is the user.

server code (On disconnecting):

 public override async Task<Task> OnDisconnectedAsync(Exception? exception)
        {

            var connection =  UserHandler.connectedUsers.Find(x => x.ConnectionId == Context.ConnectionId);

            await OnDisconnectAsync(connection.UserId);

            UserHandler.connectedUsers.Remove(connection);

            return base.OnDisconnectedAsync(exception);
        }

On the other hand When I use LongPolling I can get the userId but I can't catch him when disconnecting

client code:

    HubConnection = new HubConnectionBuilder().WithUrl(Config.BaseUrl   ApplicationConstants.SignalR.HubUrl, options =>
    {

        options.Transports = Microsoft.AspNetCore.Http.Connections.HttpTransportType.LongPolling;
        options.Headers.Add("Authorization", $"Bearer {NPCompletApp.Token}");
        options.AccessTokenProvider = async () => await Task.FromResult(NPCompletApp.Token);
    }).WithAutomaticReconnect().Build();

What should I do ? I want to know who is the user in my context & to catch him when he diconnected.

CodePudding user response:

On your server your have to configure the middleware.

This is taken from a working project...

Server :

services.TryAddEnumerable(
    ServiceDescriptor.Singleton<IPostConfigureOptions<JwtBearerOptions>,
    ConfigureJwtBearerOptions>());

ConfigureJwtBearerOptions.cs

    public class ConfigureJwtBearerOptions : IPostConfigureOptions<JwtBearerOptions>
    {
        private readonly ChatConfigurations config;

        public ConfigureJwtBearerOptions(ChatConfigurations config)
        {
            this.config = config;
        }

        public void PostConfigure(string name, JwtBearerOptions options)
        {
            var originalOnMessageReceived = options.Events.OnMessageReceived;
            options.Events.OnMessageReceived = async context =>
            {
                await originalOnMessageReceived(context);

                if (string.IsNullOrEmpty(context.Token)) {

                    var accessToken = context.Request.Query["access_token"];
                    var requestPath = context.HttpContext.Request.Path;
                    var endPoint = $"/{config.EndPoint}";

                    if (!string.IsNullOrEmpty(accessToken) &&
                        requestPath.StartsWithSegments(endPoint)) {
                        context.Token = accessToken;
                    }
                }
            };
        }
    }

In your client you also have to configure for tokens.

public async ValueTask InitialiseAsync()
{
    IsInitialised = false;
    hubConnection = CreateHubConnection();

    hubConnection.On<string, string>("ReceiveMessage", ReceiveMessageAsync);

    ....

    await hubConnection.StartAsync();
    await hubConnection.SendAsync("JoinGroup", roomName);

    IsInitialised = true;

}

private HubConnection CreateHubConnection()
{
    var endPoint = $"/{config.EndPoint}";
    var hubConnection = new HubConnectionBuilder()
         .WithUrl(navigationManager.ToAbsoluteUri(endPoint), options =>
         {
             options.AccessTokenProvider = async () =>
             {
                 var accessTokenResult = await accessTokenProvider.RequestAccessToken();
                 accessTokenResult.TryGetToken(out var accessToken);
                 var token = accessToken.Value;
                 return token;
             };
         })
         .WithAutomaticReconnect()
         .Build();

    return hubConnection;
}

My Hubs OnConnectedAsync

public async override Task OnConnectedAsync()
{
    logger.LogDebug("Hub Connection");
    await chatService.RegisterConnectionAsync(Context.ConnectionId, Context.UserIdentifier);
    await base.OnConnectedAsync();
}

Note: I am persisting connections to a database.

My Hubs OnDisconnectedAsync

public async override Task OnDisconnectedAsync(Exception exception)
{
    logger.LogDebug("Hub Disconnect");
    await chatService.RegisterDisconnectAsync(Context.ConnectionId);
    await base.OnDisconnectedAsync(exception);
}

Some debug logs:

dbug: OrakTech.ChatServer.Brokers.Loggings.LoggingBroker[0]
      Hub Connection
dbug: OrakTech.ChatServer.Brokers.Loggings.LoggingBroker[0]
      Hub Connected (r7SJaAMEGs7eovH810H5Xg, c8f81673-d8b3-4e46-80f6-a83b671e6ff1)
dbug: OrakTech.ChatServer.Brokers.Loggings.LoggingBroker[0]
      Join Group (TestRoom : r7SJaAMEGs7eovH810H5Xg)
dbug: OrakTech.ChatServer.Brokers.Loggings.LoggingBroker[0]
      Hub Disconnect
dbug: OrakTech.ChatServer.Brokers.Loggings.LoggingBroker[0]
      Hub Disconnect (r7SJaAMEGs7eovH810H5Xg)
  • Related