示例#1
0
        private List <ISocket> CreateSocketAndListenForResponsesAsync()
        {
            var sockets = new List <ISocket>();

            sockets.Add(_SocketFactory.CreateSsdpUdpSocket(IPAddress.Any, _LocalPort));

            if (_enableMultiSocketBinding)
            {
                foreach (var address in _networkManager.GetInternalBindAddresses())
                {
                    if (address.AddressFamily == AddressFamily.InterNetworkV6)
                    {
                        // Not support IPv6 right now
                        continue;
                    }

                    try
                    {
                        sockets.Add(_SocketFactory.CreateSsdpUdpSocket(address.Address, _LocalPort));
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, "Error in CreateSsdpUdpSocket. IPAddress: {0}", address);
                    }
                }
            }

            foreach (var socket in sockets)
            {
                _ = ListenToSocketInternal(socket);
            }

            return(sockets);
        }
示例#2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SsdpServerPublisher"/> class.
        /// </summary>
        /// <param name="dlnaServerManager">The <see cref="IDlnaServerManager"/> instance.</param>
        /// <param name="configuration">The <see cref="IConfigurationManager"/> instance.</param>
        /// <param name="logger">The <see cref="ILogger"/> instance.</param>
        /// <param name="loggerFactory">The <see cref="ILoggerFacory"/> instance.</param>
        /// <param name="networkManager">The <see cref="INetworkManager"/> instance.</param>
        public SsdpServerPublisher(
            IDlnaServerManager dlnaServerManager,
            IConfigurationManager configuration,
            ILogger logger,
            ILoggerFactory loggerFactory,
            INetworkManager networkManager)
        {
            _dlnaServerManager    = dlnaServerManager;
            _networkManager       = networkManager;
            _logger               = logger;
            _devices              = new List <SsdpRootDevice>();
            _readOnlyDevices      = new ReadOnlyCollection <SsdpRootDevice>(_devices);
            _recentSearchRequests = new Dictionary <string, SearchRequest>(StringComparer.OrdinalIgnoreCase);
            _random               = new Random();

            Server = SsdpServer.GetOrCreateInstance(
                configuration,
                loggerFactory,
                networkManager.GetInternalBindAddresses(),
                networkManager);

            _dlnaServerManager.ConfigurationChanged += UpdateConfiguration;
            _networkManager.NetworkChanged          += NetworkChanged;
        }
