Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Phoenix channels: send push to a particular client

Hi I am trying to reimplement whatsapp functionality using elixir phoenix. I am having a problem figuring out the following: if all people in the chat room has received the message, I want to send the owner of the message status "received" so that he can show double tick sign. However how do you broadcast to one particular client?

like image 264
almeynman Avatar asked Jun 07 '16 13:06

almeynman


1 Answers

You can solve this via topic per user, this can be easily implemented by pattern matching, notice the security validation also:

def join("users:" <> user_id, _params, socket) do
    {user_id, _} = Integer.parse(user_id)

    %{id: id} = socket.assigns[:user]

    #prevent connection to solo channel of other users, but allow in development
    case id == user_id || Mix.env == :dev do
      true ->
        {:ok, socket}
      false ->
        {:error, "This is not your solo channel!"}
      end
  end

As you would have stored the user from Repo.get when the user connect to the socket at:

defmodule MyApp.UserSocket do
  use Phoenix.Socket

  def connect(%{"token" => token}, socket) do
    case Phoenix.Token.verify(socket, "user", token, max_age: 1209600) do
      {:ok, user_id} ->
        socket = assign(socket, :user, Repo.get!(User, user_id))
        {:ok, socket}
      {:error, _} -> #...
    end
  end
end

And finally, you can send messages to a specific user out of socket context as:

YourAll.Endpoint.broadcast user_topic, "message", %{details: "etc"}

To test the performance, this is a very informative session in which Gary Rennie shows how to benchmark WebSockets using Tsung tool.

like image 134
simo Avatar answered Sep 25 '22 22:09

simo