2016-07-24 4 views
3

私のアプリで別のチャンネルにブロードキャストしようとしていますが、動作させることができません。また、私はテストを書くことを試みているが、私はどのようにわからない。別のチャンネルにブロードキャストするPhoenix 1.1.6

私が収集できるものから、私はnotification_channelからのメッセージのブロードキャストに成功しましたが、chat_channelで受信されませんでした。

通知はチャットに送信する必要があります。

test "do we send a new:recommendation to chat ?", %{guardian_token: guardian_token} do 
     nils_base_64 = Base.encode64("user:nils") 

     {:ok, socket} = connect(UserSocket, %{}) 
     {:ok, _, socket1} = subscribe_and_join(socket, "notifications:"<>nils_base_64, %{"guardian_token" => guardian_token}) 
     {:ok, _, socket} = subscribe_and_join(socket1, "chat:Y2hhdDpjaGF0Mw==", %{"guardian_token" => guardian_token}) 

     payload = %{ 
      "message" => "look at this cool thing!", 
      "url" => "link to stuff", 
      "title" => "AWESOME EVENT", 
      "groups" => ["Y2hhdDpjaGF0Mw==", "Y2hhdDpwdWJsaWM="] 
     } 

     reply = %{message: "look at this cool thing!", title: "AWESOME EVENT", url: "link to stuff", user_grapqhl_id: nils_base_64, user_name: "Nils Eriksson"} 

     ref = push socket1, "new:group:recommendation", payload 
     assert_reply ref, :ok 
     assert_broadcast "new:recommendation", ^reply 
    end 

この検定p試験

def handle_in("new:recommendation", msg, socket) do 
     IO.puts "i am a recommendation !" 
     IO.inspect msg 
     chat_msg = %{ 
     "creator_id" => msg["user_grapqhl_id"], 
     "text" => msg["message"], 
     "creator_name" => msg["user_name"] 
     } 

    broadcast! socket, "new:msg", create_chat_msg(chat_msg,socket) 
    {:reply, :ok, socket} 
    end 

chat_channel.ex

def handle_in("new:group:recommendation", msg, socket) do 
    payload = %{ 
     message: msg["message"], 
     url: msg["url"], 
     title: msg["title"], 
     user_name: get_name_of_user(socket.assigns.user_grapqhl_id), 
     user_grapqhl_id: socket.assigns.user_grapqhl_id 
    } 

    IO.puts "incomming" 
    IO.inspect msg 
    Enum.map(msg["groups"], fn(x) -> 
     App.Endpoint.broadcast_from! self(), "chat:"<>x, 
      "new:recommendation", payload 
     end) 
    {:reply, :ok, socket} 

    end 

notification_channel.ex私はそれをreply を変更するか、または放送をコメントアウトすることによって失敗することができます。 handle_infail:pleaseに変更してchat_channelに変更すると、失敗することはありません。 これは、私がこの変更を送信する場合に文句を言うものです ref = push socket1, "new:group:recommendation", payloadref = push socket, "new:group:recommendation", payloadその場合にはお勧めしません。

これは配線上にあるものです。

 Process mailbox: 
    %Phoenix.Socket.Message{event: "init:msgs", payload: %{messages: []}, ref: nil, topic: "chat:Y2hhdDpjaGF0Mw=="} 
    %Phoenix.Socket.Broadcast{event: "new:recommendation", payload: %{message: "look at this cool thing!", title: "AWESOME EVENTs", url: "link to stuff", user_grapqhl_id: "dXNlcjpuaWxz", user_name: "Nils Eriksson"}, topic: "chat:Y2hhdDpjaGF0Mw=="} 
    %Phoenix.Socket.Message{event: "new:recommendation", payload: %{message: "look at this cool thing!", title: "AWESOME EVENTs", url: "link to stuff", user_grapqhl_id: "dXNlcjpuaWxz", user_name: "Nils Eriksson"}, ref: nil, topic: "chat:Y2hhdDpjaGF0Mw=="} 

私が使用しているelmパッケージがまだソケットレベルでの認証をサポートしていないため、チャネル認証を使用しています。

alias Phoenix.Socket.Broadcast 
    ... 

def handle_info(%Broadcast{topic: _, event: ev, payload: payload}, socket) do 
    IO.puts ev 
    IO.inspect payload 
    # do something with ev and payload(push or broadcast) 
    {:noreply, socket} 
    end 

それとも、そのイベントを聞くことができますので、これは

答えて

4

あなたは。あなたがあなたのchat_channelhandle_info/2を使用する必要がありますあなたのEndpointからbroadcast_from/4を使用しているため、エンド

def join("chat:" <> chat_id, %{"guardian_token" => token}, socket) do 
    IO.puts chat_id 
    case sign_in(socket, token) do 
    {:ok, authed_socket, _guardian_params} -> 
     Process.flag(:trap_exit, true) 
     send(self, {:after_join}) 
     [_type, node_chat_id] = Node.from_global_id(chat_id) 
     {:ok, assign(authed_socket, :chat_id, node_chat_id)} 
    {:error, reason} -> 
     IO.puts "Can't join channel cuz: " <> reason 
     # handle error TODO 
    end 

chatで次のようになりますクライアントから:

chatChannel.on("new:recommendation", resp => { 
    // doSomething with response 
} 

編集:

のは、どのようにchannelPubSubシステムの仕事について少し説明しましょう。

あなたはpayload.Firstでイベントをブロードキャストまたはプッシュしたい場合には、それはPubSubシステムに送信し、その後PubSubシステムはchannelPubSubで自身を登録することを話題に、すべての加入者プロセス(channel)に送信しますシステム。

Endpoint.broadcast_from/4を使用してサーバーからイベントをブロードキャストすると、PubSubシステムはペイロード付きのイベントを受信し、そのイベントをチャネル登録されたトピックにブロードキャストします。

チャネルはhandle_outコールバックをトリガーし、クライアントにメッセージをプッシュします。 chat_channelでは、handle_in "new:recommendation"イベントは必要ありません。あなたのクライアントは、そのイベントを聴くだけで済みます。

chatChannel.on("new:recommendation", resp => { 
    // do something with response 
} 

そして、私はあなたのテストを書き直してみましょう:あなたは、あなたのチャンネルがassert_receiveでメッセージを受信して​​いることを確認することができ聴きたいトピックへsubscribeことで

setup do 
    nils_base_64 = Base.encode64("user:nils") 
    {:ok, socket} = connect(UserSocket, %{}) 
    {:ok, _, socket} = subscribe_and_join(socket, "notifications:"<>nils_base_64, %{"guardian_token" => guardian_token}) 
    {:ok, socket: socket} 
    end 


test "do we send a new:recommendation to chat ?", %{socket: socket} do 
     MyApp.Endpoint.subscribe("chat:Y2hhdDpjaGF0Mw==") 

     payload = %{ 
      "message" => "look at this cool thing!", 
      "url" => "link to stuff", 
      "title" => "AWESOME EVENT", 
      "groups" => ["Y2hhdDpjaGF0Mw==", "Y2hhdDpwdWJsaWM="] 
     } 



     reply = %Phoenix.Socket.Broadcast{message: "look at this cool thing!", 
       title: "AWESOME EVENT", 
       url: "link to stuff", 
       user_grapqhl_id: nils_base_64, 
       user_name: "Nils Eriksson"} 

     ref = push socket, "new:group:recommendation", payload 
     assert_reply ref, :ok 
     assert_receive ^reply 
    end 

。 これは別のチャネルにbroadcastをテストする方法です。

試してみてください。テストに合格します。

+0

私はチャネル認証を持っていることが重要ですか?私はこれを試しても何も変わっていない。 私は、それが価値あるものであれば、外部チャネルを購読することができました。 – Note89

+0

あなたのテストはすでに合格しています。問題は何ですか?私はあなたが別のチャンネルに放送することができないと思った? – TheAnh

+0

はい、それらは合格しますが、チャットチャンネルで受信されたかどうかはテストされません。 メッセージはブロードキャストされますが、取り上げられません。 – Note89

0

チャットチャンネルのトピックにApp.Endpoint.broadcast topic, event, payloadを使用してください。それは動作するはずです。

関連する問題