2016-09-28 59 views
0

我正在使用Phoenix elixir構建web應用程序,其中我的web應用程序需要加載索引頁,而不是在後臺等待接收消息。這是我的代碼,我有問題Elixir Phoenix遞歸函數停止頁面加載

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函數內,因爲當我打電話內指數wait_for_messages它是遞歸函數,它從來沒有達到render conn, "index.html"線。有什麼辦法可以使它工作,這樣可以加載頁面inde.html,並且wait_for_messages在後臺運行?

+0

最簡單的方法是使用'spawn'或'spawn_link'(http://elixir-lang.org/docs/stable/elixir/Kernel.html#spawn/1),但我不會發布這個作爲正確方法的答案通常是在某處使用Supervisor來處理錯誤,對於簡單情況可能使用Task.Supervisor。 – Dogbert

+0

但是,如果我使用spawn或spawn_link也停止我的頁面內容加載,只是在後臺運行功能 –

回答

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 
+0

現在我沒有任何錯誤,但函數wait_for_messages不工作,因爲它應該。它需要等待消息並在接收時打印,但不起作用。 –

+0

@MišelAdemi如果您需要Logger並使用Logger.info(「[x] Received#{payload}」)而不是IO.puts「[x]接收#{有效載荷} –

0

也許鳳凰渠道將是這更好的配合。將客戶端發送給index.html,然後從客戶端應用程序中加入一條從AMQP總線發送消息(將廣播給所有連接的客戶端)的通道。這將爲您的應用程序提供更實用的免費功能。 Docs在這裏:http://www.phoenixframework.org/docs/channels

至於IO.puts ...我不清楚控制檯輸出的目的......更多的Elixir-y方法可以做到這一點, AMQP消息傳遞以及另一個流程,您可以從一個使用消息的iex控制檯開始/交互,並提供一個停止(例如終止)AMQP處理器的API。

..但就目前而言,依賴於控制檯輸出限制您一次只能進行一次這樣的交互......而Web服務本質上並非如此。