我正在使用Phoenix elixir构建Web应用程序,我的Web应用程序需要加载索引页面,而不是在后台等待接收消息。这是我有问题的代码
defmodule ApplicationB.PageController do
use ApplicationB.Web, :controller
use AMQP
def index(conn, _params) do
{:ok, connection} = AMQP.Connection.open
{:ok, channel} = AMQP.Channel.open(connection)
AMQP.Queue.declare(channel, "hello")
AMQP.Basic.consume(channel, "hello", nil, no_ack: true)
IO.puts " [*] Waiting for messages. To exit press CTRL+C, CTRL+C"
wait_for_messages
render conn, "index.html"
end
def wait_for_messages do
receive do
{:basic_deliver, payload, _meta} ->
IO.puts " [x] Received #{payload}"
ApplicationB.Endpoint.broadcast! "message", "hello", %{body: "poruka"}
wait_for_messages
end
end
end
我知道我的问题在我的wait_for_messages函数中,因为当我在index中调用wait_for_messages时它是递归函数,它永远不会到达render conn, "index.html"
行。有没有办法使它工作,以便可以加载页面inde.html并在后台运行wait_for_messages?
答案 0 :(得分:0)
您似乎在寻找Task模块。
为防止wait_for_messages / 0阻止您的操作,您可以使用Task.start_link/1
,如下所示:
def index(conn, _params) do
{:ok, connection} = AMQP.Connection.open
{:ok, channel} = AMQP.Channel.open(connection)
AMQP.Queue.declare(channel, "hello")
AMQP.Basic.consume(channel, "hello", nil, no_ack: true)
IO.puts " [*] Waiting for messages. To exit press CTRL+C, CTRL+C"
Task.start_link(fn -> wait_for_messages end)
render conn, "index.html"
end
答案 1 :(得分:0)
也许Phoenix Channels更适合这种情况。向客户端发送index.html,然后从该客户端应用程序中加入一个从AMQP总线发送消息的通道(将其广播到所有连接的客户端)。这将使您的应用程序以更加分散的方式实现免费的功能。文档在这里:http://www.phoenixframework.org/docs/channels
至于IO.puts ......我不清楚控制台输出的目的......更多的Elixir-y方法是让一个进程执行AMQP消息传递而另一个进程是你可以从消耗来自它的消息的iex控制台开始/交互,并提供一个API来停止(例如杀死)AMQP处理器。
..但是就目前而言,依靠控制台输出一次限制你进行一次这样的交互...而且Web服务本质上不是那种东西。