Search code examples
phoenix-frameworkphoenix-channels

Adding custom functions to channels


I wish to modify Chris McCord's chat example to add additional functionality. Basically, I want the JavaScript client to have access to a number of convenience functions, such as getUsersInRoom(room_id), is_online(user_id), etc., using JSON.

But I'm not sure how to do this. The docs on Channels say that:

Each Channel will implement one or more clauses of each of these four callback functions - join/3, terminate/2, handle_in/3, and handle_out/3.

Does that mean these are the only functions allowed? I think what I need is a socket API, but I've never worked with sockets before and will appreciate some help. Also, the example seems to work on direct function calls with strings passed as arguments, but I need my chatting system to use JSON. I'm not at all sure how I can accomplish this.


Solution

  • Your question is a two-parter, so I'll give you a two-part answer. Also, your question is a more general design one, rather than specific to Elixir or Phoenix, so I'll keep answers generally too.

    Also, the example seems to work on direct function calls with strings passed as arguments, but I need my chatting system to use JSON. I'm not at all sure how I can accomplish this.

    There is no such thing as passing JSON types over the wire. You marshal (stringify) JSON into a string, send that string, then unmarshal (parse) back into JSON on the other side. So, if you want to structure your messages as JSON, that is totally cool, just remember to marshal/unmarshal at each reception point.

    (paraphrased) Convenience functions

    The simplest way to do this is by making these functions actual message types, then using either handle_in or handle_out functions to pick out that type, gather and return data. For example, have one message be current_online_users that returns a list of handles. You can filter that list client-side to check for presence. Some websocket implementations also have presence hooks, but I'm unfamiliar with those in Phoenix.

    Another way you can do this is by building into your JSON message structure. At the top-level, you can return the current count of users in a room as seen by Phoenix.

    Hope this helps.