necromorph23

necromorph23

Phoenix Channels keeps giving 'error', 'joining' and 'closed' states response

I am implementing a chess server in elixir, I am implementing the client in React and I am using phoenix npm framework in react for handling socket and channel logic. This is my User Socket Code:

defmodule VortexPubSub.Cygnus.UserSocket do
  use Phoenix.Socket
  require Logger
  alias VortexPubSub.KafkaProducer
  alias VortexPubSub.Constants
  alias Holmberg.Mutation.User, as: UserMutation

  channel "game:chess:*", VortexPubSub.Cygnus.ChessGameChannel

  @impl true
  def connect(%{"token" => token , "user_id" => user_id , "username" => username}, socket) do

        user_connection_event_payload = %{user_id: user_id , username: username}
        case UserMutation.set_user_online(user_id, true) do
          {:ok , _} -> {:ok , assign(socket, :user_id, user_id)}

          {:error, _} ->:error
        end
  end

  def connect(_params) do
    Logger.info("THIS IS different connect fn")
    :error
  end

  def id(socket), do: nil

end

The Chess Channel is defined like this:

defmodule VortexPubSub.Cygnus.ChessGameChannel do
  alias MaelStorm.ChessServer
  alias VortexPubSub.Presence
  alias VortexPubSub.KafkaProducer
  alias VortexPubSub.Constants

  def join("game:chess:" <> game_id, _params, socket) do
    IO.puts("Received join message from user ")
    case ChessServer.game_pid(game_id) do
      pid when is_pid(pid) ->
        IO.puts("Channel Joinin Successful")
        {:ok, socket}

      nil ->
        IO.puts("ERROR WHILE JOINING CHANNEL")
        {:error, %{reason: "Game does not exist"}}

      _ -> IO.puts("Some other error ")
        {:error, %{reason: "Game does not exist"}}
    end
  end

  def handle_in("joined-room", %{"user_id" => user_id, "username" => username}, socket) do
    #Add logic to prevent user from joining if the game is in progress
      "game:chess:" <> game_id = socket.topic

    Phoenix.PubSub.broadcast!(socket, "new-user-joined", %{user_id: user_id, username: username, game_id: game_id})

    #Send Current turn mappings of game to joined user

    KafkaProducer.send_message(Constants.kafka_user_topic(), %{user_id: user_id, username: username, game_id: game_id} ,
      Constants.kafka_user_joined_event_key())

    {:noreply, socket}
  end


  def handle_in("leaved-room", %{"user_id" => user_id, "username" => username, "game_id" => game_id, "player_type" => player_type}, socket) do
    if player_type == "host" do

    Phoenix.PubSub.broadcast!(socket, "remove-all-users", %{user_id: user_id, username: username, game_id: game_id, player_type: player_type})
    KafkaProducer.send_message(Constants.kafka_game_topic(), %{message: "host-left", game_id: game_id}, Constants.kafka_game_general_event_key())

    else
      Phoenix.PubSub.broadcast!(socket, "user-left-room", %{user_id: user_id, username: username, game_id: game_id, player_type: player_type})
    end

    KafkaProducer.send_message(Constants.kafka_user_topic(),  %{user_id: user_id, username: username, game_id: game_id, player_type: player_type}, Constants.kafka_user_left_room_event_key())
    {:noreply,socket}

  end

  def handle_in("update-user-status-in-room", %{user_id: user_id, username: username, game_id: game_id, status: status} ,socket) do
    Phoenix.PubSub.broadcast!(socket, "user-status-update", %{user_id: user_id, username: username, game_id: game_id, status: status}  )
    KafkaProducer.send_message(Constants.kafka_user_topic(),  %{user_id: user_id, username: username, game_id: game_id, status: status}, Constants.kafka_user_status_event_key())
    {:noreply,socket}
  end


  def handle_in("game-event", %{user_id: user_id, game_id: game_id, game_event: game_event, event_type: event_type} , socket) do
    Phoenix.PubSub.broadcast!(socket, "send-user-game-event", %{user_id: user_id, game_id: game_id, game_event: game_event, event_type: event_type}  )
    user_game_move_event =  %{
          game_id: game_id,
          user_id: user_id,
          user_move: game_event,
         move_type: event_type,
      }

    KafkaProducer.send_message(Constants.kafka_user_game_events_topic(),  %{user_id: user_id, game_id: game_id, game_event: game_event, event_type: event_type}, Constants.kafka_user_game_move_event_key())
    {:noreply,socket}
  end

  def handle_in("verifying-game-status", %{user_id: user_id, game_id: game_id} , socket) do
    Phoenix.PubSub.broadcast!(socket, "verifying-game", %{user_id: user_id , game_id: game_id} )
    KafkaProducer.send_message(Constants.kafka_user_topic(),  %{user_id: user_id, game_id: game_id}, Constants.kafka_verifying_game_status_event_key())
    {:noreply,socket}
  end

  def handle_in("start-game-event", %{admin_id: admin_id, game_id: game_id, game_name: game_name} , socket) do
    Phoenix.PubSub.broadcast!(socket, "start-game-for-all", %{admin_id: admin_id , game_id: game_id, game_name: game_name} )
   # KafkaProducer.send_message(Constants.kafka_user_topic(),  %{admin_id: admin_id, game_id: game_id}, Constants.kafka_verifying_game_status_event_key())
    {:noreply,socket}
  end

  defp current_player(socket) do
      socket.assigns.current_player
  end

  def terminate(reason, socket) do
    # Add Logic to rearrange the state if user disconnects in arbitary way
    # Handle cleanup or logging when a client leaves
    IO.puts "Client left channel: #{inspect(reason)}"
    :ok
  end
