adding skeleton for cache hub proxy

This commit is contained in:
andy 2021-11-03 22:27:50 +00:00
parent 933e8725c4
commit 3867ea8fad
8 changed files with 247 additions and 0 deletions

41
Selector.Web/Pages/Now.cs Normal file
View File

@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.SignalR;
using Microsoft.AspNetCore.Identity;
using Selector.Web.Hubs;
using Selector.Web.Service;
using Selector.Model;
namespace Selector.Web.Pages
{
public class NowModel : PageModel
{
private readonly ILogger<NowModel> Logger;
private readonly INowPlayingMappingFactory MappingFactory;
private readonly CacheHubProxy HubProxy;
private readonly UserManager<ApplicationUser> UserManager;
public NowModel(ILogger<NowModel> logger,
INowPlayingMappingFactory mappingFactory,
CacheHubProxy hubProxy,
UserManager<ApplicationUser> userManager)
{
Logger = logger;
MappingFactory = mappingFactory;
HubProxy = hubProxy;
UserManager = userManager;
}
public void OnGet()
{
HubProxy.FormMapping(MappingFactory.Get(UserManager.GetUserId(User)));
}
}
}

View File

@ -0,0 +1,13 @@
@page
@model NowModel
@{
ViewData["Title"] = "Now";
}
<div class="text-center">
<h1 class="display-4">Now</h1>
</div>
@section Scripts {
<script type="module" src="~/js/now.bundle.js"></script>
}

View File

@ -0,0 +1,71 @@
using System;
using System.Linq;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.SignalR;
using StackExchange.Redis;
using Selector.Web.Hubs;
namespace Selector.Web.Service
{
public class CacheHubProxy
{
private readonly ILogger<CacheHubProxy> Logger;
private readonly ISubscriber Subscriber;
private readonly ServiceProvider Services;
public CacheHubProxy(ILogger<CacheHubProxy> logger,
ISubscriber subscriber,
ServiceProvider services
)
{
Logger = logger;
Subscriber = subscriber;
Services = services;
}
public void FormMapping<THub, T>(ICacheHubMapping<THub, T> mapping) where THub: Hub<T> where T: class
{
var context = Services.GetService<IHubContext<THub, T>>();
mapping.ConstructMapping(Subscriber, context);
}
}
// public class CacheHubProxy<THub, T>
// where THub: Hub<T>
// where T: class
// {
// private readonly ILogger<CacheHubProxy<THub, T>> Logger;
// private readonly ISubscriber Subscriber;
// private readonly IHubContext<THub, T> HubContext;
// private readonly List<ICacheHubMapping<THub, T>> Mappings;
// public CacheHubProxy(ILogger<CacheHubProxy<THub, T>> logger,
// ISubscriber subscriber,
// IHubContext<THub, T> hubContext,
// IEnumerable<ICacheHubMapping<THub, T>> mappings
// )
// {
// Logger = logger;
// Subscriber = subscriber;
// HubContext = hubContext;
// Mappings = mappings.ToList();
// }
// public void FormMapping(ICacheHubMapping<THub, T> mapping)
// {
// mapping.ConstructMapping(Subscriber, HubContext);
// }
// public void AddMapping(ICacheHubMapping<THub, T> mapping)
// {
// Mappings.Add(mapping);
// FormMapping(mapping);
// }
// }
}

View File

@ -0,0 +1,35 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace Selector.Web.Service
{
public class CacheHubProxyService: IHostedService
{
private readonly ILogger<CacheHubProxyService> Logger;
private readonly CacheHubProxy Proxy;
public CacheHubProxyService(
ILogger<CacheHubProxyService> logger,
CacheHubProxy proxy
)
{
Logger = logger;
Proxy = proxy;
}
public Task StartAsync(CancellationToken cancellationToken)
{
Logger.LogInformation("Starting cache hub proxy");
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
Logger.LogInformation("Stopping cache hub proxy");
return Task.CompletedTask;
}
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using StackExchange.Redis;
namespace Selector.Web.Service
{
public interface ICacheHubMapping<THub, T>
where THub : Hub<T>
where T : class
{
public Task ConstructMapping(ISubscriber subscriber, IHubContext<THub, T> hub);
// public Task RemoveMapping(ISubscriber subscriber, THub hub);
}
}

View File

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using SpotifyAPI.Web;
namespace Selector.Web.Service
{
public interface INowPlayingMappingFactory {
public NowPlayingMapping Get(string userId);
}
public class NowPlayingMappingFactory : INowPlayingMappingFactory {
private readonly ILoggerFactory LoggerFactory;
public NowPlayingMappingFactory(ILoggerFactory loggerFactory)
{
LoggerFactory = loggerFactory;
}
public NowPlayingMapping Get(string userId)
{
return new NowPlayingMapping(
LoggerFactory?.CreateLogger<NowPlayingMapping>(),
userId
);
}
}
}

View File

@ -0,0 +1,33 @@
using System;
using System.Text.Json;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
using StackExchange.Redis;
using Selector.Web.Hubs;
using Selector.Cache;
namespace Selector.Web.Service
{
public class NowPlayingMapping : ICacheHubMapping<NowPlayingHub, INowPlayingHubClient>
{
private readonly string UserId;
public NowPlayingMapping(ILogger<NowPlayingMapping> logger, string userId)
{
UserId = userId;
}
public async Task ConstructMapping(ISubscriber subscriber, IHubContext<NowPlayingHub, INowPlayingHubClient> hub)
{
(await subscriber.SubscribeAsync(Key.CurrentlyPlaying(UserId))).OnMessage(async message => {
var deserialised = JsonSerializer.Deserialize<CurrentlyPlayingDTO>(message.ToString());
await hub.Clients.User(UserId).OnNewPlaying(deserialised);
});
}
}
}

View File

@ -15,6 +15,7 @@ using Microsoft.EntityFrameworkCore;
using StackExchange.Redis;
using Selector.Web.Service;
using Selector.Web.Hubs;
using Selector.Model;
using Selector.Model.Authorisation;
@ -115,6 +116,10 @@ namespace Selector.Web
services.AddTransient<IDatabaseAsync>(services => services.GetService<ConnectionMultiplexer>().GetDatabase());
services.AddTransient<ISubscriber>(services => services.GetService<ConnectionMultiplexer>().GetSubscriber());
}
// HOSTED
services.AddSingleton<CacheHubProxy>();
services.AddSingleton<INowPlayingMappingFactory, NowPlayingMappingFactory>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.