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

402 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
Ivan Yurov 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
0
Apoorv-2204 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}])