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

Auto Discovery Cleanup #10793

Merged
merged 7 commits into from
Jan 6, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
4 changes: 3 additions & 1 deletion Jellyfin.Server/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
using System.Text;
using Jellyfin.Api.Middleware;
using Jellyfin.MediaEncoding.Hls.Extensions;
using Jellyfin.Networking;
using Jellyfin.Networking.HappyEyeballs;
using Jellyfin.Server.Extensions;
using Jellyfin.Server.HealthChecks;
using Jellyfin.Server.Implementations;
using Jellyfin.Server.Implementations.Extensions;
using Jellyfin.Server.Infrastructure;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Extensions;
using Microsoft.AspNetCore.Builder;
Expand Down Expand Up @@ -121,6 +121,8 @@ public void ConfigureServices(IServiceCollection services)
.AddCheck<DbContextFactoryHealthCheck<JellyfinDbContext>>(nameof(JellyfinDbContext));

services.AddHlsPlaylistGenerator();

services.AddHostedService<AutoDiscoveryHost>();
}

/// <summary>
Expand Down
103 changes: 103 additions & 0 deletions src/Jellyfin.Networking/AutoDiscoveryHost.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
using MediaBrowser.Model.ApiClient;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace Jellyfin.Networking;

/// <summary>
/// <see cref="BackgroundService"/> responsible for responding to auto-discovery messages.
/// </summary>
public sealed class AutoDiscoveryHost : BackgroundService
{
/// <summary>
/// The port to listen on for auto-discovery messages.
/// </summary>
private const int PortNumber = 7359;

private readonly ILogger<AutoDiscoveryHost> _logger;
private readonly IServerApplicationHost _appHost;
private readonly IConfigurationManager _configurationManager;

/// <summary>
/// Initializes a new instance of the <see cref="AutoDiscoveryHost" /> class.
/// </summary>
/// <param name="logger">Instance of the <see cref="ILogger{UdpServerEntryPoint}"/> interface.</param>
/// <param name="appHost">Instance of the <see cref="IServerApplicationHost"/> interface.</param>
/// <param name="configurationManager">Instance of the <see cref="IConfigurationManager"/> interface.</param>
public AutoDiscoveryHost(
ILogger<AutoDiscoveryHost> logger,
IServerApplicationHost appHost,
IConfigurationManager configurationManager)
{
_logger = logger;
_appHost = appHost;
_configurationManager = configurationManager;
}

/// <inheritdoc />
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
if (!_configurationManager.GetNetworkConfiguration().AutoDiscovery)
{
return;
}

using var udpClient = new UdpClient(PortNumber);
udpClient.MulticastLoopback = false;

while (!stoppingToken.IsCancellationRequested)
{
try
{
var result = await udpClient.ReceiveAsync(stoppingToken).ConfigureAwait(false);
var text = Encoding.UTF8.GetString(result.Buffer);
if (text.Contains("who is JellyfinServer?", StringComparison.OrdinalIgnoreCase))
{
await RespondToV2Message(udpClient, result.RemoteEndPoint, stoppingToken).ConfigureAwait(false);
}
}
catch (SocketException ex)
{
_logger.LogError(ex, "Failed to receive data from socket");
}
catch (OperationCanceledException)
{
_logger.LogDebug("Broadcast socket operation cancelled");
}
}
}

private async Task RespondToV2Message(UdpClient udpClient, IPEndPoint endpoint, CancellationToken cancellationToken)
{
var localUrl = _appHost.GetSmartApiUrl(endpoint.Address);
if (string.IsNullOrEmpty(localUrl))
{
_logger.LogWarning("Unable to respond to server discovery request because the local ip address could not be determined.");
return;
}

var response = new ServerDiscoveryInfo(localUrl, _appHost.SystemId, _appHost.FriendlyName);

try
{
_logger.LogDebug("Sending AutoDiscovery response");
await udpClient
.SendAsync(JsonSerializer.SerializeToUtf8Bytes(response).AsMemory(), endpoint, cancellationToken)
.ConfigureAwait(false);
}
catch (SocketException ex)
{
_logger.LogError(ex, "Error sending response message");
}
}
}
136 changes: 0 additions & 136 deletions src/Jellyfin.Networking/Udp/UdpServer.cs

This file was deleted.

Loading
Loading