1

我在演示 phoenix 应用程序中遇到了问题。该应用程序由一个 api 组成,它侦听消息 json 并在 ecto 数据库中创建一个适当的条目。

defmodule ServerLive.Messages.Message do
  use Ecto.Schema

  schema "messages" do
    field :content, :string
    field :sender_id, :integer
    field :timestamp, :utc_datetime

    timestamps()
  end
end

还有一个实时视图显示消息表中的条目。我的目标是在实时视图上实现更新,并在成功创建消息时将创建的消息添加到套接字中。为此,我尝试使用该模块并在安装实时视图时PubSub引入了对该主题的订阅。"messaging"

defmodule ServerLiveWeb.Demo do
  use ServerLiveWeb, :live_view

  alias ServerLive.Messages

  @topic "messaging"

  def mount(_params, _session, socket) do
    # mount all messages in reverse order
    socket = assign(socket, :messages, Enum.reverse(Messages.list_messages()))
    # subscribe to messaging
    ServerLiveWeb.Endpoint.subscribe(@topic)
    {:ok, socket}
  end

  ...

  def handle_event("insert", message, socket) do
    socket = update(socket, :messages, fn m -> message <> m end)
    {:noreply, socket}
  end
end

正在从消息 api 控制器执行广播

defmodule ServerLiveWeb.MessageController do
  use ServerLiveWeb, :controller

  alias ServerLive.Messages

  @topic "messaging"

  def create(conn, %{"message" => message_params}) do
    with {:ok, %Message{} = message} <- Messages.create_message(message_params) do
      # broadcast message
      ServerLiveWeb.Endpoint.broadcast(@topic, "insert", message)
      |> put_status(:created)
      |> put_resp_header("location", Routes.message_path(conn, :show, message))
    end
  end

  ...

现在的问题是,每次 api 请求创建消息并执行广播时,mount都会调用函数而不是插入事件句柄。可能是什么问题呢?

我已经使用调试器进行了调查,第二个挂载调用的调用堆栈是:

  • ServerLiveWeb.Demo.mount/3
  • Phoenix.LiveView.Utils.maybe_call_mount!/3
  • Phoenix.LiveView.Channel.verified_mount/5
  • Phoenix.LiveView.Channel.handle_info/2
4

0 回答 0