【问题标题】:Implementing a global notification system in blazor server with SignalR使用 SignalR 在 blazor 服务器中实现全局通知系统
【发布时间】:2022-04-27 15:14:58
【问题描述】:

我正在尝试实现一个通知系统,该系统根据特定用户在具有 SignalR 的 Blazor 服务器端 .NET 5 中的角色或权限来通知他们。 我已经实现了身份验证和授权。

在我的MainLayout.razor 页面中,我实现了一个HubConnectionBuilder,如下所示:

private HubConnection _hubConnection;

protected override async Task OnInitializedAsync()
{
    //SignalR
    _hubConnection = new HubConnectionBuilder()
        .WithUrl(MyNavigationManager.ToAbsoluteUri("/hub"))
        .Build();

    _hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
    {
        Toaster.NotificacaoGlobal(user, message);
        StateHasChanged();
    });

    await _hubConnection.StartAsync();
}

我还创建了一个 TestHub.cs,其中有一些方法如下:

public class TestHub : Hub
{
    public async Task SendMessage(string user, string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }

    public override Task OnConnectedAsync()
    {
        return base.OnConnectedAsync();
    }

    public override Task OnDisconnectedAsync(Exception exception)
    {
        return base.OnDisconnectedAsync(exception);
    }
}

在 Startup.cs 我添加了:

app.UseEndpoints(endpoints =>
            {
                endpoints.MapBlazorHub();
                endpoints.MapFallbackToPage("/_Host");
                endpoints.MapHub<TestHub>("/hub");
            });

services.AddSignalR();

我的想法是将 connectionId 和 UserId 存储在 OnConnectedAsync() 上,然后在 await Clients.All.SendAsync("ReceiveMessage", user, message); 方法上使用 Clients.User(userId).SendAsync("ReceiveMessage", user, message); 之类的内容过滤用户

我尝试在 OnConnectedAsync() 方法中同时使用 Context.UserIdentifierContext.User.Identity.Name 并且都返回 null。有人说在TestHub.cs 中使用[Authorize] 属性,但这给了我一个例外:HttpRequestException: Response status code does not indicate success: 401 (Unauthorized). on await _hubConnection.StartAsync()

实施 IUserIdProvider 并没有像某些人建议的那样解决问题:

public class IdBasedUserIdProvider : IUserIdProvider
 {
      public string GetUserId(HubConnectionContext connection)
      {
           //TODO: Implement USERID Mapper Here
           //throw new NotImplementedException();

           return connection.User.FindFirst("sub").Value;
      }
 }


services.AddSingleton<IUserIdProvider, IdBasedUserIdProvider>();

我是 blazor 和 SignalR 的新手,我可能不知道。

提前致谢!

编辑 1:

如被问及,我将尽我所能澄清我遇到的问题。

我需要什么?向特定用户发送推送通知的系统。

我做了什么?尝试实现 SignalR 以通过 SignalR 发送这些通知

斗争:在我的剃须刀页面上实现TestHub.cs 类和OnInitializedAsync() 上的初始化程序后,我无法在SignalR 中使用connectionId 映射身份用户。 如果可能的话,我需要澄清一下,我在实现 SignalR 时是否犯了错误,SignalR 在这种情况下是否有意义,或者是否有任何其他工具或系统更有意义。

我希望我已经足够澄清了。谢谢。

【问题讨论】:

  • 我建议您编辑您的问题并在开始时澄清问题和您的问题。目前您似乎要求进行设计审查。
  • 我已经在编辑 1 上更新了我的问题,我试图澄清我的问题。提前致谢

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


【解决方案1】:

我尝试在 OnConnectedAsync() 方法中同时使用 Context.UserIdentifier 和 Context.User.Identity.Name 并且都返回 null。

创建自定义 IUserIdProvider

public class UserNameProvider : IUserIdProvider
{
    public string GetUserId(HubConnectionContext connection)
    {
        return connection.User?.Identity?.Name?? "";
    }
}

并将其添加到您的 programm.cs 中

builder.Services.AddSingleton<IUserIdProvider, UserNameProvider>();

那么 Context.UserIdentifier 不应再为空

[Authorize]
public class ChatHub : Hub
{
    public async Task SendMessage(string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", Context.UserIdentifier, message);
    }
}

【讨论】:

    猜你喜欢
    • 2014-11-07
    • 1970-01-01
    • 1970-01-01
    • 2016-06-19
    • 1970-01-01
    • 2018-04-27
    • 2021-11-20
    • 2012-01-06
    • 1970-01-01
    相关资源
    最近更新 更多