Why phoenix channel close after rejoin

channels
phoenix
websockets

#1

Hi. I connect to WS, then join to channel room:lobby send command ["1","1","room:lobby:1","phx_join",{}]. Question. Why when I join to channel again, send command ["1","1","room:lobby:1","phx_join",{}] i get "phx_close" phoenix closed channel, what the main idea? I know the way how to not close channel if I join to the channel again:

  def join("room:lobby:" <> room_id, _message, socket) do
    user_id = socket.assigns.user_id
    case user_id do
      ^room_id ->
        send(self(), :do_something)
        {:ok, socket}
      _ ->
        {:error, ErrorView.render("403.json")}
    end
  end

  def handle_info(:do_something, socket) do
    user_id = socket.assigns.user_id
    push socket, "init_state", %{response: "bla bla"}
    {:noreply, socket}
  end

In this case, I always get a response "bla bla" after the join. What the best practice?


#2

From the same socket? If so, probably because phoenix detects that you’ve already joined this channel once and closes your second join attempt so as to avoid duplication.


#3

I believe this source code refers to the issue that @sergey-chechaev is having : https://github.com/phoenixframework/phoenix/blob/v1.4/lib/phoenix/socket.ex#L697

You can turn on logger level debug to see if you’re getting the relevant error message.


#4

But why close channel? Instead not join and get a warning.


#5

Not joining a channel is the same as closing it, in my view. And there is a warning as @sb8244 has pointed out above.


#6

Internally, Phoenix represents 1 channel per topic on a socket. A socket process cannot have 2 channel processes with the same topic. You can see a bit of this being reflected in code like https://github.com/phoenixframework/phoenix/blob/master/lib/phoenix/socket.ex#L455

From a purely theoretical stance, it does make sense to me that 1 instance of a socket can only have unique channels, as having duplicate channels wouldn’t be very helpful to that socket (although could still have some edge use cases).


#7

I’d imagine that it’s expected that if the client connects again it might have “lost” the prev. connection (even just at the application level) and it’s safer to just use the new connection instead of trusting that the old one is still working.