Skip to content

Instantly share code, notes, and snippets.

@alvinncx
Last active February 4, 2021 12:30
Show Gist options
  • Save alvinncx/8ad308b1e68326f4735681492cff7460 to your computer and use it in GitHub Desktop.
Save alvinncx/8ad308b1e68326f4735681492cff7460 to your computer and use it in GitHub Desktop.
Getting Phoenix.PubSub & Phoenix.LiveView to work together
# Configures the endpoint
config :example, Example.Endpoint,
...
pubsub: [name: Example.PubSub, adapter: Phoenix.PubSub.PG2],
...
# The general idea is to somehow get all the clients to subscribe to the same
# PubSub server topic and then broadcast a change to all clients when there is a system-wide change.
# I'm starting to think of Phoenix.LiveView are like GenServers where you need to define a handle_info/2
# to listen and respond to changes.
#
# The pre-requisite is to first set up PubSub and LiveView
# 1. Set up PubSub in config.exs if you haven't.
# 2. Set up LiveView. You can follow this guide here: https://github.com/phoenixframework/phoenix_live_view
# 3. In your mount/2, make sure to subscribe to the channel you want it to listen to.
# 4. Set up a handle_info/2 to pattern match the broadcast info, and also what to do with the message.
# 5. In your event handler, set up a broadcast with the action. An effect like this is probably better handled within
# contexts than on the same file here. But for sake of example will put it here.
# 6. Now when handle_info/2 receives the message, it will update the clients that it is currently connected to.
defmodule ExampleWeb.PageLive do
use Phoenix.LiveView
def render(assigns) do
ExampleWeb.PageView.render("index.html", assigns)
end
def mount(_session, socket) do
Phoenix.PubSub.subscribe(Meeter.PubSub, "change")
{:ok, assign(socket, content: "Update Me!")}
end
def fetch(socket) do
assign(socket, content: "Updated!")
end
def handle_event("check", _value, socket) do
Phoenix.PubSub.broadcast(Meeter.PubSub, "change", {:change})
{:noreply, fetch(socket)}
end
def handle_info({:change} = info, socket) do
{:noreply, fetch(socket)}
end
end
<h2><%= @content %></h2>
<div>
<button phx-click="check">Update Everyone!</button>
</div>
@shaheenery
Copy link

Hi Alvin,

I've read articles suggesting the following for line 23:
if connected?(socket), do: Phoenix.PubSub.subscribe(Meeter.PubSub, "change")

@alvinncx
Copy link
Author

alvinncx commented Feb 4, 2021

@shaheenery I think that makes sense. You want to know whether the client is connected? first before mounting.

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