I have created a Blazor webapp that shows a calendar-like page with various 'events' on it. You can drag/drop these events between days.
When multiple users are looking at similar dates, how can I ensure they will be able to see the changes being made by another user(s)?
The data for the calendar is being retrieved from a .NET API and then stored in memory for each of use. As the user drag/drops, the event is updated on their UI and also in the database.
I do not have much Blazor experience but I feel like this should be possible?
Once a given user's update to an event is propagated to the db, and you want to real-time update the UI for everyone consulting the calendar, you can use SignalR to achieve this. (it is a library that allows server-side code to send asynchronous notifications to client-side web applications.)
In your ASP.NET API, register and configure SignalR and create a Hub to handle this realtime communication, for example:
in your Program.cs
or your custom static extensions class:
builder.services.AddSignalR();
//.......
//.......
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<CalendarHub>("/calendarHub");
// other endpoints
});
using Microsoft.AspNetCore.SignalR;
public class CalendarHub : Hub
{
public async Task UpdateEvent(string eventId, string newDate)
{
await Clients.All.SendAsync("ReceiveEventUpdate", eventId, newDate);
}
}
When an event is dragged and dropped, it should trigger an update on the API, so we need to handle it and notify all the clients, so in your controller for example:
[ApiController]
[Route("api/[controller]")]
public class EventsController : ControllerBase
{
private readonly IHubContext<CalendarHub> _hubContext;
public EventsController(IHubContext<CalendarHub> hubContext)
{
_hubContext = hubContext;
}
[HttpPost("update")]
public async Task<IActionResult> UpdateEvent(EventUpdateModel model)
{
// Update event in database
// ...
// Notify all clients
await _hubContext.Clients.All.SendAsync("ReceiveEventUpdate", model.EventId, model.NewDate);
return Ok();
}
}
Now in your Blazor Component, you need to connect to the SignalR Hub so you can handle the updates, for example:
@code {
private HubConnection hubConnection;
protected override async Task OnInitializedAsync()
{
hubConnection = new HubConnectionBuilder()
.WithUrl(Navigation.ToAbsoluteUri("/calendarHub"))
.Build();
hubConnection.On<string, string>("ReceiveEventUpdate", (eventId, newDate) =>
{
// Update the event in your UI
StateHasChanged();
});
await hubConnection.StartAsync();
}
}
I tried to make it as simple as possible just to kickstart how you can solve this situation, you can check Microsoft's SignalR Documentation as it pretty much takes into consideration what render mode and other configs someone may be using.