ASP.NET 核心 - 当对数据库进行某些更改时,使用 SignalR 刷新 UI
ASP.NET Core with - Refresh UI with SignalR when certain changes are made to the DB
我有一个通知面板,它本身包含与当前用户相关的通知。我正在努力思考集线器和客户端脚本一起执行的整个概念。我想刷新使用 SignalR 接收通知的用户的 UI。
枢纽class
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;
}
}
基本上,当一个用户因为某些操作必须通知另一个用户时,我想让服务器监听函数调用刷新UI,这将刷新目标用户UI。我真的不知道如何开始使用客户端部分。非常感谢任何帮助。
您只需要一个连接到 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);
}
我有一个通知面板,它本身包含与当前用户相关的通知。我正在努力思考集线器和客户端脚本一起执行的整个概念。我想刷新使用 SignalR 接收通知的用户的 UI。
枢纽class
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;
}
}
基本上,当一个用户因为某些操作必须通知另一个用户时,我想让服务器监听函数调用刷新UI,这将刷新目标用户UI。我真的不知道如何开始使用客户端部分。非常感谢任何帮助。
您只需要一个连接到 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);
}