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
但是喊叫事件在我的客户端上发生了多次?看起来彼此连接可能会出现额外的时间,但不是 100%。
如果我正确理解你在做什么,你希望所有连接到凤凰频道的客户端都能听到声音。
那里的 PubSub 订阅很有意义。
句柄信息中的广播没有意义,因为它是针对当前客户端的。你应该只是在那里推动。请参阅下面的代码以及连接了两个客户端的 React Native 控制台的屏幕截图。广播已处理
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
喊声是从 Android 客户端发出的。如果您连接了两个客户端,那么您应该会看到每个套接字有两个不同的 pid。
现在,如果您只是尝试将消息广播到所有连接的客户端,则应该只使用 handle_in 中的 broadcast/3,而不是使用 PubSub。 PubSub 用于从套接字外部推送消息。就像某些 cron 作业一样,它会发现其他外部状态是否已更改,然后将其推送到套接字。对于从一个客户端向其他客户端广播消息,那么 handle_in 内的 broadcast/3 就足够了
在handle_info中使用广播和pubsub意味着所有客户端都获得pubsub然后它们都广播。没有你想要的。