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 Search SignalR hub #308

Merged
merged 1 commit into from
Dec 18, 2021
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
83 changes: 83 additions & 0 deletions src/slskd/Search/API/Hubs/SearchHub.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// <copyright file="SearchHub.cs" company="slskd Team">
// Copyright (c) slskd Team. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see https://www.gnu.org/licenses/.
// </copyright>

using Microsoft.Extensions.Options;

namespace slskd.Search.API
{
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR;

public static class SearchHubMethods
{
public static readonly string Response = "RESPONSE";
public static readonly string Update = "UPDATE";
}

/// <summary>
/// Extension methods for the search SignalR hub.
/// </summary>
public static class SearchHubExtensions
{
/// <summary>
/// Broadcast an update for a search.
/// </summary>
/// <param name="hub">The hub.</param>
/// <param name="search">The search to broadcast.</param>
/// <returns>The operation context.</returns>
public static Task BroadcastUpdateAsync(this IHubContext<SearchHub> hub, Search search)
{
return hub.Clients.All.SendAsync(SearchHubMethods.Update, search);
}

/// <summary>
/// Broadcast the present application options.
/// </summary>
/// <param name="hub">The hub.</param>
/// <param name="searchId">The ID of the search associated with the response.</param>
/// <param name="response">The response to broadcast.</param>
/// <returns>The operation context.</returns>
public static Task BroadcastResponseAsync(this IHubContext<SearchHub> hub, Guid searchId, Soulseek.SearchResponse response)
{
return hub.Clients.All.SendAsync(SearchHubMethods.Response, new { searchId, response });
}
}

/// <summary>
/// The search SignalR hub.
/// </summary>
[Authorize]
public class SearchHub : Hub
{
public SearchHub(
IStateMonitor<State> stateMonitor,
IOptionsMonitor<Options> optionsMonitor)
{
StateMonitor = stateMonitor;
OptionsMonitor = optionsMonitor;
}

private IStateMonitor<State> StateMonitor { get; }
private IOptionsMonitor<Options> OptionsMonitor { get; }

public override async Task OnConnectedAsync()
{
}
}
}
18 changes: 17 additions & 1 deletion src/slskd/Search/SearchService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ namespace slskd.Search
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using slskd.Search.API;
using Soulseek;
using SearchOptions = Soulseek.SearchOptions;
using SearchQuery = Soulseek.SearchQuery;
Expand All @@ -43,18 +45,21 @@ public class SearchService : ISearchService
/// <summary>
/// Initializes a new instance of the <see cref="SearchService"/> class.
/// </summary>
/// <param name="searchHub"></param>
/// <param name="optionsMonitor"></param>
/// <param name="soulseekClient"></param>
/// <param name="application"></param>
/// <param name="contextFactory">The database context to use.</param>
/// <param name="log">The logger.</param>
public SearchService(
IHubContext<SearchHub> searchHub,
IOptionsMonitor<Options> optionsMonitor,
ISoulseekClient soulseekClient,
IApplication application,
IDbContextFactory<SearchDbContext> contextFactory,
ILogger<SearchService> log)
{
SearchHub = searchHub;
OptionsMonitor = optionsMonitor;
Client = soulseekClient;
Application = application;
Expand All @@ -70,6 +75,7 @@ public class SearchService : ISearchService
private ISoulseekClient Client { get; }
private IDbContextFactory<SearchDbContext> ContextFactory { get; }
private ILogger<SearchService> Log { get; set; }
private IHubContext<SearchHub> SearchHub { get; set; }

/// <summary>
/// Performs a search for the specified <paramref name="query"/> and <paramref name="scope"/>.
Expand All @@ -96,7 +102,7 @@ public async Task<Search> CreateAsync(Guid id, SearchQuery query, SearchScope sc
options ??= new SearchOptions();
options = options.WithActions(
stateChanged: (args) => UpdateSearchState(search, args.Search),
responseReceived: (args) => UpdateSearchState(search, args.Search));
responseReceived: (args) => UpdateSearchResponses(search, args.Search, args.Response));

try
{
Expand Down Expand Up @@ -201,10 +207,20 @@ private void UpdateSearchState(Search search, SoulseekSearch soulseekSearch)
search.ResponseCount = soulseekSearch.ResponseCount;
search.State = soulseekSearch.State;

SearchHub.BroadcastUpdateAsync(search);
SaveSearchState(search);
}
}

private void UpdateSearchResponses(Search search, SoulseekSearch soulseekSearch, Soulseek.SearchResponse response)
{
if (CancellationTokens.ContainsKey(search.Id))
{
SearchHub.BroadcastResponseAsync(search.Id, response);
UpdateSearchState(search, soulseekSearch);
}
}

private void SaveSearchState(Search search)
{
var context = ContextFactory.CreateDbContext();
Expand Down
2 changes: 2 additions & 0 deletions src/slskd/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ namespace slskd
using slskd.Integrations.Pushbullet;
using slskd.Messaging;
using slskd.Search;
using slskd.Search.API;
using slskd.Shares;
using slskd.Transfers;
using slskd.Users;
Expand Down Expand Up @@ -337,6 +338,7 @@ public void ConfigureServices(IServiceCollection services)
{
endpoints.MapHub<ApplicationHub>("/hub/application");
endpoints.MapHub<LogsHub>("/hub/logs");
endpoints.MapHub<SearchHub>("/hub/search");

endpoints.MapControllers();
endpoints.MapHealthChecks("/health");
Expand Down