not reseting state on browser disconnect or reconnect

This commit is contained in:
2026-03-03 14:53:59 -07:00
parent 60714f9afd
commit 7eb95af0b8
6 changed files with 119 additions and 96 deletions

View File

@@ -8,13 +8,13 @@ defmodule BackendWeb.ClusterStatusChannel do
@impl true
def join("cluster_status", _params, socket) do
Logger.info("Client joined clusterstatus channel")
:net_kernel.monitor_nodes(true)
{:ok, %{status: "connected"}, socket}
end
@impl true
def handle_in("get_nodes", _payload, socket) do
Logger.info("Client requested node list #{inspect(Node.list())}")
push(socket, "node_list", %{other_nodes: Node.list(), connected_node: node()})
send_node_list(socket)
{:noreply, socket}
end
@@ -29,4 +29,28 @@ defmodule BackendWeb.ClusterStatusChannel do
def handle_in(_event, _payload, socket) do
{:noreply, socket}
end
@impl true
def handle_info({:nodeup, node_name}, socket) do
Logger.info("Node up: #{node_name}, broadcasting updated node list")
send_node_list(socket)
{:noreply, socket}
end
@impl true
def handle_info({:nodedown, node_name}, socket) do
Logger.info("Node down: #{node_name}, broadcasting updated node list")
send_node_list(socket)
{:noreply, socket}
end
defp send_node_list(socket) do
game_pid = Backend.GameRunner.get_pid()
push(socket, "node_list", %{
other_nodes: Node.list(),
connected_node: node(),
game_node: node(game_pid)
})
end
end

View File

@@ -20,6 +20,11 @@ defmodule BackendWeb.ConnectedUserChannel do
:new_browser_connection
)
socket =
socket
|> assign(:player_name, socket_user)
|> assign(:keys_pressed, MapSet.new())
current_state = Backend.GameRunner.get_state()
{:ok, %{game_state: current_state}, socket}
end
@@ -47,74 +52,42 @@ defmodule BackendWeb.ConnectedUserChannel do
end
@impl true
@spec handle_in(<<_::48, _::_*8>>, map(), any()) ::
{:noreply, any()} | {:reply, :ok, Phoenix.Socket.t()}
def handle_in("join_game", %{"name" => name}, socket) do
Logger.info("Player '#{name}' joining game on #{node()}")
socket =
socket
|> assign(:player_name, name)
|> assign(:keys_pressed, MapSet.new())
Backend.GameRunner.add_player(name)
{:reply, :ok, socket}
end
@impl true
def handle_in("key_down", %{"key" => key}, socket) do
case socket.assigns[:player_name] do
nil ->
Logger.warning("Key down attempted without joining game")
{:noreply, socket}
def handle_in("key_down", %{"key" => key}, %{assigns: %{player_name: player_name}} = socket) do
keys_pressed = MapSet.put(socket.assigns[:keys_pressed] || MapSet.new(), key)
socket = assign(socket, :keys_pressed, keys_pressed)
player_name ->
keys_pressed = MapSet.put(socket.assigns[:keys_pressed] || MapSet.new(), key)
socket = assign(socket, :keys_pressed, keys_pressed)
Logger.debug(
"Player '#{player_name}' key down: #{key}, keys: #{inspect(MapSet.to_list(keys_pressed))}"
)
Logger.debug(
"Player '#{player_name}' key down: #{key}, keys: #{inspect(MapSet.to_list(keys_pressed))}"
)
Backend.GameRunner.update_player_keys(
player_name,
MapSet.to_list(keys_pressed)
)
Backend.GameRunner.update_player_keys(player_name, MapSet.to_list(keys_pressed))
{:noreply, socket}
end
{:noreply, socket}
end
@impl true
def handle_in("key_up", %{"key" => key}, socket) do
case socket.assigns[:player_name] do
nil ->
Logger.warning("Key up attempted without joining game")
{:noreply, socket}
def handle_in("key_up", %{"key" => key}, %{assigns: %{player_name: player_name}} = socket) do
keys_pressed = MapSet.delete(socket.assigns[:keys_pressed] || MapSet.new(), key)
socket = assign(socket, :keys_pressed, keys_pressed)
player_name ->
keys_pressed = MapSet.delete(socket.assigns[:keys_pressed] || MapSet.new(), key)
socket = assign(socket, :keys_pressed, keys_pressed)
Logger.debug(
"Player '#{player_name}' key up: #{key}, keys: #{inspect(MapSet.to_list(keys_pressed))}"
)
Logger.debug(
"Player '#{player_name}' key up: #{key}, keys: #{inspect(MapSet.to_list(keys_pressed))}"
)
Backend.GameRunner.update_player_keys(player_name, MapSet.to_list(keys_pressed))
Backend.GameRunner.update_player_keys(player_name, MapSet.to_list(keys_pressed))
{:noreply, socket}
end
end
@impl true
def terminate(_reason, socket) do
case socket.assigns[:player_name] do
nil ->
Logger.info("WebSocket disconnected from #{node()}")
player_name ->
Logger.info("Player '#{player_name}' disconnected from #{node()}")
Backend.GameRunner.remove_player(player_name)
end
:ok
{:noreply, socket}
end
end