Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add signalR using web sockets #18

Merged
merged 5 commits into from
May 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions ProChess/Client/Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
<ItemGroup>
<PackageReference Include="Blazored.LocalStorage" Version="4.3.0" />
<PackageReference Include="Blazored.Modal" Version="7.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="7.0.4" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.4" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.4" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="7.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.5" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="7.0.5" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\Shared.csproj" />
Expand Down
56 changes: 49 additions & 7 deletions ProChess/Client/Components/Board/Chessboard.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,75 @@
using Blazored.Modal.Services;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.SignalR.Client;
using Shared.Data;
using Shared.Rules;

namespace Client.Components.Board
{
public partial class Chessboard
{
[CascadingParameter]
IModalService Modal { get; set; } = default!;
private bool _whiteTurn { get; set; } = true;
Piece? activePiece = null;
List<Cell> cellsPossible = new();
#region Parameters

[CascadingParameter] IModalService Modal { get; set; } = default!;
[Parameter] public HubConnection HubConnection { get; set; } = default!;
[Parameter] public string TableId { get; set; } = default!;
[Parameter] public bool IsWhitePlayer { get; set; }

#endregion

#region Private filds and properties

#region Fields

private readonly int[] _positionsTransformation = { 0, 7 };
private readonly string[] _horizontalAxis = { "a", "b", "c", "d", "e", "f", "g", "h" };
private readonly string[] _verticalAxis = { "1", "2", "3", "4", "5", "6", "7", "8" };
private readonly int[] _positionsTransformation = { 0, 7 };

#endregion

#region Property

private bool _whiteTurn { get; set; } = true;
private List<Piece> _whitePieces { get; set; } = new List<Piece>();
private List<Piece> _blackPieces { get; set; } = new List<Piece>();

#endregion

#endregion

Piece? activePiece = null;
List<Cell> cellsPossible = new();

protected override void OnInitialized()
{
GamePieces gamePieces = new GamePieces();

_blackPieces = gamePieces.InitializationBlackPieces();
_whitePieces = gamePieces.InitializationWhitePieces();

HubConnection.On<int, int, int, int>("Move", ServerMoveAsync);
}

private async Task ServerMoveAsync(int previousRow, int previousColumn, int newRow, int newColumn)
{
var piece = _blackPieces.FirstOrDefault(x => x.StartColumn == previousColumn && x.StartRow == previousRow);
if (piece == null)
{
piece = _whitePieces.FirstOrDefault(x => x.StartColumn == previousColumn && x.StartRow == previousRow);
}
activePiece = piece;
EvaluatePieceSpots();
await MoveOrAttackPiece(new Cell(newRow, newColumn));
}

private void ClickOnPiece(MouseEventArgs e, Piece piece)
{
if (_whiteTurn != IsWhitePlayer)
{
return;
}

if (activePiece == piece)
{
activePiece = null;
Expand Down Expand Up @@ -74,6 +113,8 @@ private async Task MoveOrAttackPiece(Cell cell)

if (activePiece != null)
{
await HubConnection.SendAsync("Move", TableId, activePiece.StartRow, activePiece.StartColumn, cell.Row, cell.Column);

activePiece.MoveOrAttack(cell, _whitePieces, _blackPieces);

if (activePiece as Pawn != null && (activePiece.StartRow == _positionsTransformation[0] ||
Expand All @@ -85,7 +126,7 @@ private async Task MoveOrAttackPiece(Cell cell)
var infoPiece = await modal.Result;
var newPiece = (infoPiece.Data as Piece) ?? throw new InvalidOperationException("Bad");

if (activePiece.Color == PieceColor.White)
if (activePiece.Color == PieceColor.White)
{
_whitePieces.Remove(activePiece);
_whitePieces.Add(newPiece);
Expand All @@ -100,6 +141,7 @@ private async Task MoveOrAttackPiece(Cell cell)
activePiece = null;
_whiteTurn = !_whiteTurn;
EvaluatePieceSpots();
StateHasChanged();
}
}
}
Expand Down
23 changes: 20 additions & 3 deletions ProChess/Client/Pages/Index.razor
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
@page "/"
@using Microsoft.AspNetCore.SignalR.Client;
@inject HttpClient Http

<div id="app">
<Chessboard />
</div>
@if (@inGame)
{
<div id="app">
<Chessboard HubConnection="@hubConnection" TableId="@tableId" IsWhitePlayer="@isWhitePlayer"/>
</div>
}
else
{
<button @onclick="CreateGame">Create Game</button>

@if (tables != null)
{
@foreach (string tableId in tables)
{
<button @onclick="() => JoinGame(tableId)">Join Game @tableId</button>
}
}
}
45 changes: 45 additions & 0 deletions ProChess/Client/Pages/Index.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System.Net.Http.Json;
using Microsoft.AspNetCore.SignalR.Client;

namespace Client.Pages
{
public partial class Index
{
HubConnection hubConnection = new HubConnectionBuilder().WithUrl("https://localhost:7197/connect").Build();

bool inGame = false;
bool isWhitePlayer = true;
string tableId = "";

List<string>? tables = new List<string>();

protected override async Task OnInitializedAsync()
{
await RefreshTables();
}

public async Task RefreshTables()
{
tables = await Http.GetFromJsonAsync<List<string>>("/table/getTables");
}

public async Task CreateGame()
{
await hubConnection.StartAsync();

tableId = Guid.NewGuid().ToString();
await hubConnection.SendAsync("JoinTable", tableId);
inGame = true;
}

public async Task JoinGame(string gameId)
{
await hubConnection.StartAsync();
this.tableId = gameId;
isWhitePlayer = false;
await hubConnection.SendAsync("JoinTable", gameId);
inGame = true;
}
}
}

2 changes: 1 addition & 1 deletion ProChess/Client/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Client;
using Blazored.Modal;
using Client.Auth;
using Blazored.Modal;
using Blazored.LocalStorage;
using Client.Auth.Service;

Expand Down
4 changes: 2 additions & 2 deletions ProChess/Domain/Domain.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="7.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.4" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="7.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="7.0.3" />
</ItemGroup>

Expand Down
7 changes: 7 additions & 0 deletions ProChess/Shared/Data/TableManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Shared.Data
{
public class TableManager
{
public Dictionary<string, int> Tables { get; set; } = new();
}
}
2 changes: 1 addition & 1 deletion ProChess/Shared/Shared.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="7.0.4" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="7.0.5" />
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion ProChess/Tests/Shared.Test/Shared.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.10.0" />
<PackageReference Include="FluentAssertions" Version="6.11.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.4.2" />
Expand Down
23 changes: 23 additions & 0 deletions ProChess/WebAPI/Controllers/TableController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Microsoft.AspNetCore.Mvc;
using Shared.Data;

namespace WebAPI.Controllers
{
[Route("table")]
[ApiController]
public class TableController : ControllerBase
{
private readonly TableManager _tableManager;

public TableController(TableManager tableManager)
{
_tableManager = tableManager;
}

[HttpGet("getTables")]
public IEnumerable<string> GetTables()
{
return _tableManager.Tables.Where(x => x.Value < 2).Select(x => x.Key);
}
}
}
40 changes: 40 additions & 0 deletions ProChess/WebAPI/Hubs/MultiplayerHub.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using Microsoft.AspNetCore.SignalR;
using Shared.Data;

namespace WebAPI.Hubs
{
public class MultiplayerHub : Hub
{
private readonly TableManager _tableManager;

public MultiplayerHub(TableManager tableManager)
{
_tableManager = tableManager;
}

public async Task JoinTable(string tableId)
{
if (_tableManager.Tables.ContainsKey(tableId))
{
if (_tableManager.Tables[tableId] < 2)
{
await Groups.AddToGroupAsync(Context.ConnectionId, tableId);

await Clients.GroupExcept(tableId, Context.ConnectionId).SendAsync("TableJoined");

_tableManager.Tables[tableId]++;
}
}
else
{
await Groups.AddToGroupAsync(Context.ConnectionId, tableId);
_tableManager.Tables.Add(tableId, 1);
}
}

public async Task Move(string tableId, int previousRow, int previousColumn, int newRow, int newColumn)
{
await Clients.GroupExcept(tableId, Context.ConnectionId).SendAsync("Move", previousRow, previousColumn, newRow, newColumn);
}
}
}
12 changes: 5 additions & 7 deletions ProChess/WebAPI/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Shared.Data;
using System.Text;
using WebAPI.Hubs;

var builder = WebApplication.CreateBuilder(args);

Expand All @@ -14,6 +16,7 @@

builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();
builder.Services.AddSignalR();

builder.Services.AddDbContext<ChessDbContext>(options =>
options.UseNpgsql(builder.Configuration.GetConnectionString("ChessDatabase")));
Expand All @@ -35,15 +38,10 @@
};
});

//builder.Services.AddSwaggerGen(options => options.SwaggerDoc("v1",
// new Microsoft.OpenApi.Models.OpenApiInfo
// {
// Title = "ProChess",
// Version = "v1",
// }));
builder.Services.AddSwaggerGen();

builder.Services.AddScoped<IUnitOfWork, UnitOfWork>();
builder.Services.AddSingleton<TableManager>();

var app = builder.Build();

Expand All @@ -65,7 +63,6 @@
app.UseStaticFiles();

app.UseSwagger();
//app.UseSwaggerUI(options => options.SwaggerEndpoint("/swagger/v1/swagger.json", "ProChess"));
app.UseSwaggerUI();

app.UseRouting();
Expand All @@ -75,6 +72,7 @@

app.MapRazorPages();
app.MapControllers();
app.MapHub<MultiplayerHub>("/connect");
app.MapFallbackToFile("index.html");

app.Run();
8 changes: 4 additions & 4 deletions ProChess/WebAPI/WebAPI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
<PropertyGroup Condition=" '$(RunConfiguration)' == 'https' " />
<PropertyGroup Condition=" '$(RunConfiguration)' == 'http' " />
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.4" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="7.0.4" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="7.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.4">
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="7.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="7.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down