Blazor et Supabase, Temps réel - Part 3

Suite de l'article sur Blazor et Supabase, dans cette partie nous allons découvrir et mettre en place le temps réel
Banner Image Blazor et Supabase, Temps réel - Part 3
Publié par phnogues le octobre 28, 2024

English version here

Part 1 : Base de données
Part 2 : Authentification
Part 3 : Temps réel


Supabase gère également le temps réel. Dans cet article nous verrons deux façons d'utiliser le temps réel :

Je vous invite à coner le repo GitHub pour avoir le code complet avec vous : https://github.com/phnogues/Blazor.Supabase/

Prérequis:

Cas 1 - trigger depuis la base de données

1- Autoriser la table à utiliser le temps réel :
Depuis la table concernée, dans l'interface de Supabase, activer le temps réel avec le bouton "Realtime Off/On" (Table Editor / La table / bouton en haut à droite)

2- Code c# :

[Inject]
Supabase.Client _supabase { get; set; }
	
private RealtimeChannel? _crepesChannel;
	
protected override async Task OnInitializedAsync()
{
	await _supabase.Realtime.ConnectAsync();

	// channel for crepes changes
	_crepesChannel = _supabase.Realtime.Channel("public:crepes");
	if (!_crepesChannel.IsJoined)
	{
		_crepesChannel.Register(new PostgresChangesOptions("public", "crepes"));
	}
	_crepesChannel.AddPostgresChangeHandler(PostgresChangesOptions.ListenType.Inserts, CrepeInsertedHandler);
	_crepesChannel.AddPostgresChangeHandler(PostgresChangesOptions.ListenType.Updates, CrepeUpdatedHandler);

	await _crepesChannel.Subscribe();
}
private void CrepeInsertedHandler(IRealtimeChannel _, PostgresChangesResponse change)
{
	var crepe = change.Model<Crepe>();
	_notificationService.Notify(NotificationSeverity.Success, "New crepe inserted", $"{crepe.Name}");
	Events.Add($"New crepe inserted: {crepe.Name}");

	this.InvokeAsync(() => this.StateHasChanged());
}

private void CrepeUpdatedHandler(IRealtimeChannel _, PostgresChangesResponse change)
{
	var crepe = change.Model<Crepe>();
	_notificationService.Notify(NotificationSeverity.Success, "Crepe updated", $"{crepe.Name}");
	Events.Add($"Crepe updated: {crepe.Name}");

	this.InvokeAsync(() => this.StateHasChanged());
}

Cas 2 : Utilisation d'un broadcast de messages

private RealtimeChannel? _kitchenChannel;

protected override async Task OnInitializedAsync()
{
	// Realtime
	await _supabase.Realtime.ConnectAsync();
	_kitchenChannel = _supabase.Realtime.Channel("order");
	if (!_kitchenChannel.IsJoined)
	{
		_kitchenChannel.Register<Order>(true, true);
	}

	await _kitchenChannel.Subscribe();
}

// Méthode à appeler depuis un bouton ou autre
private async Task Order(CrepeDto crepe)
{
	_kitchenChannel?.Broadcast<Order>()?.Send("order", new Order { Name = crepe.Name, Price = crepe.Price, Date = DateTime.UtcNow }); ;
}

[Inject]
Supabase.Client _supabase { get; set; }

private RealtimeChannel? _orderChannel;

protected override async Task OnInitializedAsync()
{
	await _supabase.Realtime.ConnectAsync();

	// channel for orders
	_orderChannel = _supabase.Realtime.Channel("order");
	if (!_orderChannel.IsJoined)
	{
		_orderChannel.Register<Order>(true, true);
		_orderChannel?.Broadcast<Order>()?.AddBroadcastEventHandler(HandleOrderBroadcastReceived);
	}

	await _orderChannel.Subscribe();
}

public class Order : BaseBroadcast
{
	[JsonProperty("name")]
	public string Name { get; set; }

	[JsonProperty("price")]
	public float Price { get; set; }

	[JsonProperty("date")]
	public DateTime Date { get; set; }
}
private void HandleOrderBroadcastReceived(IRealtimeBroadcast sender, BaseBroadcast? args)
{
	var order = _orderChannel?.Broadcast<Order>()?.Current();

	if (order == null) return;

	_notificationService.Notify(NotificationSeverity.Warning, "New order ! ", $"{order.Name}");
	Events.Add($"New order: {order.Name} {order.Price}€ {order.Date}");

	this.InvokeAsync(() => this.StateHasChanged());
}
.Net
.Net Blazor Supabase

Commentaires :