Skip to content

Commit

Permalink
Merge pull request #18 from mladion/add_signalR_using_webSockets
Browse files Browse the repository at this point in the history
Add signalR using web sockets
  • Loading branch information
mladion committed May 9, 2023
2 parents c646ee1 + 596fb16 commit 32734a2
Show file tree
Hide file tree
Showing 13 changed files with 202 additions and 29 deletions.
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

0 comments on commit 32734a2

Please sign in to comment.