2016-09-28 9 views
0

私は、Webアプリケーションがインデックスページを読み込む必要があり、メッセージを受け取るためにバックグラウンドで待機する必要があるPhoenixエリクシールを使用して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を呼び出すとき、それは再帰関数であり、それはrender conn, "index.html"ラインに到達することはありませんので、私の問題は、私のwait_for_messages関数内であることを知っているを持っている私のコードです。それは、ページinde.htmlがロードされ、wait_for_messagesがバックグラウンドで実行されるように、動作させる方法はありますか?

+0

最も簡単な方法は、 'spawn'または' spawn_link'(http://elixir-lang.org/docs/stable/elixir/Kernel.html#spawn/1)を使うことですが、私はこれを投稿していません正しい方法としての答えは、通常、単純な場合には「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'を必要とし、' IO.puts "の代わりに' Logger.info( "[x] Received#{payload}") 'を使うとどうなりますか[x] Received#{payload}" ' –

0

おそらくフェニックスチャンネルは、このためのより良いフィット感だろう。クライアントにindex.htmlを送信し、そのクライアント側のアプリケーションからAMQPバスからメッセージを送信するチャネルに参加させる(接続されたすべてのクライアントにブロードキャストする)。これは、あなたのアプリケーションに、実際に無料でより多くの分散方法でその機能を与えるでしょう。ドキュメントはここにあります:http://www.phoenixframework.org/docs/channels

私はコンソール出力をする目的ではっきりしていません...これを行うには、エリクサー - yの方法は、 AMQPメッセージングと別のプロセスでは、そこからメッセージを消費するiexコンソールから開始/対話することができ、AMQPプロセッサを停止(たとえば強制終了)するためのAPIを提供します。

..しかし、そのコンソール出力に依存すると、一度に1つのそのようなやりとりに制限されます...そして、Webサービスは本質的にそのようなものではありません。

関連する問題