Phoenix Presence

Understand the details of Phoenix's Presence in the game.

What is Phoenix Presence?

From the earliest days of Phoenix channels, developers have tried to figure out how to tell who is currently subscribed to a Channel. Until recently, the answer was to create a custom solution that best fits an individual application’s circumstances. However, we now have Phoenix Presence to solve that problem in a general way for all of us.

Presence has one job to do: to keep track of the clients subscribed to a topic on a Channel. For us, this means keeping track of the players in each game. Presence does this amazingly. This might sound like a trivial task, but it’s deceptively difficult.

If we were to roll our own version of Presence, our first thought might be to maintain a list of the subscribers, add clients to the list when they join, and remove them when they leave. This might work for a system with a single node.

With a single data structure on multiple nodes, though, we would have to make sure that the data is available to all nodes in the cluster. However, nodes don’t stay up forever, and a crash could lose all the subscription data.

We could put the data in an external database to solve that data durability problem. However, then network hiccups could disrupt communication to the database, and the system would miss clients joining or leaving. This would make the data out of sync with the real state of the channel.

The scenarios only get more complex from there. Add in users subscribing to the same topic from multiple devices and flaky mobile connections, and a solid solution might seem evasive indeed.

That’s where CRDTs (conflict-free replicated data types) come to the rescue. They track the sequence of clients joining and leaving, across nodes and clients. They do it without relying on clock time, which varies from machine to machine. CRDTs allow Presence to reconstruct the sequence of events to accurately determine which clients are currently subscribed to a topic on a Channel.

Note: In the future, this job might even be expanded to keep track of other things that can join or leave a group, like nodes, services, and processes. Stay tuned!

Phoenix Presence’s power is compounded by how easy it is to set up and use. We need a new, mostly empty Presence module and need to make sure it’s started when IslandsInterface is.

After this, we need a single callback function in the Channel to make it work—though we add another just to help us see Presence in action.

The plan is that as a player joins before we return {:ok, socket}, the Channel sends itself a message with the player’s screen name. The first callback we write will match that message and have Presence start tracking that screen name.

Application setup

Let’s start with a clean slate by shutting the server down and reloading both players’ windows.

We need to begin with an empty Presence module in our application:

Get hands-on with 1200+ tech skills courses.