【问题标题】:ASP.NET Core with - Refresh UI with SignalR when certain changes are made to the DBASP.NET Core with - 当对数据库进行某些更改时,使用 SignalR 刷新 UI
【发布时间】:2020-07-24 01:50:18
【问题描述】:

我有一个通知面板,它本身保存与当前用户相关的通知。我正在努力理解集线器和客户端脚本一起执行的整个概念。我想刷新使用 SignalR 接收通知的用户的 UI。

中心类

public class NotificationHub : Hub
{
    private readonly ApplicationDbContext dbContext;

    public NotificationHub(ApplicationDbContext dbContext)
    {
        this.dbContext = dbContext;
    }

    public override Task OnConnectedAsync()
    {
        base.OnConnectedAsync();
        var user = this.Context.User.Identity.Name;
        // Groups.AddAsync(Context.ConnectionId, user);

        return Task.CompletedTask;
    }
}

配置:

        services.AddSignalR();
        services.AddSingleton(typeof(IUserIdProvider), typeof(MyUserIdProvider));

路线

        app.UseEndpoints(
            endpoints =>
                {
                    endpoints.MapControllerRoute("areaRoute", "{area:exists}/{controller=Home}/{action=Index}/{id?}");
                    endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
                    endpoints.MapRazorPages();
                    endpoints.MapHub<NotificationHub>("/notificationHub");
                });

这是向 Dogsitter 用户发送通知的控制器,这里我想刷新 Dogsitter 的通知 UI:

[HttpPost]
    public async Task<IActionResult> SendRequestToDogsitter([FromForm]string id, SendNotificationInputModel inputModel)
    {
        var user = await this.userManager.GetUserAsync(this.User);
        var owner = user.Owners.FirstOrDefault();
        var dogsitter = this.dogsitterService.GetDogsitterByDogsitterId(id);

        await this.ownerService.SendNotification(id, owner, inputModel.Date, inputModel.StartTime, inputModel.EndTime);

        // Refresh the page to reflect changes.
        await this.notificationHubContext.Clients.User(user.UserName).SendAsync("refreshUI");

        // Notify the user who is receiving the notification. (if connected)
        await this.notificationHubContext.Clients.User(owner.User.UserName).SendAsync("sendNotification", dogsitter.User.UserName);

        return this.RedirectToAction("FindDogsitter");
    }

由于我的通知面板存在于布局页面中呈现的部分视图中,因此我将脚本放在布局页面本身中:

 <script>
        var notificationConnection;
        openConnection();

        function openConnection() {
            notificationConnection = new signalR.HubConnection("/notificationHub");
            notificationConnection
                .start()
                .catch(() => {
                    alert("Error while establishing connection");
                });
        }

        notificationConnection.on("SendNotification", (user) => {

        });

        friendConnection.on("refreshUI", (user) => {

        });
    </script>

最后是我在这篇文章之后更改的 MyUserIdProvider:https://docs.microsoft.com/en-us/archive/msdn-magazine/2018/august/cutting-edge-social-style-notifications-with-asp-net-core-signalr

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

基本上,当用户由于某些操作而必须通知另一个用户时,我希望服务器侦听函数调用 refreshUI 将刷新目标用户 UI。我真的不知道如何开始使用客户端部分.非常感谢任何帮助。

【问题讨论】:

  • 你想在SignalR的某条消息到达时刷新页面?
  • 更像是在我向数据库提交更改之后。只需快速刷新通知选项卡即可。那是我不知道的。
  • 如果您使用的是 SignalR,则不应刷新通知选项卡,这就是可以使用 signalR 的原因。您只需添加通知,无需刷新 UI。
  • 但是我该怎么做呢?至少在我的情况下。我的通知有操作链接,如何仅使用 SignalR 和客户端代码在通知面板中添加具有全部功能的通知。
  • 我添加了一个答案。

标签: javascript c# asp.net-core asynchronous signalr


【解决方案1】:

您只需要一个连接到 signalR 的服务、集线器上已有的通知面板、客户端连接时获取所有通知的方法和广播方法,例如:

在您的集线器上,当客户端连接时,您应该会收到所有通知:

public async Task<OperationResult> GetNotificationsAsync(Groups groups)
{
    try
    {
        IList<OutgoingNotification> notifications = await this.NotificationsManager.GetNotificationsForThisClientAsync(groups).ConfigureAwait(false);

        if (notifications.Count != 0)
        {
            // Send the notifications

            for (int i = 0; i < notifications.Count; i++)
            {
                await this.BroadcastNotificationToCallerAsync(notifications[i]).ConfigureAwait(false);
            }
        }

        return OperationResult.Success();
    }
    catch (ArgumentNullException)
    {
        throw new ServiceException(ServiceExceptionCode.NoDataProvidedToGetNotifications, Resources.RES_No_Data_Provided_To_Get_Notifications);
    }
}

在客户端:

private async getNotifications(groups: ISignalRGroups) {
  await this.hubMessageConnection.invoke("GetNotificationsAsync", groups)
    .then(() => {
      this.onGetNotificationsComplete.emit();
    })
    .catch(() => {
      this.onError.emit(WidgetStateEnum.getNotificationError);
    });
}

然后,当您想发送通知时,只需通过 DI 注入您的管理器中的集线器即可发送通知,例如:

private IHubContext<NotificationsHub, INotificationsHub> NotificationsHub
{
    get
    {
        return this.serviceProvider.GetRequiredService<IHubContext<NotificationsHub, INotificationsHub>>();
    }
}
public async Task SendNotificationToGroupAsync(OutgoingNotification outcomingNotification)
{
    await this.NotificationsHub.Clients.Group(outcomingNotification.Target).Message(outcomingNotification).ConfigureAwait(false);
}

【讨论】:

  • 我会试试这个。非常感谢。
猜你喜欢
  • 2023-04-03
  • 2017-02-12
  • 1970-01-01
  • 1970-01-01
  • 2014-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-13
相关资源
最近更新 更多