示例#3
0
        private void RegisterServerEndpoints()
        {
            var udn           = CreateUuid(_appHost.SystemId);
            var descriptorUri = "/dlna/" + udn + "/description.xml";

            var bindAddresses = NetworkManager.CreateCollection(
                _networkManager.GetInternalBindAddresses()
                .Where(i => i.AddressFamily == AddressFamily.InterNetwork || (i.AddressFamily == AddressFamily.InterNetworkV6 && i.Address.ScopeId != 0)));

            if (bindAddresses.Count == 0)
            {
                // No interfaces returned, so use loopback.
                bindAddresses = _networkManager.GetLoopbacks();
            }

            foreach (IPNetAddress address in bindAddresses)
            {
                if (address.AddressFamily == AddressFamily.InterNetworkV6)
                {
                    // Not supporting IPv6 right now
                    continue;
                }

                // Limit to LAN addresses only
                if (!_networkManager.IsInLocalNetwork(address))
                {
                    continue;
                }

                var fullService = "urn:schemas-upnp-org:device:MediaServer:1";

                _logger.LogInformation("Registering publisher for {ResourceName} on {DeviceAddress}", fullService, address);

                var uri = new UriBuilder(_appHost.GetApiUrlForLocalAccess(false) + descriptorUri);

                var device = new SsdpRootDevice
                {
                    CacheLifetime = TimeSpan.FromSeconds(1800), // How long SSDP clients can cache this info.
                    Location      = uri.Uri,                    // Must point to the URL that serves your devices UPnP description document.
                    Address       = address.Address,
                    PrefixLength  = address.PrefixLength,
                    FriendlyName  = "Jellyfin",
                    Manufacturer  = "Jellyfin",
                    ModelName     = "Jellyfin Server",
                    Uuid          = udn
                                    // This must be a globally unique value that survives reboots etc. Get from storage or embedded hardware etc.
                };

                SetProperies(device, fullService);
                _publisher.AddDevice(device);

                var embeddedDevices = new[]
                {
                    "urn:schemas-upnp-org:service:ContentDirectory:1",
                    "urn:schemas-upnp-org:service:ConnectionManager:1",
                    // "urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1"
                };

                foreach (var subDevice in embeddedDevices)
                {
                    var embeddedDevice = new SsdpEmbeddedDevice
                    {
                        FriendlyName = device.FriendlyName,
                        Manufacturer = device.Manufacturer,
                        ModelName    = device.ModelName,
                        Uuid         = udn
                                       // This must be a globally unique value that survives reboots etc. Get from storage or embedded hardware etc.
                    };

                    SetProperies(embeddedDevice, subDevice);
                    device.AddDevice(embeddedDevice);
                }
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="DlnaServerManager"/> class.
        /// </summary>
        /// <param name="loggerFactory">The <see cref="ILoggerFactory"/> instance.</param>
        /// <param name="appHost">The <see cref="IServerApplicationHost"/> instance.</param>
        /// <param name="libraryManager">The <see cref="ILibraryManager"/> instance.</param>
        /// <param name="userManager">The <see cref="IUserManager"/> instance.</param>
        /// <param name="profileManager">The <see cref="IProfileManager"/> instance.</param>
        /// <param name="imageProcessor">The <see cref="IImageProcessor"/> instance.</param>
        /// <param name="userDataManager">The <see cref="IUserDataManager"/> instance.</param>
        /// <param name="localizationManager">The <see cref="ILocalizationManager"/> instance.</param>
        /// <param name="mediaSourceManager">The <see cref="IMediaSourceManager"/> instance.</param>
        /// <param name="mediaEncoder">The <see cref="IMediaEncoder"/> instance.</param>
        /// <param name="networkManager">The <see cref="INetworkManager"/> instance.</param>
        /// <param name="userViewManager">The <see cref="IUserViewManager"/> instance.</param>
        /// <param name="tvSeriesManager">The <see cref="ITVSeriesManager"/> instance.</param>
        /// <param name="configurationManager">The <see cref="IConfigurationManager"/> instance.</param>
        /// <param name="httpClientFactory">The <see cref="IHttpClientFactory"/> instance.</param>
        /// <param name="xmlSerializer">The <see cref="IXmlSerializer"/> instance.</param>
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. :-> ServerString
#pragma warning disable CA1062 // Validate arguments of public methods. -> Created by DI.

        public DlnaServerManager(
            ILoggerFactory loggerFactory,
            IServerApplicationHost appHost,
            ILibraryManager libraryManager,
            IUserManager userManager,
            IDeviceProfileManager profileManager,
            IImageProcessor imageProcessor,
            IUserDataManager userDataManager,
            ILocalizationManager localizationManager,
            IMediaSourceManager mediaSourceManager,
            IMediaEncoder mediaEncoder,
            INetworkManager networkManager,
            IUserViewManager userViewManager,
            ITVSeriesManager tvSeriesManager,
            IConfigurationManager configurationManager,
            IHttpClientFactory httpClientFactory,
            IXmlSerializer xmlSerializer)
        {
            SsdpConfiguration.JellyfinVersion = appHost.ApplicationVersionString;

            // Changing serverId will cause dlna url links to become invalid between restarts.
            ServerId              = DlnaServerPlugin.Instance !.Configuration.ChangeIdOnStartup ? Guid.NewGuid() : Guid.Parse(appHost.SystemId);
            _networkManager       = networkManager;
            _appHost              = appHost;
            _logger               = loggerFactory.CreateLogger <DlnaServerManager>();
            _configurationManager = configurationManager;
            _profileManager       = profileManager;

            EventManager = new DlnaEventManager(_logger, httpClientFactory);

            // Link into the streaming API, so that headers etc can be performed.
            StreamingHelpers.StreamEvent ??= DlnaStreamHelper.StreamEventProcessor;

            _logger.LogDebug("DLNA Server : Starting Content Directory service.");
            ContentDirectory = new ContentDirectoryService(
                profileManager,
                userDataManager,
                imageProcessor,
                libraryManager,
                userManager,
                _logger,
                localizationManager,
                mediaSourceManager,
                userViewManager,
                mediaEncoder,
                tvSeriesManager);

            _logger.LogDebug("DLNA Server : Starting Connection Manager service.");
            ConnectionManager = new ConnectionManagerService(profileManager, _logger);

            var config = DlnaServerPlugin.Instance !.Configuration;
            // Get bind addresses or interfaces if not specified.
            var interfaces = config.BindAddresses;

            var bindInterfaces = _networkManager.GetInternalBindAddresses();

            if (interfaces.Length > 0)
            {
                // Select only the internal interfaces that are LAN and bound.
                var addresses = _networkManager.CreateIPCollection(interfaces, false, false);
                _bindAddresses = bindInterfaces.Where(i => addresses.Contains(i) &&
                                                      (i.AddressFamily == AddressFamily.InterNetwork || (i.AddressFamily == AddressFamily.InterNetworkV6 && i.Address.ScopeId != 0)))
                                 .ToArray();
            }
            else
            {
                _bindAddresses = bindInterfaces.Where(i => !i.IsLoopback() &&
                                                      (i.AddressFamily == AddressFamily.InterNetwork || (i.AddressFamily == AddressFamily.InterNetworkV6 && i.Address.ScopeId != 0)))
                                 .ToArray();
            }

            if (_bindAddresses.Length == 0)
            {
                // only use loop-backs if no other address available.
                _bindAddresses = bindInterfaces;
            }

            _publisher = new SsdpServerPublisher(
                configurationManager,
                _logger,
                loggerFactory,
                _networkManager,
                _bindAddresses,
                config.AliveMessageIntervalSeconds,
                config.EnableWindowsExplorerSupport);

            // Load system profiles into memory.
            ProfileHelper.ExtractSystemTemplates(_logger, _profileManager, xmlSerializer).GetAwaiter().GetResult();

            // Solves a race condition can occur when API receives input before DI initialization is complete.
            Instance = this;
        }