Skip to content

[Major] Provide API for presence, broadcast and postgres_changes #21

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 17 commits into from
Jan 30, 2023

Conversation

acupofjose
Copy link
Contributor

@acupofjose acupofjose commented Jan 21, 2023

Todo:

  • broadcast
    • Can broadcast changes using Send
    • Can listen for broadcasts
    • Can filter broadcast for specific event
    • Can deserialize/serialize using types.
  • presence
    • Can listen for presence changes
    • Keep track of LastState and CurrentState
    • Can Track events
    • Can deserialize/serialize using types.
  • postgres_changes
    • On Insert
    • On Update
    • On Delete
    • Wildcards
  • Update tests

Changes:

  • [Major, New] Channel.PostgresChanges event will receive the wildcard * changes event, not Channel.OnMessage.
  • [Major] Channel.OnInsert, Channel.OnUpdate, and Channel.OnDelete now conform to the server's payload of Response.Payload.**Data**
  • [Major] Channel.OnInsert, Channel.OnUpdate, and Channel.OnDelete now return PostgresChangesEventArgs
  • [Minor] Rename Channel to RealtimeChannel
  • Supports better handling of disconnects in RealtimeSocket and adds a Client.OnReconnect event.
  • [Minor] Moves ChannelOptions to Channel.ChannelOptions
  • [Minor] Moves ChannelStateChangedEventArgs to Channel.ChannelStateChangedEventArgs
  • [Minor] Moves Push to Channel.Push
  • [Minor] Moves Channel.ChannelState to Constants.ChannelState
  • [Minor] Moves SocketResponse, SocketRequest, SocketResponsePayload, SocketResponseEventArgs, and SocketStateChangedEventArgs to Socket namespace.
  • [New] Adds RealtimeBroadcast
  • [New] Adds RealtimePresence

Broadcast:

Given the following model (CursorBroadcast):

class MouseBroadcast : BaseBroadcast<MouseStatus> { }
class MouseStatus 
{
	[JsonProperty("mouseX")]
	public float MouseX { get; set; }

	[JsonProperty("mouseY")]
	public float MouseY { get; set; }

	[JsonProperty("userId")]
	public string UserId { get; set; }
}

Listen for typed broadcast events:

var channel = supabase.Realtime.Channel("cursor");

var broadcast = channel.Register<MouseBroadcast>(false, true);
broadcast<MouseBroadcast>().OnBroadcast += (sender, args) =>
{
	var state = broadcast.Current();
	Debug.WriteLine($"{state.Payload}: {state.Payload.MouseX}:{state.Payload.MouseY}");
};
await channel.Subscribe();

Broadcast an event:

var channel = supabase.Realtime.Channel("cursor");
var data = new CursorBroadcast { Event = "cursor", Payload = new MouseStatus { MouseX = 123, MouseY = 456 } };
channel.Send(ChannelType.Broadcast, data);

Presence:

Given the following model: (UserPresence)

class UserPresence: BasePresence 
{
    [JsonProperty("lastSeen")]
    public DateTime LastSeen { get; set; }
}

Listen for typed presence events:

var presenceId = Guid.NewGuid().ToString();

var channel = supabase.Realtime.Channel("last-seen");
var presence = channel.Register<UserPresence>(presenceId);
presence.OnSync += (sender, args) =>
{
	foreach (var state in presence.CurrentState)
	{
                var userId = state.Key;
                var lastSeen = state.Value.First().LastSeen;
		Debug.WriteLine($"{userId}: {lastSeen}");
	}
};
await channel.Subscribe();

Track a user presence event:

var presenceId = Guid.NewGuid().ToString();
var channel = supabase.Realtime.Channel("last-seen");

var presence = channel.Register<UserPresence>(presenceId);
presence.Track(new UserPresence { LastSeen = DateTime.Now });

Postgres Changes

Using the new Register method:

var channel = supabase.Realtime.Channel("public-users");
channel.Register(new PostgresChangesOptions("public", "users"));
channel.PostgresChanges += (sender, args) =>
{
	switch (args.Response.Data.Type)
	{
		case EventType.Insert:
			// Handle user created
			break;
		case EventType.Update:
			// Handle user updated
			break;
		case EventType.Delete:
			// Handle user deleted
			break;
	}
};
await channel.Subscribe();

Using the previous shorthand (backwards compat):

var channel = supabase.Realtime.Channel("realtime", "public", "users");
channel.PostgresChanges+= (sender, args) =>
{
	switch (args.Response.Data.Type)
	{
		case EventType.Insert:
			// Handle user created
			break;
		case EventType.Update:
			// Handle user updated
			break;
		case EventType.Delete:
			// Handle user deleted
			break;
	}
};
await channel.Subscribe();

@acupofjose acupofjose marked this pull request as draft January 21, 2023 05:31
@acupofjose acupofjose added the enhancement New feature or request label Jan 26, 2023
@acupofjose acupofjose linked an issue Jan 26, 2023 that may be closed by this pull request
@acupofjose acupofjose marked this pull request as ready for review January 30, 2023 22:36
@acupofjose acupofjose merged commit 42caaaf into master Jan 30, 2023
@acupofjose acupofjose deleted the dev/presence-broadcast-api branch January 30, 2023 22:36
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Include Presence API from JS client.
1 participant