mirror of
https://github.com/fly-apps/live_beats.git
synced 2024-11-28 02:31:01 +00:00
add presence client
This commit is contained in:
parent
216916817b
commit
bd927bf8b2
4 changed files with 117 additions and 5 deletions
|
@ -20,9 +20,10 @@ defmodule LiveBeats.Application do
|
||||||
#start presence
|
#start presence
|
||||||
LiveBeatsWeb.Presence,
|
LiveBeatsWeb.Presence,
|
||||||
# Start the Endpoint (http/https)
|
# Start the Endpoint (http/https)
|
||||||
LiveBeatsWeb.Endpoint
|
LiveBeatsWeb.Endpoint,
|
||||||
# Start a worker by calling: LiveBeats.Worker.start_link(arg)
|
# Start a worker by calling: LiveBeats.Worker.start_link(arg)
|
||||||
# {LiveBeats.Worker, arg}
|
# {LiveBeats.Worker, arg}
|
||||||
|
{Phoenix.Presence.Client, client: LiveBeats.PresenceClient, pubsub: LiveBeats.PubSub, presence: LiveBeats.Presence}
|
||||||
]
|
]
|
||||||
|
|
||||||
# See https://hexdocs.pm/elixir/Supervisor.html
|
# See https://hexdocs.pm/elixir/Supervisor.html
|
||||||
|
|
85
lib/live_beats/presence/phoenix_presence_client.ex
Normal file
85
lib/live_beats/presence/phoenix_presence_client.ex
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
defmodule Phoenix.Presence.Client do
|
||||||
|
use GenServer
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
TODO
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
* `:pubsub` - The required name of the pubsub server
|
||||||
|
* `:presence` - The required name of the presence module
|
||||||
|
* `:client` - The required callback module
|
||||||
|
"""
|
||||||
|
def start_link(opts) do
|
||||||
|
GenServer.start_link(__MODULE__, opts, name: PresenceClient)
|
||||||
|
end
|
||||||
|
|
||||||
|
def track(topic, key, meta) do
|
||||||
|
GenServer.call(PresenceClient, {:track, self(), topic, key, meta})
|
||||||
|
end
|
||||||
|
|
||||||
|
def untrack(topic, key) do
|
||||||
|
GenServer.call(PresenceClient, {:untrack, self(), topic, key})
|
||||||
|
end
|
||||||
|
|
||||||
|
def init(opts) do
|
||||||
|
client = Keyword.fetch!(opts, :client)
|
||||||
|
client_state = client.init(%{})
|
||||||
|
|
||||||
|
state = %{
|
||||||
|
topics: %{},
|
||||||
|
client: client,
|
||||||
|
pubsub: Keyword.fetch!(opts, :pubsub),
|
||||||
|
presence_mod: Keyword.fetch!(opts, :presence),
|
||||||
|
client_state: client_state
|
||||||
|
}
|
||||||
|
|
||||||
|
{:ok, state}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_info(%{topic: topic, event: "presence_diff", payload: diff}, state) do
|
||||||
|
{:noreply, merge_diff(state, topic, diff)}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_call({:track, pid, topic, key, meta}, _from, state) do
|
||||||
|
{:reply, :ok, track_pid(state, pid, topic, key, meta)}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_call({:untrack, pid, topic, key}, _from, state) do
|
||||||
|
{:reply, :ok, untrack_pid(state, pid, topic, key)}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp track_pid(state, pid, topic, key, meta) do
|
||||||
|
case Map.fetch(state.topics, topic) do
|
||||||
|
{:ok, presences} ->
|
||||||
|
state.presence_mod.track(pid, topic, key, meta)
|
||||||
|
# update topics state...
|
||||||
|
# new_state
|
||||||
|
state
|
||||||
|
|
||||||
|
:error ->
|
||||||
|
# subscribe to topic we weren't yet tracking
|
||||||
|
Phoenix.PubSub.subscribe(state.pubsub, topic)
|
||||||
|
# new_state
|
||||||
|
state
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp untrack_pid(state, pid, topic, key) do
|
||||||
|
state.presence_mod.untrack(pid, topic, key)
|
||||||
|
# remove presence from state.topics
|
||||||
|
# if no more presences for given topic, unsubscribe
|
||||||
|
# Phoenix.PubSub.unsubscribe(state.pubsub, topic)
|
||||||
|
# new_state
|
||||||
|
state
|
||||||
|
end
|
||||||
|
|
||||||
|
defp merge_diff(state, topic, diff) do
|
||||||
|
# merge diff into state.topics
|
||||||
|
# invoke state.client.handle_join|handle_leave
|
||||||
|
# if no more presences for given topic, unsubscribe
|
||||||
|
# Phoenix.PubSub.unsubscribe(state.pubsub, topic)
|
||||||
|
# new_state
|
||||||
|
state
|
||||||
|
end
|
||||||
|
end
|
28
lib/live_beats/presence/presence_client.ex
Normal file
28
lib/live_beats/presence/presence_client.ex
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
defmodule LiveBeats.PresenceClient do
|
||||||
|
@behaviour Phoenix.Presence.Client
|
||||||
|
|
||||||
|
@presence LiveBeats.Presence
|
||||||
|
|
||||||
|
def start_link(opts) do
|
||||||
|
Phoenix.Presence.Client.start_link(presence: @presence, client: __MODULE__)
|
||||||
|
end
|
||||||
|
|
||||||
|
def list(topic) do
|
||||||
|
@presence.list(topic)
|
||||||
|
end
|
||||||
|
|
||||||
|
def init(_opts) do
|
||||||
|
# user-land state
|
||||||
|
{:ok, %{}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_join(key, presence, state) do
|
||||||
|
# can local pubsub to LVs about new join
|
||||||
|
{:ok, state}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_leave(key, presence, state) do
|
||||||
|
# can local pubsub to LVs about new leave
|
||||||
|
{:ok, state}
|
||||||
|
end
|
||||||
|
end
|
|
@ -87,11 +87,9 @@ defmodule LiveBeatsWeb.ProfileLive do
|
||||||
if connected?(socket) do
|
if connected?(socket) do
|
||||||
MediaLibrary.subscribe_to_profile(profile)
|
MediaLibrary.subscribe_to_profile(profile)
|
||||||
Accounts.subscribe(current_user.id)
|
Accounts.subscribe(current_user.id)
|
||||||
LiveBeatsWeb.Presence.track(
|
Phoenix.Presence.Client.track(topic(profile.user_id),
|
||||||
self(),
|
|
||||||
topic(profile.user_id),
|
|
||||||
current_user.id,
|
current_user.id,
|
||||||
current_user
|
%{}
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue