2017-05-08 4 views
1

他の人が特定の他の人にメッセージを送信するために使用できる1ユーザチャネルとしてサブトピックを使用しています。例えばPhoenix Presenceを使用してトピック/サブトピックの存在を追跡するにはどうすればよいですか?

: - 私は、ユーザー1だ、と私はユーザー2. にメッセージを送りたい - 私は、ペイロード{ to: 2, message: 'hi' }handle_inにメッセージを送るには、ここでApp.Endpoint.broadcast("user:2", "hi")

をして、私のuser_channel.exからの抜粋です:好奇心旺盛だ人のため

def handle_in("chat", incoming_payload, socket) do 
    from_uid = socket.assigns.uid 
    uid = incoming_payload["to"] 
    message = incoming_payload["message"] 
    topic = "user:#{uid}" 
    payload = %{uid: from_uid, message: message} 

    # Send to the topic based of the incoming_payload's 
    # 'to' param. 
    App.Endpoint.broadcast(topic, "chat", payload) 

    {:reply, :ok, socket} 
end 

:コードがオープンソース

https://github.com/NullVoxPopuli/mesh-relay-phoenix/tree/feature/presence-tracking

+0

質問は何ですか? –

答えて

1

エリキシル-LANGたるみチャンネルでいくつかの素晴らしい人々のおかげで、私は(働く)この解に到達することができました:

defmodule MeshRelay.UserChannel do 
    use Phoenix.Channel, :channel 
    alias MeshRelay.Presence 
    require Logger 

    defp uids_present(to_uid, from_uid) do 
    to_uid && from_uid 
    end 

    defp has_valid_payload(payload) do 
    uid = payload["to"] 
    message = payload["message"] 

    uid && message 
    end 

    # uid is the member's channel that 
    # he/she receives their messages on. 
    # no messages not intended to be received by 
    # this member should be sent on this channel/subtopic 
    # 
    # socket.assigns.uid is the uid from the connect 
    def join("user:" <> uid, _params, socket) do 
    has_uids = uids_present(uid, socket.assigns.uid) 

    if has_uids do 
     send(self(), :after_join) 
     # Logger.debug Presence.list(socket) 
     {:ok, socket} 
    else 
     # kick him out he is not allowed here 
     {:error, 
     %{reason: "in order to receive messages, you must join a channel using your own uid"}, 
     socket 
     } 
    end 
    end 

    def handle_in("chat", incoming_payload, socket) do 
    if has_valid_payload(incoming_payload) do 
     from_uid = socket.assigns.uid 
     uid = incoming_payload["to"] 
     message = incoming_payload["message"] 
     topic = "user:#{uid}" 
     payload = %{uid: from_uid, message: message} 

     if is_member_online?(uid) do 
     MeshRelay.Endpoint.broadcast(topic, "chat", payload) 
     # broadcast! socket, "chat", payload 
     {:reply, :ok, socket} 
     else 
     reply_with_error_message(socket, %{ 
      reason: "member not found", 
      to_uid: uid, 
      from_uid: from_uid 
     }) 
     end 
    else 
     reply_with_error_message(socket, %{ 
     reason: "please format your message: { \"to\": \"uidstring\", \"message\": \"encrypted message\" }" 
     }) 
    end 
    end 

    def reply_with_error_message(socket, error) do 
    {:reply, {:error, error}, socket } 
    end 

    def handle_info(:after_join, socket) do 
    Presence.track(socket.channel_pid, "connected_members", socket.assigns.uid, %{ 
     online_at: inspect(System.system_time(:milli_seconds)) 
    }) 

    {:noreply, socket} 
    end 

    def is_member_online?(uid) do 
    Presence.list("connected_members") 
    |> Map.keys 
    |> Enum.any?(fn key -> key == uid end) 
    end 


end 
関連する問題