2016-05-23 8 views
0

Phoenix.Channel.reply/2の例をPhoenixのドキュメントから非同期的に返信する完全な動作例に拡張しようとしています。フェニックスチャンネル/ソケットプッシュイベント:チャネルの非同期応答にPhoenix.Channel.reply/2を使用する方法

https://hexdocs.pm/phoenix/Phoenix.Channel.html#reply/2から撮影:

def handle_in("work", payload, socket) do 
    Worker.perform(payload, socket_ref(socket)) 
    {:noreply, socket} 
end 

def handle_info({:work_complete, result, ref}, socket) do 
    reply ref, {:ok, result} 
    {:noreply, socket} 
end 

次のように私は例を作り直しました:

room_channels.ex

... 
def handle_in("work", job, socket) do 
    send worker_pid, {self, job} 
    {:noreply, socket} 
end 

def handle_info({:work_complete, result}, socket) do 
    broadcast socket, "work_complete", %{result: result} 
    {:noreply, socket} 
end 
... 

worker.ex

... 
receive do 
    {pid, job} -> 
    result = perform(job) # stub 
    send pid, {:work_complete, result} 
end 
... 

このソリューションは動作しますが、それは/ Phoenix.Channel.reply socket_ref(socket)でsocket_refを生成し、合格にしてに依存しません2。代わりに、Phoenix.Channel.broadcast/3に依存しています。

ドキュメントは応答/ 2は特に非同期ソケットプッシュイベントに返信するこのシナリオのために使用されることを意味する:

応答(ARG1、ARG2)非同期ソケットに

返信押す。

は、 handle_inコールバックから返された{:reply、{status、payload}、socket}戻り値を使用して返信する必要がある場合に便利です。他のプロセスで作業を実行し、完了したら がsocket_ref/1でプッシュへの参照を生成することによって返信/ 3が使用されることがまれである場合は、 が必要です。

私は生成しsocket_refを渡し、ソケットプッシュへの非同期応答のためPhoenix.Channel.reply/2に依存しているとき、私はそれがすべてで仕事を得ることはありません:

room_channels。元

... 
def handle_in("work", job, socket) do 
    send worker_pid, {self, job, socket_ref(socket)} 
    {:noreply, socket} 
end 

def handle_info({:work_complete, result, ref}, socket) do 
    reply ref, {:ok, result} 
    {:noreply, socket} 
end 
... 

worker.ex

... 
receive do 
    {pid, job, ref} -> 
    result = perform(job) # stub 
    send pid, {:work_complete, result, ref} 
end 
... 

マイroom_channels.ex handle_info関数が呼び出されましたが、reply/2はソケットの下にメッセージを送信していないようです。 stderrにstacktraceもstdoutにもエラーがあることを示す出力がありません。さらに、socket_refを追跡することは、自分のコードにオーバーヘッドを追加するように思えます。

放送/ 3と私は返事の溶液を得ることができる方法/ 2が動作するようにと私の溶液上socket_refと返信/ 2を使用する利点は何ですか?

答えて

0

私はPhoenix.Channel.reply/2との例は動作しますが、間違っていた:私の実装では

room_channels.ex

... 
def handle_in("work", job, socket) do 
    send worker_pid, {self, job, socket_ref(socket)} 
    {:noreply, socket} 
end 

def handle_info({:work_complete, result, ref}, socket) do 
    reply ref, {:ok, result} 
    {:noreply, socket} 
end 
... 

worker.ex

... 
receive do 
    {pid, job, ref} -> 
    result = perform(job) # stub 
    send pid, {:work_complete, result, ref} 
end 
... 

を私は、{:noreply, socket}の代わりに{:reply, :ok, socket}の戻り値でイベントプッシュへの同期返信を送信したのは間違いです。

WebSocketフレームをサーバーからクライアントに送信すると、ブラウザはサーバー応答をreply ref, {:ok, result}から受信しましたが、関連付けられたコールバックは呼び出されませんでした。

PhoenixのSocket.jsクライアントライブラリは、プッシュイベントごとに最大で1つの応答を受け付けているようです。

0

希望私はこの会話に遅すぎるわけではありません。

私は上記のコードを使用して管理し、JavaScriptを使用してコールバックを取得しました。

トリックはphx_replyイベントを聞くことです。 priv/static/app.js内の各Channel javascriptオブジェクトは、CHANNEL_EVENTS(ラインで事前に定義し、次のコードブロックでそれをリッスンするように設定されているのリストを持っている:私は何

this.on(CHANNEL_EVENTS.reply, function (payload, ref) { 
    _this2.trigger(_this2.replyEventName(ref), payload); 
}); 

は私がphx_replyのために聞く、チャンネル内onコールバックでしたイベント:

channel.on("phx_reply", (data) => { 
    console.log("DATA ", data); 
    // Process the data 
} 

これはエリクサー1.3とフェニックスでテストされている1.2

希望に役立ちます

0を!
関連する問題