2

I've used Phoenix Channels for distribution of colors in my project and I keep getting such error:

[debug] Duplicate channel join for topic "colors:*" in EveryColor.ColorSocket. Closing existing channel for new join

How to replicate:

  1. make install && make build
  2. mix phoenix.server
  3. Load webpage once and everything works
  4. Reload and new color button stops working and above message appears in console..

Code:

Backend

defmodule EveryColor.DistributionChannel do
  use Phoenix.Channel

  alias EveryColor.Distributor

  def join("colors:"<>_ , _message, socket) do
    #send(self, :after_join)
    {:ok, %{color: Distributor.random_color, counter: Distributor.get_counter+1} ,socket}
  end

  def handle_info(:after_join, socket) do
    broadcast_counter socket
    push socket, "color_generated", %{color: Distributor.random_color}
    {:noreply, socket}
  end

  def handle_in("get", _payload, socket) do
    broadcast_counter socket
    {:reply, {:ok, %{color: Distributor.random_color}}, socket}
  end

  def broadcast_counter(socket) do
    broadcast socket, "counter_bump", %{counter: Distributor.get_counter+1}
  end

end

Front:

import { Socket } from 'phoenix-socket';
import { store } from './App.jsx';

let channel;

export default function connectToSocket(channelName) {

  const logs = process.env.NODE_ENV === 'development'
        ? { logger: ((kind, msg, data) => { console.log(`kind: ${kind}: msg: ${msg}`, data); })}
        : { };

  const socket = new Socket(`ws:localhost:4000/socket`, logs);

  socket.connect();

  socket.onOpen( e => console.log('Socket onOpen: ', e));
  socket.onError( e => console.log('Socket onError: ', e));
  socket.onClose( e => console.log('Socket onClose: ', e));

  channel = socket.channel(channelName);
  channel.join(5000)
    .receive('ok', data => {
      store.dispatch({type: 'NEXT_COLOR', color: data.color });
      store.dispatch({type: 'UPDATE_COUNTER', counter: data.counter });
    })
    .receive('error', err => {
      console.log(err);
    });

  channel.on('color_generated', payload => {
    console.log(payload.color);
    store.dispatch({type: 'NEXT_COLOR', color: payload.color });
  });

  channel.on('counter_bump', payload => {
    store.dispatch({type: 'UPDATE_COUNTER', counter: payload.counter });
  });

}

export function dispatchSocketMessage(message) {
  return new Promise((resolve, reject) => {
    channel.push(message)
      .receive('ok', resolve)
      .receive('err', reject);
  });
}

Repos:

  1. Front
  2. Backend
Haito
  • 2,039
  • 1
  • 24
  • 35

0 Answers0