I am currently busy with my first real app using elixir/phoenix and react (backend communication using sockets/channels only except for one REST endpoint for error messages). So far it has been a enjoyable ride.
It is a kind of a multiplayer interaction environment where users log in with a PIN and pick a nickname. Using a given PIN, a nickname must be unique/not chosen yet in order be able to connect. And through the PIN, the application does know which content to display. And basically all connected nicknames for a given PIN form a group of users interacting (interaction happens through one or more channels).
In order to achieve the “only one socket connection for a given PIN and nickname”, I have implemented a presence check within the socket connect and tracking of the socket process through
Presence.track/4 using the socket pid as pid, the module name (of the socket) as topic and the nickname as key.
Presence.connect/2 code basically does a
Presence.list/1 and checks if the user provided nickname is present within the presence list, returning
:error to not allow the connection in case the nickname is present.
This works so far for one PIN. But in the future I would have to allow more than one PIN to be used (within the same application deployment). I also would like to inform some separate gen_server that some presence changes happened.
I guess I could use the PIN as a topic or combine the PIN and the nickname together to form the key for tracking and validation but it seems that it does not solve the presence change tracking. Then there is the subscribe functionality in pubsub which might help (subscribing on “phx_presence:Elixir.MyApp.Presence” or something like that)?
Or should I explore custom trackers and save the presence data into an agent/gen_server of some kind (no idea yet how to do that though) maybe?
Any thoughts would be very much appreciated