end

This is my react code to create a socket connection and connect to channel

  useEffect( () => {
    if(!gameStore.isSpectator) {

      console.log("Channel join loop. Current status of channel is")
      console.log(chann)
 
     if(chann === null) {
      let new_socket = new Socket("ws://localhost:4001/socket", {params: {token: "token" , user_id: user_details.id , username: user_details.username }})
      new_socket.connect()
      console.log("setting chann this time")
      let chann_new = new_socket.channel("game:" + gameType + ":" + game_id , {})
      console.log("new channel is")
      console.log(chann_new)

      chann_new.join().receive("ok", response => {
        console.log(`Joined game successfully 😊`)
      })
      .receive("error", response => {
        console.log("Error while joining game")
        console.log(response)
      })

      chann_new.onError((response) => {
        console.log("SOme error occured on the channel")
        console.log(response)
      })
      
      setChannel(chann_new);
     }
       // chann_new?.push("joined-room", {game_id: game_id, user_id: user_details.id , username: user_details.username})
    } 

    return () => {
      chann?.off("joined-room")
    }
   
  } , [chann] )

The Socket connection is successful as I get this message in logs after successful connection

21:54:56.733 [info] CONNECTED TO VortexPubSub.Cygnus.UserSocket in 3ms
  Transport: :websocket
  Serializer: Phoenix.Socket.V2.JSONSerializer
  Parameters: %{"token" => "token", "user_id" => "9fc09f31-35ce-4b1f-8839-9d1ac48282db", "username" => "necromorph23", "vsn" => "2.0.0"}

But after joining the channel I keep getting this error:

Ranch listener VortexPubSub.Endpoint.HTTP had connection process started with :cowboy_clear:start_link/4 at #PID<0.624.0> exit with reason: {:undef, [{VortexPubSub.Cygnus.ChessGameChannel, :child_spec, [{VortexPubSub.Endpoint, {#PID<0.624.0>, #Reference<0.3611881942.3265527814.183130>}}], []}, {Phoenix.Channel.Server, :join, 4, [file: ~c"lib/phoenix/channel/server.ex", line: 26]}, {Phoenix.Socket, :handle_in, 4, [file: ~c"lib/phoenix/socket.ex", line: 665]}, {WebSockAdapter.CowboyAdapter, :websocket_handle, 2, [file: ~c"lib/websock_adapter/cowboy_adapter.ex", line: 24]}, {:cowboy_websocket, :handler_call, 6, [file: ~c"/mnt/e/proj/vortex_pub_sub/deps/cowboy/src/cowboy_websocket.erl", line: 528]}, {:cowboy_http, :loop, 1, [file: ~c"/mnt/e/proj/vortex_pub_sub/deps/cowboy/src/cowboy_http.erl", line: 253]}, {:proc_lib, :init_p_do_apply, 3, [file: ~c"proc_lib.erl", line: 241]}]}

The socket keeps on getting disconnecting and it connects again to the server and tries to join the channel but this loop keeps on happening.
This is the channel states I have observed in the Inspect Logs

Can anyone help me to fix this issue.
Thanks :slight_smile:

Where Next?

Popular in Questions Top

Trevoke
I have an umbrella app. Some of the apps inside depend on other apps in the umbrella, unsurprisingly. I’m writing a test for one of the...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New

Other popular topics Top

nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 54006 488
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 31494 112
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New

We're in Beta

About us Mission Statement