aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2017-11-23 10:46:16 -0500
committerLuke Pulverenti <luke.pulverenti@gmail.com>2017-11-23 10:46:16 -0500
commit4f09c1e06dab7cc8b260129648f5a54c77b8a4f9 (patch)
tree84666fd94143a2078c4ad2500301cd0c21a94c61
parent77695f8abed3156de04c6bb2496c14a2ab3d90a8 (diff)
reduce dlna chatter
-rw-r--r--Emby.Dlna/Main/DlnaEntryPoint.cs3
-rw-r--r--Emby.Dlna/PlayTo/Device.cs16
-rw-r--r--Emby.Dlna/PlayTo/PlayToManager.cs194
-rw-r--r--Emby.Dlna/PlayTo/SsdpHttpClient.cs7
-rw-r--r--Emby.Server.Implementations/ApplicationHost.cs22
-rw-r--r--Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs3
-rw-r--r--Emby.Server.Implementations/Library/SearchEngine.cs3
-rw-r--r--Emby.Server.Implementations/Library/UserManager.cs2
-rw-r--r--Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs2
-rw-r--r--Emby.Server.Implementations/Networking/NetworkManager.cs10
-rw-r--r--Emby.Server.Implementations/Session/SessionManager.cs2
-rw-r--r--Emby.Server.Implementations/Social/SharingManager.cs5
-rw-r--r--Emby.Server.Implementations/Udp/UdpServer.cs28
-rw-r--r--MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs5
-rw-r--r--MediaBrowser.Api/SearchService.cs13
-rw-r--r--MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs5
-rw-r--r--MediaBrowser.Api/System/ActivityLogWebSocketListener.cs3
-rw-r--r--MediaBrowser.Api/System/SystemInfoWebSocketListener.cs5
-rw-r--r--MediaBrowser.Api/System/SystemService.cs5
-rw-r--r--MediaBrowser.Controller/IServerApplicationHost.cs7
-rw-r--r--MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs8
-rw-r--r--MediaBrowser.Controller/Sync/ISyncManager.cs2
-rw-r--r--MediaBrowser.Model/Dlna/StreamBuilder.cs2
-rw-r--r--MediaBrowser.Model/Search/SearchHint.cs1
-rw-r--r--MediaBrowser.WebDashboard/Api/PackageCreator.cs11
-rw-r--r--SharedVersion.cs2
26 files changed, 215 insertions, 151 deletions
diff --git a/Emby.Dlna/Main/DlnaEntryPoint.cs b/Emby.Dlna/Main/DlnaEntryPoint.cs
index 3dd36a27b..5eeab3dec 100644
--- a/Emby.Dlna/Main/DlnaEntryPoint.cs
+++ b/Emby.Dlna/Main/DlnaEntryPoint.cs
@@ -24,6 +24,7 @@ using MediaBrowser.Model.System;
using MediaBrowser.Model.Threading;
using Rssdp;
using Rssdp.Infrastructure;
+using System.Threading;
namespace Emby.Dlna.Main
{
@@ -252,7 +253,7 @@ namespace Emby.Dlna.Main
var cacheLength = _config.GetDlnaConfiguration().BlastAliveMessageIntervalSeconds;
_Publisher.SupportPnpRootDevice = false;
- var addresses = (await _appHost.GetLocalIpAddresses().ConfigureAwait(false)).ToList();
+ var addresses = (await _appHost.GetLocalIpAddresses(CancellationToken.None).ConfigureAwait(false)).ToList();
var udn = CreateUuid(_appHost.SystemId);
diff --git a/Emby.Dlna/PlayTo/Device.cs b/Emby.Dlna/PlayTo/Device.cs
index 165f123f1..a617117f3 100644
--- a/Emby.Dlna/PlayTo/Device.cs
+++ b/Emby.Dlna/PlayTo/Device.cs
@@ -831,7 +831,7 @@ namespace Emby.Dlna.PlayTo
#region From XML
- private async Task GetAVProtocolAsync()
+ private async Task GetAVProtocolAsync(CancellationToken cancellationToken)
{
if (_disposed)
{
@@ -845,12 +845,12 @@ namespace Emby.Dlna.PlayTo
string url = NormalizeUrl(Properties.BaseUrl, avService.ScpdUrl);
var httpClient = new SsdpHttpClient(_httpClient, _config);
- var document = await httpClient.GetDataAsync(url).ConfigureAwait(false);
+ var document = await httpClient.GetDataAsync(url, cancellationToken).ConfigureAwait(false);
AvCommands = TransportCommands.Create(document);
}
- private async Task GetRenderingProtocolAsync()
+ private async Task GetRenderingProtocolAsync(CancellationToken cancellationToken)
{
if (_disposed)
{
@@ -864,7 +864,7 @@ namespace Emby.Dlna.PlayTo
string url = NormalizeUrl(Properties.BaseUrl, avService.ScpdUrl);
var httpClient = new SsdpHttpClient(_httpClient, _config);
- var document = await httpClient.GetDataAsync(url).ConfigureAwait(false);
+ var document = await httpClient.GetDataAsync(url, cancellationToken).ConfigureAwait(false);
RendererCommands = TransportCommands.Create(document);
}
@@ -897,11 +897,11 @@ namespace Emby.Dlna.PlayTo
set;
}
- public static async Task<Device> CreateuPnpDeviceAsync(Uri url, IHttpClient httpClient, IServerConfigurationManager config, ILogger logger, ITimerFactory timerFactory)
+ public static async Task<Device> CreateuPnpDeviceAsync(Uri url, IHttpClient httpClient, IServerConfigurationManager config, ILogger logger, ITimerFactory timerFactory, CancellationToken cancellationToken)
{
var ssdpHttpClient = new SsdpHttpClient(httpClient, config);
- var document = await ssdpHttpClient.GetDataAsync(url.ToString()).ConfigureAwait(false);
+ var document = await ssdpHttpClient.GetDataAsync(url.ToString(), cancellationToken).ConfigureAwait(false);
var deviceProperties = new DeviceInfo();
@@ -987,8 +987,8 @@ namespace Emby.Dlna.PlayTo
if (device.GetAvTransportService() != null)
{
- await device.GetRenderingProtocolAsync().ConfigureAwait(false);
- await device.GetAVProtocolAsync().ConfigureAwait(false);
+ await device.GetRenderingProtocolAsync(cancellationToken).ConfigureAwait(false);
+ await device.GetAVProtocolAsync(cancellationToken).ConfigureAwait(false);
}
return device;
diff --git a/Emby.Dlna/PlayTo/PlayToManager.cs b/Emby.Dlna/PlayTo/PlayToManager.cs
index dd30dfc3d..f1b7181dd 100644
--- a/Emby.Dlna/PlayTo/PlayToManager.cs
+++ b/Emby.Dlna/PlayTo/PlayToManager.cs
@@ -18,6 +18,7 @@ using MediaBrowser.Model.Events;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Threading;
+using System.Threading;
namespace Emby.Dlna.PlayTo
{
@@ -44,6 +45,8 @@ namespace Emby.Dlna.PlayTo
private readonly List<string> _nonRendererUrls = new List<string>();
private DateTime _lastRendererClear;
private bool _disposed;
+ private SemaphoreSlim _sessionLock = new SemaphoreSlim(1, 1);
+ private CancellationTokenSource _disposeCancellationTokenSource = new CancellationTokenSource();
public PlayToManager(ILogger logger, ISessionManager sessionManager, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, IServerApplicationHost appHost, IImageProcessor imageProcessor, IDeviceDiscovery deviceDiscovery, IHttpClient httpClient, IServerConfigurationManager config, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, IMediaEncoder mediaEncoder, ITimerFactory timerFactory)
{
@@ -98,92 +101,104 @@ namespace Emby.Dlna.PlayTo
return;
}
+ var cancellationToken = _disposeCancellationTokenSource.Token;
+
+ await _sessionLock.WaitAsync(cancellationToken).ConfigureAwait(false);
+
try
{
- lock (_nonRendererUrls)
+ if (_disposed)
{
- if ((DateTime.UtcNow - _lastRendererClear).TotalMinutes >= 10)
- {
- _nonRendererUrls.Clear();
- _lastRendererClear = DateTime.UtcNow;
- }
-
- if (_nonRendererUrls.Contains(location, StringComparer.OrdinalIgnoreCase))
- {
- return;
- }
+ return;
}
- var uri = info.Location;
- _logger.Debug("Attempting to create PlayToController from location {0}", location);
- var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger, _timerFactory).ConfigureAwait(false);
+ await AddDevice(info, location, cancellationToken).ConfigureAwait(false);
+ }
+ catch (OperationCanceledException)
+ {
+
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error creating PlayTo device.", ex);
+
+ _nonRendererUrls.Add(location);
+ }
+ finally
+ {
+ _sessionLock.Release();
+ }
+ }
+
+ private async Task AddDevice(UpnpDeviceInfo info, string location, CancellationToken cancellationToken)
+ {
+ if ((DateTime.UtcNow - _lastRendererClear).TotalMinutes >= 10)
+ {
+ _nonRendererUrls.Clear();
+ _lastRendererClear = DateTime.UtcNow;
+ }
+
+ if (_nonRendererUrls.Contains(location, StringComparer.OrdinalIgnoreCase))
+ {
+ return;
+ }
+
+ var uri = info.Location;
+ _logger.Debug("Attempting to create PlayToController from location {0}", location);
+ var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger, _timerFactory, cancellationToken).ConfigureAwait(false);
+
+ if (device.RendererCommands == null)
+ {
+ _nonRendererUrls.Add(location);
+ return;
+ }
+
+ _logger.Debug("Logging session activity from location {0}", location);
+ var sessionInfo = await _sessionManager.LogSessionActivity(device.Properties.ClientType, _appHost.ApplicationVersion.ToString(), device.Properties.UUID, device.Properties.Name, uri.OriginalString, null).ConfigureAwait(false);
+
+ var controller = sessionInfo.SessionController as PlayToController;
- if (device.RendererCommands == null)
+ if (controller == null)
+ {
+ string serverAddress;
+ if (info.LocalIpAddress == null || info.LocalIpAddress.Equals(IpAddressInfo.Any) || info.LocalIpAddress.Equals(IpAddressInfo.IPv6Loopback))
{
- lock (_nonRendererUrls)
- {
- _nonRendererUrls.Add(location);
- return;
- }
+ serverAddress = await GetServerAddress(null, cancellationToken).ConfigureAwait(false);
}
-
- if (_disposed)
+ else
{
- return;
+ serverAddress = await GetServerAddress(info.LocalIpAddress, cancellationToken).ConfigureAwait(false);
}
- _logger.Debug("Logging session activity from location {0}", location);
- var sessionInfo = await _sessionManager.LogSessionActivity(device.Properties.ClientType, _appHost.ApplicationVersion.ToString(), device.Properties.UUID, device.Properties.Name, uri.OriginalString, null)
- .ConfigureAwait(false);
-
- var controller = sessionInfo.SessionController as PlayToController;
-
- if (controller == null)
+ string accessToken = null;
+
+ sessionInfo.SessionController = controller = new PlayToController(sessionInfo,
+ _sessionManager,
+ _libraryManager,
+ _logger,
+ _dlnaManager,
+ _userManager,
+ _imageProcessor,
+ serverAddress,
+ accessToken,
+ _deviceDiscovery,
+ _userDataManager,
+ _localization,
+ _mediaSourceManager,
+ _config,
+ _mediaEncoder);
+
+ controller.Init(device);
+
+ var profile = _dlnaManager.GetProfile(device.Properties.ToDeviceIdentification()) ??
+ _dlnaManager.GetDefaultProfile();
+
+ _sessionManager.ReportCapabilities(sessionInfo.Id, new ClientCapabilities
{
- if (_disposed)
- {
- return;
- }
+ PlayableMediaTypes = profile.GetSupportedMediaTypes(),
- string serverAddress;
- if (info.LocalIpAddress == null || info.LocalIpAddress.Equals(IpAddressInfo.Any) || info.LocalIpAddress.Equals(IpAddressInfo.IPv6Loopback))
+ SupportedCommands = new string[]
{
- serverAddress = await GetServerAddress(null).ConfigureAwait(false);
- }
- else
- {
- serverAddress = await GetServerAddress(info.LocalIpAddress).ConfigureAwait(false);
- }
-
- string accessToken = null;
-
- sessionInfo.SessionController = controller = new PlayToController(sessionInfo,
- _sessionManager,
- _libraryManager,
- _logger,
- _dlnaManager,
- _userManager,
- _imageProcessor,
- serverAddress,
- accessToken,
- _deviceDiscovery,
- _userDataManager,
- _localization,
- _mediaSourceManager,
- _config,
- _mediaEncoder);
-
- controller.Init(device);
-
- var profile = _dlnaManager.GetProfile(device.Properties.ToDeviceIdentification()) ??
- _dlnaManager.GetDefaultProfile();
-
- _sessionManager.ReportCapabilities(sessionInfo.Id, new ClientCapabilities
- {
- PlayableMediaTypes = profile.GetSupportedMediaTypes(),
-
- SupportedCommands = new string[]
- {
GeneralCommandType.VolumeDown.ToString(),
GeneralCommandType.VolumeUp.ToString(),
GeneralCommandType.Mute.ToString(),
@@ -192,33 +207,23 @@ namespace Emby.Dlna.PlayTo
GeneralCommandType.SetVolume.ToString(),
GeneralCommandType.SetAudioStreamIndex.ToString(),
GeneralCommandType.SetSubtitleStreamIndex.ToString()
- },
+ },
- SupportsMediaControl = true,
+ SupportsMediaControl = true,
- // xbox one creates a new uuid everytime it restarts
- SupportsPersistentIdentifier = (device.Properties.ModelName ?? string.Empty).IndexOf("xbox", StringComparison.OrdinalIgnoreCase) == -1
- });
+ // xbox one creates a new uuid everytime it restarts
+ SupportsPersistentIdentifier = (device.Properties.ModelName ?? string.Empty).IndexOf("xbox", StringComparison.OrdinalIgnoreCase) == -1
+ });
- _logger.Info("DLNA Session created for {0} - {1}", device.Properties.Name, device.Properties.ModelName);
- }
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error creating PlayTo device.", ex);
-
- lock (_nonRendererUrls)
- {
- _nonRendererUrls.Add(location);
- }
+ _logger.Info("DLNA Session created for {0} - {1}", device.Properties.Name, device.Properties.ModelName);
}
}
- private Task<string> GetServerAddress(IpAddressInfo address)
+ private Task<string> GetServerAddress(IpAddressInfo address, CancellationToken cancellationToken)
{
if (address == null)
{
- return _appHost.GetLocalApiUrl();
+ return _appHost.GetLocalApiUrl(cancellationToken);
}
return Task.FromResult(_appHost.GetLocalApiUrl(address));
@@ -226,6 +231,15 @@ namespace Emby.Dlna.PlayTo
public void Dispose()
{
+ try
+ {
+ _disposeCancellationTokenSource.Cancel();
+ }
+ catch
+ {
+
+ }
+
_disposed = true;
_deviceDiscovery.DeviceDiscovered -= _deviceDiscovery_DeviceDiscovered;
GC.SuppressFinalize(this);
diff --git a/Emby.Dlna/PlayTo/SsdpHttpClient.cs b/Emby.Dlna/PlayTo/SsdpHttpClient.cs
index 78b688d92..d4b594367 100644
--- a/Emby.Dlna/PlayTo/SsdpHttpClient.cs
+++ b/Emby.Dlna/PlayTo/SsdpHttpClient.cs
@@ -7,6 +7,7 @@ using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
+using System.Threading;
namespace Emby.Dlna.PlayTo
{
@@ -89,7 +90,7 @@ namespace Emby.Dlna.PlayTo
}
}
- public async Task<XDocument> GetDataAsync(string url)
+ public async Task<XDocument> GetDataAsync(string url, CancellationToken cancellationToken)
{
var options = new HttpRequestOptions
{
@@ -99,7 +100,9 @@ namespace Emby.Dlna.PlayTo
BufferContent = false,
// The periodic requests may keep some devices awake
- LogRequestAsDebug = true
+ LogRequestAsDebug = true,
+
+ CancellationToken = cancellationToken
};
options.RequestHeaders["FriendlyName.DLNA.ORG"] = FriendlyName;
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index 531e13123..2e5c4be90 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -1901,9 +1901,9 @@ namespace Emby.Server.Implementations
/// Gets the system status.
/// </summary>
/// <returns>SystemInfo.</returns>
- public async Task<SystemInfo> GetSystemInfo()
+ public async Task<SystemInfo> GetSystemInfo(CancellationToken cancellationToken)
{
- var localAddress = await GetLocalApiUrl().ConfigureAwait(false);
+ var localAddress = await GetLocalApiUrl(cancellationToken).ConfigureAwait(false);
return new SystemInfo
{
@@ -1955,12 +1955,12 @@ namespace Emby.Server.Implementations
get { return Certificate != null || ServerConfigurationManager.Configuration.IsBehindProxy; }
}
- public async Task<string> GetLocalApiUrl()
+ public async Task<string> GetLocalApiUrl(CancellationToken cancellationToken)
{
try
{
// Return the first matched address, if found, or the first known local address
- var address = (await GetLocalIpAddresses().ConfigureAwait(false)).FirstOrDefault(i => !i.Equals(IpAddressInfo.Loopback) && !i.Equals(IpAddressInfo.IPv6Loopback));
+ var address = (await GetLocalIpAddresses(cancellationToken).ConfigureAwait(false)).FirstOrDefault(i => !i.Equals(IpAddressInfo.Loopback) && !i.Equals(IpAddressInfo.IPv6Loopback));
if (address != null)
{
@@ -1994,7 +1994,7 @@ namespace Emby.Server.Implementations
HttpPort.ToString(CultureInfo.InvariantCulture));
}
- public async Task<List<IpAddressInfo>> GetLocalIpAddresses()
+ public async Task<List<IpAddressInfo>> GetLocalIpAddresses(CancellationToken cancellationToken)
{
var addresses = ServerConfigurationManager
.Configuration
@@ -2011,7 +2011,7 @@ namespace Emby.Server.Implementations
foreach (var address in addresses)
{
- var valid = await IsIpAddressValidAsync(address).ConfigureAwait(false);
+ var valid = await IsIpAddressValidAsync(address, cancellationToken).ConfigureAwait(false);
if (valid)
{
list.Add(address);
@@ -2043,7 +2043,7 @@ namespace Emby.Server.Implementations
private readonly ConcurrentDictionary<string, bool> _validAddressResults = new ConcurrentDictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
private DateTime _lastAddressCacheClear;
- private async Task<bool> IsIpAddressValidAsync(IpAddressInfo address)
+ private async Task<bool> IsIpAddressValidAsync(IpAddressInfo address, CancellationToken cancellationToken)
{
if (address.Equals(IpAddressInfo.Loopback) ||
address.Equals(IpAddressInfo.IPv6Loopback))
@@ -2075,7 +2075,9 @@ namespace Emby.Server.Implementations
LogErrors = false,
LogRequest = false,
TimeoutMs = 30000,
- BufferContent = false
+ BufferContent = false,
+
+ CancellationToken = cancellationToken
}, "POST").ConfigureAwait(false))
{
@@ -2090,6 +2092,10 @@ namespace Emby.Server.Implementations
}
}
}
+ catch (OperationCanceledException)
+ {
+ throw;
+ }
catch
{
//Logger.Debug("Ping test result to {0}. Success: {1}", apiUrl, false);
diff --git a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
index 2cef46839..903bb0ff4 100644
--- a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
+++ b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
@@ -13,6 +13,7 @@ using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Threading;
using Mono.Nat;
using MediaBrowser.Model.Extensions;
+using System.Threading;
namespace Emby.Server.Implementations.EntryPoints
{
@@ -158,7 +159,7 @@ namespace Emby.Server.Implementations.EntryPoints
try
{
- var localAddressString = await _appHost.GetLocalApiUrl().ConfigureAwait(false);
+ var localAddressString = await _appHost.GetLocalApiUrl(CancellationToken.None).ConfigureAwait(false);
Uri uri;
if (Uri.TryCreate(localAddressString, UriKind.Absolute, out uri))
diff --git a/Emby.Server.Implementations/Library/SearchEngine.cs b/Emby.Server.Implementations/Library/SearchEngine.cs
index df21c1409..8021399bd 100644
--- a/Emby.Server.Implementations/Library/SearchEngine.cs
+++ b/Emby.Server.Implementations/Library/SearchEngine.cs
@@ -191,7 +191,8 @@ namespace Emby.Server.Implementations.Library
{
ItemFields.AirTime,
ItemFields.DateCreated,
- ItemFields.ChannelInfo
+ ItemFields.ChannelInfo,
+ ItemFields.ParentId
}
}
};
diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs
index c4e75add8..71c953b2c 100644
--- a/Emby.Server.Implementations/Library/UserManager.cs
+++ b/Emby.Server.Implementations/Library/UserManager.cs
@@ -815,7 +815,7 @@ namespace Emby.Server.Implementations.Library
var text = new StringBuilder();
- var localAddress = _appHost.GetLocalApiUrl().Result ?? string.Empty;
+ var localAddress = _appHost.GetLocalApiUrl(CancellationToken.None).Result ?? string.Empty;
text.AppendLine("Use your web browser to visit:");
text.AppendLine(string.Empty);
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
index ed8b3074b..29b7c41ef 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
+++ b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
@@ -95,7 +95,7 @@ namespace Emby.Server.Implementations.LiveTv
}
var list = sources.ToList();
- var serverUrl = await _appHost.GetLocalApiUrl().ConfigureAwait(false);
+ var serverUrl = await _appHost.GetLocalApiUrl(cancellationToken).ConfigureAwait(false);
foreach (var source in list)
{
diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs
index fbdb5c128..d938359e9 100644
--- a/Emby.Server.Implementations/Networking/NetworkManager.cs
+++ b/Emby.Server.Implementations/Networking/NetworkManager.cs
@@ -11,6 +11,7 @@ using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Net;
+using System.Threading;
namespace Emby.Server.Implementations.Networking
{
@@ -37,7 +38,7 @@ namespace Emby.Server.Implementations.Networking
if (_localIpAddresses == null || forceRefresh)
{
- var addresses = GetLocalIpAddressesInternal().Select(ToIpAddressInfo).ToList();
+ var addresses = GetLocalIpAddressesInternal().Result.Select(ToIpAddressInfo).ToList();
_localIpAddresses = addresses;
_lastRefresh = DateTime.UtcNow;
@@ -49,14 +50,14 @@ namespace Emby.Server.Implementations.Networking
return _localIpAddresses;
}
- private IEnumerable<IPAddress> GetLocalIpAddressesInternal()
+ private async Task<List<IPAddress>> GetLocalIpAddressesInternal()
{
var list = GetIPsDefault()
.ToList();
if (list.Count == 0)
{
- list.AddRange(GetLocalIpAddressesFallback().Result);
+ list.AddRange(await GetLocalIpAddressesFallback().ConfigureAwait(false));
}
var listClone = list.ToList();
@@ -65,7 +66,8 @@ namespace Emby.Server.Implementations.Networking
.OrderBy(i => i.AddressFamily == AddressFamily.InterNetwork ? 0 : 1)
.ThenBy(i => listClone.IndexOf(i))
.Where(FilterIpAddress)
- .DistinctBy(i => i.ToString());
+ .DistinctBy(i => i.ToString())
+ .ToList();
}
private bool FilterIpAddress(IPAddress address)
diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs
index 411781b25..f49251da5 100644
--- a/Emby.Server.Implementations/Session/SessionManager.cs
+++ b/Emby.Server.Implementations/Session/SessionManager.cs
@@ -1182,7 +1182,7 @@ namespace Emby.Server.Implementations.Session
{
var sessions = Sessions.Where(i => i.IsActive && i.SessionController != null).ToList();
- var info = await _appHost.GetSystemInfo().ConfigureAwait(false);
+ var info = await _appHost.GetSystemInfo(cancellationToken).ConfigureAwait(false);
var tasks = sessions.Select(session => Task.Run(async () =>
{
diff --git a/Emby.Server.Implementations/Social/SharingManager.cs b/Emby.Server.Implementations/Social/SharingManager.cs
index 57cf93948..e94b9100a 100644
--- a/Emby.Server.Implementations/Social/SharingManager.cs
+++ b/Emby.Server.Implementations/Social/SharingManager.cs
@@ -5,6 +5,7 @@ using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Social;
using System;
+using System.Threading;
using System.Threading.Tasks;
namespace Emby.Server.Implementations.Social
@@ -42,7 +43,7 @@ namespace Emby.Server.Implementations.Social
throw new ResourceNotFoundException();
}
- var externalUrl = (await _appHost.GetSystemInfo().ConfigureAwait(false)).WanAddress;
+ var externalUrl = (await _appHost.GetSystemInfo(CancellationToken.None).ConfigureAwait(false)).WanAddress;
if (string.IsNullOrWhiteSpace(externalUrl))
{
@@ -73,7 +74,7 @@ namespace Emby.Server.Implementations.Social
{
var info = _repository.GetShareInfo(id);
- AddShareInfo(info, _appHost.GetSystemInfo().Result.WanAddress);
+ AddShareInfo(info, _appHost.GetSystemInfo(CancellationToken.None).Result.WanAddress);
return info;
}
diff --git a/Emby.Server.Implementations/Udp/UdpServer.cs b/Emby.Server.Implementations/Udp/UdpServer.cs
index 8dc1fae4b..28de80da1 100644
--- a/Emby.Server.Implementations/Udp/UdpServer.cs
+++ b/Emby.Server.Implementations/Udp/UdpServer.cs
@@ -25,7 +25,7 @@ namespace Emby.Server.Implementations.Udp
private bool _isDisposed;
- private readonly List<Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, Task>>> _responders = new List<Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, Task>>>();
+ private readonly List<Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, CancellationToken, Task>>> _responders = new List<Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, CancellationToken, Task>>>();
private readonly IServerApplicationHost _appHost;
private readonly IJsonSerializer _json;
@@ -44,9 +44,9 @@ namespace Emby.Server.Implementations.Udp
AddMessageResponder("who is MediaBrowserServer_v2?", false, RespondToV2Message);
}
- private void AddMessageResponder(string message, bool isSubstring, Func<string, IpEndPointInfo, Encoding, Task> responder)
+ private void AddMessageResponder(string message, bool isSubstring, Func<string, IpEndPointInfo, Encoding, CancellationToken, Task> responder)
{
- _responders.Add(new Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, Task>>(message, isSubstring, responder));
+ _responders.Add(new Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, CancellationToken, Task>>(message, isSubstring, responder));
}
/// <summary>
@@ -67,9 +67,15 @@ namespace Emby.Server.Implementations.Udp
if (responder != null)
{
+ var cancellationToken = CancellationToken.None;
+
try
{
- await responder.Item2.Item3(responder.Item1, message.RemoteEndPoint, encoding).ConfigureAwait(false);
+ await responder.Item2.Item3(responder.Item1, message.RemoteEndPoint, encoding, cancellationToken).ConfigureAwait(false);
+ }
+ catch (OperationCanceledException)
+ {
+
}
catch (Exception ex)
{
@@ -78,7 +84,7 @@ namespace Emby.Server.Implementations.Udp
}
}
- private Tuple<string, Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, Task>>> GetResponder(byte[] buffer, int bytesReceived, Encoding encoding)
+ private Tuple<string, Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, CancellationToken, Task>>> GetResponder(byte[] buffer, int bytesReceived, Encoding encoding)
{
var text = encoding.GetString(buffer, 0, bytesReceived);
var responder = _responders.FirstOrDefault(i =>
@@ -94,14 +100,14 @@ namespace Emby.Server.Implementations.Udp
{
return null;
}
- return new Tuple<string, Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, Task>>>(text, responder);
+ return new Tuple<string, Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, CancellationToken, Task>>>(text, responder);
}
- private async Task RespondToV2Message(string messageText, IpEndPointInfo endpoint, Encoding encoding)
+ private async Task RespondToV2Message(string messageText, IpEndPointInfo endpoint, Encoding encoding, CancellationToken cancellationToken)
{
var parts = messageText.Split('|');
- var localUrl = await _appHost.GetLocalApiUrl().ConfigureAwait(false);
+ var localUrl = await _appHost.GetLocalApiUrl(cancellationToken).ConfigureAwait(false);
if (!string.IsNullOrEmpty(localUrl))
{
@@ -112,7 +118,7 @@ namespace Emby.Server.Implementations.Udp
Name = _appHost.FriendlyName
};
- await SendAsync(encoding.GetBytes(_json.SerializeToString(response)), endpoint).ConfigureAwait(false);
+ await SendAsync(encoding.GetBytes(_json.SerializeToString(response)), endpoint, cancellationToken).ConfigureAwait(false);
if (parts.Length > 1)
{
@@ -248,7 +254,7 @@ namespace Emby.Server.Implementations.Udp
}
}
- public async Task SendAsync(byte[] bytes, IpEndPointInfo remoteEndPoint)
+ public async Task SendAsync(byte[] bytes, IpEndPointInfo remoteEndPoint, CancellationToken cancellationToken)
{
if (_isDisposed)
{
@@ -267,7 +273,7 @@ namespace Emby.Server.Implementations.Udp
try
{
- await _udpClient.SendToAsync(bytes, 0, bytes.Length, remoteEndPoint, CancellationToken.None).ConfigureAwait(false);
+ await _udpClient.SendToAsync(bytes, 0, bytes.Length, remoteEndPoint, cancellationToken).ConfigureAwait(false);
_logger.Info("Udp message sent to {0}", remoteEndPoint);
}
diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs
index 69ce6a385..2d30625a9 100644
--- a/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs
+++ b/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs
@@ -3,9 +3,10 @@ using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Tasks;
using System.Collections.Generic;
using System.Linq;
-using System.Threading.Tasks;
+using System.Threading;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Threading;
+using System.Threading.Tasks;
namespace MediaBrowser.Api.ScheduledTasks
{
@@ -63,7 +64,7 @@ namespace MediaBrowser.Api.ScheduledTasks
/// </summary>
/// <param name="state">The state.</param>
/// <returns>Task{IEnumerable{TaskInfo}}.</returns>
- protected override Task<IEnumerable<TaskInfo>> GetDataToSend(WebSocketListenerState state)
+ protected override Task<IEnumerable<TaskInfo>> GetDataToSend(WebSocketListenerState state, CancellationToken cancellationToken)
{
return Task.FromResult(TaskManager.ScheduledTasks
.OrderBy(i => i.Name)
diff --git a/MediaBrowser.Api/SearchService.cs b/MediaBrowser.Api/SearchService.cs
index ad79ea57b..50033eee8 100644
--- a/MediaBrowser.Api/SearchService.cs
+++ b/MediaBrowser.Api/SearchService.cs
@@ -248,9 +248,20 @@ namespace MediaBrowser.Api
if (song != null)
{
- result.Album = song.Album;
result.AlbumArtist = song.AlbumArtists.FirstOrDefault();
result.Artists = song.Artists;
+
+ album = song.AlbumEntity;
+
+ if (album != null)
+ {
+ result.Album = album.Name;
+ result.AlbumId = album.Id.ToString("N");
+ }
+ else
+ {
+ result.Album = song.Album;
+ }
}
if (!string.IsNullOrWhiteSpace(item.ChannelId))
diff --git a/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs b/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs
index e133a88a1..65c69fc7d 100644
--- a/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs
+++ b/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs
@@ -5,8 +5,9 @@ using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Session;
using System.Collections.Generic;
using System.Linq;
-using System.Threading.Tasks;
+using System.Threading;
using MediaBrowser.Model.Threading;
+using System.Threading.Tasks;
namespace MediaBrowser.Api.Session
{
@@ -86,7 +87,7 @@ namespace MediaBrowser.Api.Session
/// </summary>
/// <param name="state">The state.</param>
/// <returns>Task{SystemInfo}.</returns>
- protected override Task<IEnumerable<SessionInfoDto>> GetDataToSend(WebSocketListenerState state)
+ protected override Task<IEnumerable<SessionInfoDto>> GetDataToSend(WebSocketListenerState state, CancellationToken cancellationToken)
{
return Task.FromResult(_sessionManager.Sessions.Where(i => i.IsActive).Select(_sessionManager.GetSessionInfoDto));
}
diff --git a/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs b/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs
index 793f74571..f9cac7389 100644
--- a/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs
+++ b/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs
@@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Threading.Tasks;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Threading;
+using System.Threading;
namespace MediaBrowser.Api.System
{
@@ -43,7 +44,7 @@ namespace MediaBrowser.Api.System
/// </summary>
/// <param name="state">The state.</param>
/// <returns>Task{SystemInfo}.</returns>
- protected override Task<List<ActivityLogEntry>> GetDataToSend(WebSocketListenerState state)
+ protected override Task<List<ActivityLogEntry>> GetDataToSend(WebSocketListenerState state, CancellationToken CancellationToken)
{
return Task.FromResult(new List<ActivityLogEntry>());
}
diff --git a/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs b/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs
index 8d74cc66c..63847f2b5 100644
--- a/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs
+++ b/MediaBrowser.Api/System/SystemInfoWebSocketListener.cs
@@ -4,6 +4,7 @@ using MediaBrowser.Model.Logging;
using MediaBrowser.Model.System;
using System.Threading.Tasks;
using MediaBrowser.Model.Threading;
+using System.Threading;
namespace MediaBrowser.Api.System
{
@@ -40,9 +41,9 @@ namespace MediaBrowser.Api.System
/// </summary>
/// <param name="state">The state.</param>
/// <returns>Task{SystemInfo}.</returns>
- protected override Task<SystemInfo> GetDataToSend(WebSocketListenerState state)
+ protected override Task<SystemInfo> GetDataToSend(WebSocketListenerState state, CancellationToken cancellationToken)
{
- return _appHost.GetSystemInfo();
+ return _appHost.GetSystemInfo(cancellationToken);
}
}
}
diff --git a/MediaBrowser.Api/System/SystemService.cs b/MediaBrowser.Api/System/SystemService.cs
index d850b2ce7..6de7dd98b 100644
--- a/MediaBrowser.Api/System/SystemService.cs
+++ b/MediaBrowser.Api/System/SystemService.cs
@@ -14,6 +14,7 @@ using MediaBrowser.Controller.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Services;
+using System.Threading;
namespace MediaBrowser.Api.System
{
@@ -164,14 +165,14 @@ namespace MediaBrowser.Api.System
/// <returns>System.Object.</returns>
public async Task<object> Get(GetSystemInfo request)
{
- var result = await _appHost.GetSystemInfo().ConfigureAwait(false);
+ var result = await _appHost.GetSystemInfo(CancellationToken.None).ConfigureAwait(false);
return ToOptimizedResult(result);
}
public async Task<object> Get(GetPublicSystemInfo request)
{
- var result = await _appHost.GetSystemInfo().ConfigureAwait(false);
+ var result = await _appHost.GetSystemInfo(CancellationToken.None).ConfigureAwait(false);
var publicInfo = new PublicSystemInfo
{
diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs
index e9f7d5932..380be068e 100644
--- a/MediaBrowser.Controller/IServerApplicationHost.cs
+++ b/MediaBrowser.Controller/IServerApplicationHost.cs
@@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using MediaBrowser.Model.Net;
+using System.Threading;
namespace MediaBrowser.Controller
{
@@ -19,7 +20,7 @@ namespace MediaBrowser.Controller
/// Gets the system info.
/// </summary>
/// <returns>SystemInfo.</returns>
- Task<SystemInfo> GetSystemInfo();
+ Task<SystemInfo> GetSystemInfo(CancellationToken cancellationToken);
/// <summary>
/// Gets a value indicating whether [supports automatic run at startup].
@@ -61,13 +62,13 @@ namespace MediaBrowser.Controller
/// Gets the local ip address.
/// </summary>
/// <value>The local ip address.</value>
- Task<List<IpAddressInfo>> GetLocalIpAddresses();
+ Task<List<IpAddressInfo>> GetLocalIpAddresses(CancellationToken cancellationToken);
/// <summary>
/// Gets the local API URL.
/// </summary>
/// <value>The local API URL.</value>
- Task<string> GetLocalApiUrl();
+ Task<string> GetLocalApiUrl(CancellationToken cancellationToken);
/// <summary>
/// Gets the local API URL.
diff --git a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs
index 6be94e7e6..17b82b3ca 100644
--- a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs
+++ b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs
@@ -36,7 +36,7 @@ namespace MediaBrowser.Controller.Net
/// </summary>
/// <param name="state">The state.</param>
/// <returns>Task{`1}.</returns>
- protected abstract Task<TReturnDataType> GetDataToSend(TStateType state);
+ protected abstract Task<TReturnDataType> GetDataToSend(TStateType state, CancellationToken cancellationToken);
/// <summary>
/// The logger
@@ -209,7 +209,9 @@ namespace MediaBrowser.Controller.Net
{
var state = tuple.Item4;
- var data = await GetDataToSend(state).ConfigureAwait(false);
+ var cancellationToken = tuple.Item2.Token;
+
+ var data = await GetDataToSend(state, cancellationToken).ConfigureAwait(false);
if (data != null)
{
@@ -218,7 +220,7 @@ namespace MediaBrowser.Controller.Net
MessageType = Name,
Data = data
- }, tuple.Item2.Token).ConfigureAwait(false);
+ }, cancellationToken).ConfigureAwait(false);
state.DateLastSendUtc = DateTime.UtcNow;
}
diff --git a/MediaBrowser.Controller/Sync/ISyncManager.cs b/MediaBrowser.Controller/Sync/ISyncManager.cs
index 0bf4b914f..5e9085a40 100644
--- a/MediaBrowser.Controller/Sync/ISyncManager.cs
+++ b/MediaBrowser.Controller/Sync/ISyncManager.cs
@@ -29,7 +29,7 @@ namespace MediaBrowser.Controller.Sync
/// Gets the jobs.
/// </summary>
/// <returns>QueryResult&lt;SyncJob&gt;.</returns>
- Task<QueryResult<SyncJob>> GetJobs(SyncJobQuery query);
+ QueryResult<SyncJob> GetJobs(SyncJobQuery query);
/// <summary>
/// Gets the job items.
diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs
index 37d266ac0..2da6f1c81 100644
--- a/MediaBrowser.Model/Dlna/StreamBuilder.cs
+++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs
@@ -1343,7 +1343,7 @@ namespace MediaBrowser.Model.Dlna
if (itemBitrate > requestedMaxBitrate)
{
- _logger.Info("Bitrate exceeds " + playMethod + " limit: media bitrate: {0}, max bitrate: {1}", item.Bitrate.Value.ToString(CultureInfo.InvariantCulture), requestedMaxBitrate.ToString(CultureInfo.InvariantCulture));
+ _logger.Info("Bitrate exceeds " + playMethod + " limit: media bitrate: {0}, max bitrate: {1}", itemBitrate.ToString(CultureInfo.InvariantCulture), requestedMaxBitrate.ToString(CultureInfo.InvariantCulture));
return false;
}
diff --git a/MediaBrowser.Model/Search/SearchHint.cs b/MediaBrowser.Model/Search/SearchHint.cs
index 5c5637481..f2617c909 100644
--- a/MediaBrowser.Model/Search/SearchHint.cs
+++ b/MediaBrowser.Model/Search/SearchHint.cs
@@ -107,6 +107,7 @@ namespace MediaBrowser.Model.Search
/// </summary>
/// <value>The album.</value>
public string Album { get; set; }
+ public string AlbumId { get; set; }
/// <summary>
/// Gets or sets the album artist.
diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs
index f55d95a2e..5fd94e0d7 100644
--- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs
+++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs
@@ -200,7 +200,16 @@ namespace MediaBrowser.WebDashboard.Api
sb.Append("<link rel=\"manifest\" href=\"manifest.json\">");
sb.Append("<meta name=\"format-detection\" content=\"telephone=no\">");
sb.Append("<meta name=\"msapplication-tap-highlight\" content=\"no\">");
- sb.Append("<meta name=\"viewport\" content=\"user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width\">");
+
+ if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase))
+ {
+ sb.Append("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no\">");
+ }
+ else
+ {
+ sb.Append("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1\">");
+ }
+
sb.Append("<meta name=\"apple-mobile-web-app-capable\" content=\"yes\">");
sb.Append("<meta name=\"mobile-web-app-capable\" content=\"yes\">");
sb.Append("<meta name=\"application-name\" content=\"Emby\">");
diff --git a/SharedVersion.cs b/SharedVersion.cs
index 99dc764df..463ec3ae3 100644
--- a/SharedVersion.cs
+++ b/SharedVersion.cs
@@ -1,3 +1,3 @@
using System.Reflection;
-[assembly: AssemblyVersion("3.2.40.1")]
+[assembly: AssemblyVersion("3.2.40.2")]