Reputation: 2019
def join("world:lobby", _message, socket) do
PubSub.subscribe(Rotb.PubSub, "zone_1")
{:ok, socket}
end
def handle_info(%{message: message}, socket) do
broadcast(socket, "shout", %{"socket_id" => socket.id, "message" => message})
{:noreply, socket}
end
def handle_in("shout", payload, socket) do
PubSub.broadcast(Rotb.PubSub, "zone_1", %{
message: payload["message"]
})
{:noreply, socket}
end
However the shout event happens multiple times on my client? It looks like it might appear an additional time for each other connection but not 100%.
Upvotes: 0
Views: 288
Reputation: 2235
Please check to see if you are calling subscribe
function in your mount
function in the LiveView.
The mount
function is called twice, and duplicate subscriptions will result in duplicate events being sent to handle_info
.
Upvotes: 0
Reputation: 1771
If I understand correctly what you are doing, you want all connected clients to the phoenix channel to get the shout.
The PubSub subscription there makes sense.
The broadcast in handle info does not make sense because its for the current client. You should just be doing a push there. See your code below with screenshot of a React Native console with two clients connected.
defmodule MyAppWeb.TestChannel do
use Phoenix.Channel
alias Phoenix.PubSub
def join("world:lobby", _message, socket) do
PubSub.subscribe(MyApp.PubSub, "zone_1")
{:ok, socket}
end
def handle_info(%{message: message}, socket) do
IO.inspect({"NEW MESSAGE", message})
push(socket, "shout", %{"socket_id" => socket.id, "message" => message})
{:noreply, socket}
end
def handle_in("shout", payload, socket) do
IO.inspect({"SHOUT", payload})
PubSub.broadcast(MyApp.PubSub, "zone_1", %{
message: payload["message"]
})
{:noreply, socket}
end
end
The shout is sent from the android client. If you have two clients connected then you should see two different pids for each socket.
Now if you are just trying to broadcast the message to all connected clients, you should just use the broadcast/3 inside handle_in and don't use PubSub. PubSub is for pushing messages from outside the socket. Like some cron job that finds if some other external state has changed then pushes that to the clients. For broadcasting messages from one client to others then broadcast/3 inside handle_in is enough
Using broadcast inside handle_info with pubsub means all clients get the pubsub then they all broadcast. No what you want.
Upvotes: 1