Intercepting outbound events with LiveView

Hi all! I’m fairly new to LiveView and am working on a simple game to get started. I’m using Phoenix.Presence to track connected users, which was going great until I wanted to track subscriptions to multiple topics independently. I could use some help orienting myself in the right direction.

My game consists of a lobby from which players pair off to play a game together; when the game ends they’re sent back to the lobby. I want to track users in the lobby for the purpose of maintaining an up-to-date list of idle players; I also want to track players in each game “room” by subscribing them to a game:<id> channel, mostly so that if a user disconnects I can react accordingly. The snag I’m running into is that joins/leaves result in a presence_diff event that doesn’t seem to care which topic it originated from.

What I really want is to override outbound events and differentiate them, which with a channel would look something like this:

intercept ["presence_diff"]

def handle_out("presence_diff", message, socket) do
  # send different events depending on message contents
end

… but without introducing a channel, and I haven’t found a way to do that. Barring that, I’ve considered adding the topic to tracking metadata, and then parsing the topic out in the presence_diff payloads to determine the right behavior… but that feels complex and not really in the spirit of metadata.

Anyway, thanks for reading, and any input would be much appreciated!

1 Like

Have you thought about using a simple PubSub, whith a different topic for each game and the lobby? Then you could have a separeate LiveView for the lobby, and one for the game. The Lobby could subscribe to the lobby topic on mount, while the game LiveView could subscribte to the given game:<id> topic.

Then you could broadcast messages, and everything would be nicely separated.

Thanks for the response! Mounting separate LiveViews for the lobby and games would simplify some aspects (and maybe complicate others), but if I’m understanding right, I think I’d still have the same issue: the presence_diff events that ensue when a player joins or leaves a game wouldn’t differentiate between individual game rooms unless I do something like stick the game ID in the tracking metadata. In other words, if a player leaves game:x, players in game:y will get a presence_diff event. Ideally, I’d like to override tracking behavior so joins/leaves would send a presence_diff_game:<id> event instead, but I don’t know if that’s possible.

I also realized I was misleading in my original post by referring to a ’game:<id> channel" – I’m trying to avoid introducing Phoenix.Channel here, although it’s possible that’s the best way to get what I’m after.

Anyway, I appreciate your response, and I’ll play around with what you suggested!