supabase-community / realtime-csharp

A C# client library for supabase/realtime.
https://supabase-community.github.io/realtime-csharp/api/Supabase.Realtime.Client.html
MIT License
70 stars 12 forks source link

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

Closed acupofjose closed 1 year ago

acupofjose commented 1 year ago

Todo:

Changes:

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();