You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Phoenix控制器中与Elixir Agent进行通信?

在Phoenix控制器中与Agent通信的方法

嘿,很高兴你能在Phoenix早期就开始折腾,还能和创作者交流,这机会真的难得!关于控制器和Agent通信的问题,我给你梳理几个关键步骤,应该就能解决啦:

第一步:给你的Agent注册一个名字(推荐做法)

直接传PID太麻烦,而且Agent重启后PID会变更,最好给它注册一个固定名字,这样控制器里直接用名字调用就行。修改你的hello_blockchain/monitor.ex:

defmodule HelloBlockchain.Monitor do
  def start_link(_opts) do
    # 用模块名作为Agent的注册名,后续调用不用传PID
    Agent.start_link(fn -> %{} end, name: __MODULE__)
  end

  def put(key, value) do
    # 直接用注册名操作Agent
    Agent.update(__MODULE__, &Map.put(&1, key, value))
  end

  def get(key) do
    Agent.get(__MODULE__, &Map.get(&1, key))
  end
end

第二步:把Agent加到应用的监督树里

这样Phoenix启动时会自动启动Agent,而且如果Agent意外崩溃,监督树会自动重启它,保证服务稳定。打开lib/hello_blockchain/application.ex,在children列表里加上你的Monitor:

defmodule HelloBlockchain.Application do
  use Application

  @impl true
  def start(_type, _args) do
    children = [
      # 保留原来的Endpoint
      HelloBlockchainWeb.Endpoint,
      # 添加Monitor到监督树
      HelloBlockchain.Monitor
    ]

    opts = [strategy: :one_for_one, name: HelloBlockchain.Supervisor]
    Supervisor.start_link(children, opts)
  end

  # 其他代码...
end

第三步:在控制器里直接调用Monitor的方法

现在你可以在任意控制器里直接调用HelloBlockchain.Monitor的put/2和get/1方法了,比如写个简单的示例控制器:

defmodule HelloBlockchainWeb.KeyValueController do
  use HelloBlockchainWeb, :controller

  # 设置键值对的接口
  def set(conn, %{"key" => key, "value" => value}) do
    HelloBlockchain.Monitor.put(key, value)
    json(conn, %{status: "success", message: "Value set successfully"})
  end

  # 获取键值对的接口
  def get(conn, %{"key" => key}) do
    value = HelloBlockchain.Monitor.get(key)
    json(conn, %{key: key, value: value})
  end
end

额外说明:如果一定要用PID怎么办?

要是你有特殊需求必须用PID,那你得确保控制器能拿到正确的PID——比如可以把PID存在应用环境变量里,或者从监督树里获取。但这种方式不如注册名字可靠,因为Agent重启后PID会改变,所以还是推荐用注册名的方式。

内容的提问来源于stack exchange,提问作者rodmclaughlin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:57:51