我在演示 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