【问题标题】:Why I can't get the HubCallerContext user with web sockets connections?为什么我无法通过 Web 套接字连接获得 HubCallerContext 用户?
【发布时间】:2022-01-12 05:58:36
【问题描述】:

当我使用 WebSockets 时,我无法在服务器上获取 userId

客户端代码:

    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();

服务器代码:

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();
        }

好在如果用户断开连接我可以捕捉到,但仍然不知道用户是谁。

服务器代码(断开连接时):

 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);
        }

另一方面,当我使用 LongPolling 时,我可以获得 userId,但在断开连接时我无法捕捉到他

客户端代码:

    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();

我该怎么办?我想知道我的上下文中的用户是谁,并在他断开连接时抓住他。

【问题讨论】:

    标签: c# asp.net asp.net-core signalr blazor


    【解决方案1】:

    您必须在您的服务器上配置中间件。

    这是取自一个工作项目...

    服务器:

    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;
                        }
                    }
                };
            }
        }
    
    

    在您的客户端中,您还必须配置令牌。

    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;
    }
    

    我的集线器OnConnectedAsync

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

    注意:我正在保持与数据库的连接。

    我的集线器OnDisconnectedAsync

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

    一些调试日志:

    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)
    

    【讨论】:

    • 非常感谢❤️
    猜你喜欢
    • 1970-01-01
    • 2015-02-05
    • 1970-01-01
    • 2014-08-26
    • 1970-01-01
    • 1970-01-01
    • 2022-07-24
    • 2014-06-01
    • 1970-01-01
    相关资源
    最近更新 更多