Elixir 你如何从凤凰控制器内部与长生不老药代理沟通?

Elixir 你如何从凤凰控制器内部与长生不老药代理沟通?,elixir,phoenix-framework,Elixir,Phoenix Framework,当一门语言的创造者回答你的问题时,在它的生命中足够早地学习它是很棒的!好吧,我的问题是-如何从Phoenix controller方法中与代理通信?我在hello_blockchain/monitor.ex中看到了这个: defmodule HelloBlockchain.Monitor do def start_link do Agent.start_link(fn -> %{} end) end def put(pid, key, value) do Ag

当一门语言的创造者回答你的问题时,在它的生命中足够早地学习它是很棒的!好吧,我的问题是-如何从Phoenix controller方法中与代理通信?我在hello_blockchain/monitor.ex中看到了这个:

defmodule HelloBlockchain.Monitor do
  def start_link do
    Agent.start_link(fn -> %{} end)
  end

  def put(pid, key, value) do
    Agent.update(pid, &Map.put(&1, key, value))
  end

  def get(pid, key) do
    Agent.get(pid, &Map.get(&1, key))
  end
end
在我的hello_blockchain_web/controllers/block_controller.ex中,我希望在控制器操作(列表)中保存一个值,并在下次调用该值时在同一操作中检索该值。但我需要探员的pid来做这件事。看来我也需要保存它。或者我可以使用一个指定的代理。但我需要一种方法来保存这个名字。这似乎是第二十二条军规。我错过了什么

文档页面以一个您可以按原样使用的示例开始。基本上:在Elixir中,您希望使用命名的
GenServer
s通过
name
而不是
pid
来查找它们

这种方法有许多优点,例如,
name
在服务器重新启动时不会更改,而
pid
会更改

因此,您可以执行以下操作:

defmodule HelloBlockchain.Monitor do
使用代理
def启动链接do
#模块这里是HelloBlockchain监视器
Agent.start_链接(fn->%{}end,名称:_模块_;
结束
def put(键、值)do
Agent.update(_模块_,&Map.put(&1,键,值))
结束
def get(钥匙)do
Agent.get(_模块_和Map.get(&1,键))
结束
结束
你们都准备好了
Agent.get(helloblockshain.Monitor,:foo)
将在任何地方工作(假设
Agent
确实已启动并受监督。)


显然,您不需要保存名称,只需给出预定义的已知名称即可。Elixir中常用的方法是使用该代理嵌套在其中的模块名称。

感谢您的快速回复。我现在的问题是如何“启动并监督”监控器。My application.ex有
def start(_type,_args)do import Supervisor.Spec children=[Supervisor(HelloBlockchainWeb.Endpoint,[]),worker(HelloBlockchain.Monitor,[])]opts=[strategy::one_for_one,name:HelloBlockchain.Supervisor]end
但是当我尝试启动应用程序时,我得到了
**(Mix)无法启动应用程序hello\u区块链:HelloBlockchain.application.start(:normal,[])返回了一个错误的值:
此注释不可读。请发布另一个问题,因为这个问题与OP中的问题无关。很抱歉格式化-注释中的代码格式不正确。我需要将Supervisor.start\u链接(儿童、选项)添加到application.ex,函数start/2以启动应用程序。但是Agent.get(helloblockshain.Monitor,:foo)导致(FunctionClauseError)Agent.get/3.get中没有匹配的函数子句。我必须调用foo=Monitor.get(:foo)和Monitor.put(:foo,“bar”)。非常感谢,mudasobwa。