如何在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
相关产品推荐
相关产品推荐

