using Microsoft.AspNetCore.SignalR.Client; using Polly; using Refit; using Sledgemapper.Shared.Entities; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Threading.Tasks; namespace Sledgemapper { public class CommunicationManager { public IMapApi Api { get; private set; } public HubConnection Connection { get; private set; } public Session SessionData; private ChannelsQueue Queue = new ChannelsQueue(); public CommunicationManager(Session sessionData) { SessionData = sessionData; Connection = new HubConnectionBuilder() .WithAutomaticReconnect() .WithUrl("http://localhost:5000/SledgemapperHub") // .WithUrl("http://hub.michelescandura.com:5000/SledgemapperHub") .Build(); var httpClientHandler = new HttpClientHandler(); //if (myConfigurationService.VerifySslCertificate == false) //{ httpClientHandler.ServerCertificateCustomValidationCallback = (message, certificate, chain, sslPolicyErrors) => true; //} Api = RestService.For( new HttpClient(httpClientHandler) { BaseAddress = new Uri("http://localhost:5000") } ); Connection.On("UpdateMap", (map) => { SessionData.Map = map.Map; SessionData.Walls = map.Walls; SessionData.Overlays = map.Overlays; }); Connection.On("PlayerUpdate", (player) => { var p = SessionData.Players.FirstOrDefault(m => m.ConnectionId == player.ConnectionId); if (p != null) { p.Position = player.Position; } }); Connection.On("DeleteTile", (tile) => { SessionData.Map.Remove(tile.ToString(), out var _); }); Connection.On("DeleteWall", (tile) => { SessionData.Walls.Remove(tile.ToString(), out var _); }); Connection.On("DeleteOverlay", (tile) => { SessionData.Overlays.Remove(tile.ToString(), out var _); }); Connection.On("NewTile", (tile) => { SessionData.Map.Remove(tile.ToString(), out var _); SessionData.Map.TryAdd(tile.ToString(), tile); }); Connection.On("NewWall", (tile) => { SessionData.Walls.Remove(tile.ToString(), out var _); SessionData.Walls.TryAdd(tile.ToString(), tile); }); Connection.On("NewOverlay", (tile) => { SessionData.Overlays.Remove(tile.ToString(), out var _); SessionData.Overlays.TryAdd(tile.ToString(), tile); }); Connection.On("NewPlayer", (player) => { var p = SessionData.Players.FirstOrDefault(m => m.ConnectionId == player.ConnectionId); if (p is null) { SessionData.Players.Add(player); } else { p.Color = player.Color; p.Position = player.Position; } }); } private async Task Execute(Func call) { await Policy .Handle(ex => ex.StatusCode == HttpStatusCode.RequestTimeout) .RetryForeverAsync() //.RetryAsync(Polly.RetrySyntax., async (exception, retryCount) => await Task.Delay(500)) .ExecuteAsync(async () => await call().ConfigureAwait(false)) .ConfigureAwait(false); } public void Enqueue(BaseMapEntity entity, TileAction action) { switch (action) { case TileAction.Add: switch (entity) { case Tile tile: Queue.Enqueue(async () => await Execute(async () => await Api.NewTile(tile, SessionData.SessionName))); break; case Overlay overlay: Queue.Enqueue(async () => await Execute(async () => await Api.NewOverlay(overlay, SessionData.SessionName))); break; case Wall wall: Queue.Enqueue(async () => await Execute(async () => await Api.NewWall(wall, SessionData.SessionName))); break; } break; case TileAction.Delete: switch (entity) { case Tile tile: Queue.Enqueue(async () => await Execute(async () => await Api.DeleteTile(tile, SessionData.SessionName))); break; case Overlay overlay: Queue.Enqueue(async () => await Execute(async () => await Api.DeleteOverlay(overlay, SessionData.SessionName))); break; case Wall wall: Queue.Enqueue(async () => await Execute(async () => await Api.DeleteWall(wall, SessionData.SessionName))); break; } break; } } } }