Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save SophieDeBenedetto/5724a79121b3531ecc38c19e960a58dc to your computer and use it in GitHub Desktop.
Save SophieDeBenedetto/5724a79121b3531ecc38c19e960a58dc to your computer and use it in GitHub Desktop.
phoenix channels + presence outline

Building Real-Time Features with Phoenix Channels and Presence

In this post we'll take a deep dive into Phoenix Channels by building a real-time collaborative text-editing feature. Then, we'll use the Phoenix Presence module to track user activity within that feature.

The App

We're building out a Phoenix app that allows users to collaborate on coding challenges. Users can visit "challenge rooms" and see a code challenge prompt along with an in-browser code editor. Users can collaborate on the code challenge by typing into the text editor.

Here's where our real-time feature comes in. All of the users in the challenge room should be able to see what a given user is typing as they are typing it. We'll leverage Phoenix Channels to support this functionality.

However, not only should they see what a user is typing, they should see an indication of who is typing it. This is where our need to track user state comes in. We'll use Phoenix Presence to build out this behavior.

What Are Phoenix Channels and How do They Work?

Briefly define Channels. Lay out how they work in the following two steps:

  1. Establish the Socket Connection
  2. Broadcast Messages

Building a Real-Time Feature with Phoenix Channels

Now that we know what Channels are and how they work, we're ready to leverage them to build our first real-time feature: collaborative text-editing.

When a user visit the page for a given code challenge at "/challenges/:id", they should see the code prompt and a shared text editor. When a user edits code in the shared text editor, those changes should be visible to everyone in the "challenge room".

  1. Delcare the WebSocket endpoint + route socket requests to our channel
  2. Connect a client to the socket
  • Sending connect request from the client
  • Handling connect request on the server
  1. User joins a channel: User visits "/challenges/:id"
  • Sending join request from the client
  • Handling join request on the server
  1. Broadcasting messages: User type into the shared text editor, everyone in the "room" sees what is being typed.
  • Sending a message from the client
  • Handling the message on the server
  • Subscribing clients handle receiving the broadcast message

Tracking Users in Real-Time with Phoenix Presence

Why Do We Need to Track User State in Real-Time?

What is Phoenix Presence and How Does it Work?

Setting Up Phoenix Presence

  1. Define a module that uses PhoenixPresence module
  2. Add that module to your app's supervisor tree

User Joins a Channel

When a user joins the "challenge room" by visitng '/challenges/:id', they should be presented with a list of users in the room. The people already in the room should see their list of present users updated to include the new user.

  1. Adding the user to the presence store
  2. Broadcasting the list of present users to subscribing clients
  3. Pushing list of pre-existing users to the newly joined client

Custom Event: User Typing

When a user types into the shared text editor, they and everyone else in the room should see an indication of who is typing.

User leaves a Channel

When a user leaves the "challenge room", the remaining users should see their list of present users updated to exclude the departed user.

Conclusion

@sidhanthp
Copy link

Looks like an excellent outline to me. Just a couple comments:

  1. Let's focus more on creating a real-time chat application and less on Phoenix Presence. I think most people won't know that Phoenix Presence is what they're looking for (so they won't click on the article) until they see it's the perfect solution to the problem.
  2. I think a front-end might be beneficial for the reader

Other than that, you can get started on the post. Looking forward to reading the draft!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment