Subscribe to Phoenix Channel on the backend (not channel.join())

390 Views Asked by At

Is it possible to subscribe the socket to some Phoenix channels on the backend and not from the client? Let's say I have some groups to which user belongs, and I want user to connect to them once WS connection is established. Sending ids of groups to the user and joining channels seems like an unnecessary roundtrip, especially that I'd like to handle messages in that groups in one callback, so I'd use onMessage on Socket and match by the mask. How would I do that?

2

There are 2 best solutions below

0
On

Maybe this can help. https://www.erlang.org/doc/man/gen_tcp.html

 {ok, Socket} = gen_tcp:connect(host/addr, port,[binary/list, {packet, 2}])
0
On

Not sure if this is a good solution, probably it uses some internal APIs which are not private though:

  defmodule Front.UserChannel do
  use Front.Web, :channel

  def join("user:" <> user_id, _payload, socket) do
    if Integer.to_string(socket.assigns[:user_id]) == user_id do
      send(self(), :after_join)
      {:ok, socket}
    else
      {:error, %{reason: "unauthorized"}}
    end
  end

  def handle_info(:after_join, socket) do
    Groups.associated_with(socket.assigns[:user_id])
    |> Enum.each(fn group_id ->
      %Phoenix.Socket{socket | topic: "group:#{group_id}", channel: Front.GroupChannel}
      |> Phoenix.Channel.Server.join(%{})
    end)
    {:noreply, socket}
  end
end