celsobonutti
Phoenix.js Channel Presence onJoin firing multiple times
I’m trying to use a Phoenix Channel for the signaling part of a WebRTC application, as I thought Presence would be perfect for this.
The thing is: I’m trying to track a user join using Phoenix.js’ Presence object, like this:
presence.onJoin(async (id, current, newPres) => {
if (!current) {
const peerConnection = await createPeerConnection(
channel,
sendMessage,
config.onTrack,
localStreamMedia
);
peerMap.set(id, peerConnection);
} else {
}
});
The thing is: every time a user joins, this callback is fired multiple times, even with its own Presence object and the objects of users that were previously in the channel. I don’t know if this is the expected behavior and couldn’t find a reference about that.
My Channel looks like this right now:
defmodule ElmWebRtcWeb.VideoChannel do
use Phoenix.Channel
alias ElmWebrtcWeb.Presence
def join("videoroom:" <> _channel, _message, socket) do
send(self(), :after_join)
{:ok, socket}
end
def handle_info(:after_join, socket) do
{:ok, _} =
Presence.track(socket, socket.assigns.user_id, %{
online_at: inspect(System.system_time(:millisecond))
})
push(socket, "presence_state", Presence.list(socket))
{:noreply, socket}
end
end
and the JS Presence is created like this:
const channel = socket.channel(`videoroom:${room}`, {});
channel.join();
const presence = new Presence(channel);
Does anyone have a clue about:
- Is this the expected behavior of Presence.js?
- If so, is there any way for me to achieve what I want with it?
- If not, what could be going wrong?
Thank you very much!
Marked As Solved
peoj
I found the exact same thing when working with onJoin() - it would fire more than expected.
My workaround has been to use onSync() instead and then calling presence.list(), which is always (in my experience) accurate.
For example:
presence.onSync(() => {
const myParticipants = presence.list();
// … and so on
});
Hope that helps!
Also Liked
celsobonutti
I haven’t been able to use this with const presence = Presence(channel), but this:
let presences = {};
const onJoin = async (id: string | undefined) => {
//onJoin implementation
};
const onLeave = async (id: string | undefined) => {
//onLeave implementation
};
channel.on('presence_diff', (diff) => {
presences = Presence.syncDiff(presences, diff, onJoin, onLeave);
});
did the job and is working perfectly.
I’m still wondering if the first implementation should work though ![]()
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









