1
0
mirror of https://github.com/danbee/chess synced 2025-03-04 08:39:06 +00:00

Move everything to websockets

This commit is contained in:
Daniel Barber 2018-03-11 13:11:38 -04:00
parent f83e145379
commit 0d68eeabfb
Signed by: danbarber
GPG Key ID: 931D8112E0103DD8
5 changed files with 77 additions and 22 deletions

View File

@ -25,28 +25,34 @@ class App extends React.Component {
store.dispatch(setGameId(gameId));
API.getGame(gameId)
.then(response => {
store.dispatch(setPlayer(response.data.player));
store.dispatch(setGame(response.data));
});
this.channel = Channel.gameChannel(gameId);
this.channel.on("game_update", data => {
this.channel.on("game:update", data => {
if (data.player != undefined) {
store.dispatch(setPlayer(data.player));
};
store.dispatch(setGame(data));
});
this.channel.join()
.receive("error", resp => {
console.log("Unable to join", resp);
});
}
sendMove(gameId, move) {
API.updateGame(gameId, move);
this.channel.push("game:move", move);
}
render() {
const { store, gameId } = this.props;
return (
<ChessBoard gameId={gameId} store={store} sendMove={this.sendMove} />
<ChessBoard
gameId={gameId}
store={store}
sendMove={this.sendMove.bind(this)}
/>
);
}
}

View File

@ -4,11 +4,6 @@ const Channel = {
gameChannel: (gameId) => {
const channel = socket.channel(`game:${gameId}`, {});
channel.join()
.receive("error", resp => {
console.log("Unable to join", resp);
});
return channel;
},
};

View File

@ -32,9 +32,13 @@ defmodule Chess.Store.Game do
def change_turn("white"), do: "black"
def for_user(user) do
for_user_id(user.id)
end
def for_user_id(user_id) do
from game in Game,
where: game.user_id == ^user.id,
or_where: game.opponent_id == ^user.id
where: game.user_id == ^user_id,
or_where: game.opponent_id == ^user_id
end
def ordered(query) do

View File

@ -1,19 +1,69 @@
defmodule ChessWeb.GameChannel do
@moduledoc false
use Phoenix.Channel
use ChessWeb, :channel
alias Chess.Store.Game
alias Chess.Board
def join("game:" <> _game_id, _params, socket) do
{:ok, socket}
import Chess.Auth, only: [current_user: 1]
def join("game:" <> game_id, _params, socket) do
send(self, {:after_join, game_id})
{:ok, assign(socket, :game_id, game_id)}
end
def update_game(game) do
def handle_info({:after_join, game_id}, socket) do
game =
socket.assigns.current_user_id
|> Game.for_user_id()
|> Repo.get!(game_id)
payload = %{
player: player(socket, game),
board: Board.transform(game.board),
turn: game.turn
}
push(socket, "game:update", payload)
{:noreply, socket}
end
def handle_in("game:move", move_params, socket) do
game =
socket.assigns.current_user_id
|> Game.for_user_id()
|> Repo.get!(socket.assigns.game_id)
changeset = Game.changeset(
game, %{
board: Board.move_piece(game.board, move_params),
turn: Game.change_turn(game.turn)
}
)
case Repo.update(changeset) do
{:ok, game} ->
send_update(game)
{:noreply, socket}
end
end
def send_update(game) do
payload = %{
board: Board.transform(game.board),
turn: game.turn
}
ChessWeb.Endpoint.broadcast("game:#{game.id}", "game_update", payload)
ChessWeb.Endpoint.broadcast("game:#{game.id}", "game:update", payload)
end
defp player(socket, game) do
if game.user_id == socket.assigns.current_user_id do
"white"
else
"black"
end
end
end

View File

@ -24,7 +24,7 @@ defmodule ChessWeb.UserSocket do
def connect(%{"token" => token}, socket) do
case Token.verify(socket, "game socket", token, max_age: 1_209_600) do
{:ok, user_id} ->
{:ok, assign(socket, :current_user, user_id)}
{:ok, assign(socket, :current_user_id, user_id)}
{:error, _reason} ->
:error
end