0

在文档中有这个例子,但它只适用于断开连接https://hexdocs.pm/phoenix/Phoenix.Socket.html#module-examples

  use Phoenix.Socket

  channel "room:*", MyAppWeb.RoomChannel

  def connect(params, socket, _connect_info) do
    {:ok, assign(socket, :user_id, params["user_id"])}
  end

  def id(socket), do: "users_socket:#{socket.assigns.user_id}"
end

# Disconnect all user's socket connections and their multiplexed channels
MyAppWeb.Endpoint.broadcast("users_socket:" <> user.id, "disconnect", %{})

我试过了,它只适用于断开连接。

我读过一些地方,你可以为该用户创建一个特定的主题,但我可以使用一个实际的例子。我无法理解复杂性,可以使用一个实际的例子。

谢谢你。

我在想如果你能得到 ets 表中的底层套接字,你就可以push/4到那个套接字,但我不知道该怎么做。

4

1 回答 1

1

您需要实际订阅一个主题才能接收广播。

“断开连接”消息很特别,因为它不需要订阅。

Phoenix.Socket源代码中,存在以下三行:

  def __info__(%Broadcast{event: "disconnect"}, state) do
    {:stop, {:shutdown, :disconnected}, state}
  end

它们是接收到“断开连接”广播时套接字状态发生变化的原因。

“回退”功能如下所示:

  def __info__(_, state) do
    {:ok, state}
  end

这意味着对于任何和所有“其他”主题,套接字状态都不会改变。

您需要手动订阅“其他”主题。

它应该看起来像这样:

socket.endpoint.subscribe("some_topic:" <> socket.assigns.user_id)

然后你可以像这样广播消息:

MyAppWeb.Endpoint.broadcast("some_topic:" <> user.id, "some_event", %{foo: bar})

如果您使用 LiveView 执行此操作,那么最简单的入门方法是将其放入您的挂载函数中:

if connected?(socket) do
  socket.endpoint.subscribe("some_topic:" <> socket.assigns.user_id)
end

然后有一个handle_info这样的:

  @impl true
  def handle_info(%{event: "some_event"} = info, socket) do
    IO.inspect info, label: "INFO"
    {:noreply, socket}
  end
于 2021-04-15T03:51:36.403 回答