BlogPostPage

Retour aux articles

Blazor et Supabase, Temps réel - Part 3

Blazor et Supabase, Temps réel - Part 3

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 :

  • Un évenement est emmis lors d'une modification ou création dans une table de la base de données
  • Utilisation du temps réel via un broadcast, similaire à un outil comme SignalR

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

image

Prérequis:

  • Un compte Supabase (gratuit suffit)
  • Avoir paramétré Supabase, vu dans la partie 1 de mes articles sur Supabase

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# :

  • Pour s'abonner à un évenement de la table, dans la méthode OnInitializedAsync :
[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();
}
  • Les Handlers seront appelés lors de l'ajout ou la suppression d'une crêpe :
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

  • Rien à faire côté Supabase (mais on peut surveiller les événements depuis l'onglet Realtime)
  • Pour émettre un évenement :
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 }); ;
}

  • Pour écouter le message :
[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; }
}
  • Le Handler associé
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());
}

Commentaires (0)

Aucun commentaire pour le moment. Soyez le premier à commenter !

Laisser un commentaire

Votre email ne sera pas publié.
An unhandled error has occurred. Reload 🗙

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please reload the page.