|
@@ -8,6 +8,7 @@ using System.Text;
|
|
|
using System.Threading;
|
|
|
using System.Threading.Tasks;
|
|
|
using MediaBrowser.Model.Threading;
|
|
|
+using RSSDP;
|
|
|
|
|
|
namespace Rssdp.Infrastructure
|
|
|
{
|
|
@@ -28,14 +29,6 @@ namespace Rssdp.Infrastructure
|
|
|
private ITimer _ExpireCachedDevicesTimer;
|
|
|
private ITimerFactory _timerFactory;
|
|
|
|
|
|
- private const string HttpURequestMessageFormat = @"{0} * HTTP/1.1
|
|
|
-HOST: {1}:{2}
|
|
|
-MAN: ""{3}""
|
|
|
-MX: {5}
|
|
|
-ST: {4}
|
|
|
-
|
|
|
-";
|
|
|
-
|
|
|
private static readonly TimeSpan DefaultSearchWaitTime = TimeSpan.FromSeconds(4);
|
|
|
private static readonly TimeSpan OneSecond = TimeSpan.FromSeconds(1);
|
|
|
|
|
@@ -166,21 +159,16 @@ ST: {4}
|
|
|
if (searchWaitTime > TimeSpan.Zero)
|
|
|
await BroadcastDiscoverMessage(searchTarget, SearchTimeToMXValue(searchWaitTime)).ConfigureAwait(false);
|
|
|
|
|
|
- await Task.Run(() =>
|
|
|
+ lock (_SearchResultsSynchroniser)
|
|
|
{
|
|
|
- lock (_SearchResultsSynchroniser)
|
|
|
+ foreach (var device in GetUnexpiredDevices().Where(NotificationTypeMatchesFilter))
|
|
|
{
|
|
|
- foreach (var device in GetUnexpiredDevices().Where((d) => NotificationTypeMatchesFilter(d)))
|
|
|
- {
|
|
|
- if (this.IsDisposed) return;
|
|
|
-
|
|
|
- DeviceFound(device, false);
|
|
|
- }
|
|
|
+ DeviceFound(device, false);
|
|
|
}
|
|
|
- }).ConfigureAwait(false);
|
|
|
+ }
|
|
|
|
|
|
if (searchWaitTime != TimeSpan.Zero)
|
|
|
- await Task.Delay(searchWaitTime);
|
|
|
+ await Task.Delay(searchWaitTime).ConfigureAwait(false);
|
|
|
|
|
|
IEnumerable<DiscoveredSsdpDevice> retVal = null;
|
|
|
|
|
@@ -192,7 +180,7 @@ ST: {4}
|
|
|
_SearchResults = null;
|
|
|
}
|
|
|
|
|
|
- var expireTask = RemoveExpiredDevicesFromCacheAsync();
|
|
|
+ RemoveExpiredDevicesFromCache();
|
|
|
}
|
|
|
finally
|
|
|
{
|
|
@@ -417,25 +405,27 @@ ST: {4}
|
|
|
|
|
|
#region Network Message Processing
|
|
|
|
|
|
- private static byte[] BuildDiscoverMessage(string serviceType, TimeSpan mxValue)
|
|
|
- {
|
|
|
- return System.Text.UTF8Encoding.UTF8.GetBytes(
|
|
|
- String.Format(HttpURequestMessageFormat,
|
|
|
- SsdpConstants.MSearchMethod,
|
|
|
- SsdpConstants.MulticastLocalAdminAddress,
|
|
|
- SsdpConstants.MulticastPort,
|
|
|
- SsdpConstants.SsdpDiscoverMessage,
|
|
|
- serviceType,
|
|
|
- mxValue.TotalSeconds
|
|
|
- )
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
private Task BroadcastDiscoverMessage(string serviceType, TimeSpan mxValue)
|
|
|
{
|
|
|
- var broadcastMessage = BuildDiscoverMessage(serviceType, mxValue);
|
|
|
+ var values = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
|
|
- return _CommunicationsServer.SendMulticastMessage(broadcastMessage);
|
|
|
+ values["HOST"] = "239.255.255.250:1900";
|
|
|
+ values["USER-AGENT"] = "UPnP/1.0 DLNADOC/1.50 Platinum/1.0.4.2";
|
|
|
+ //values["X-EMBY-SERVERID"] = _appHost.SystemId;
|
|
|
+
|
|
|
+ values["MAN"] = "\"ssdp:discover\"";
|
|
|
+
|
|
|
+ // Search target
|
|
|
+ values["ST"] = "ssdp:all";
|
|
|
+
|
|
|
+ // Seconds to delay response
|
|
|
+ values["MX"] = "3";
|
|
|
+
|
|
|
+ var header = "M-SEARCH * HTTP/1.1";
|
|
|
+
|
|
|
+ var message = SsdpHelper.BuildMessage(header, values);
|
|
|
+
|
|
|
+ return _CommunicationsServer.SendMulticastMessage(message);
|
|
|
}
|
|
|
|
|
|
private void ProcessSearchResponseMessage(HttpResponseMessage message)
|
|
@@ -608,19 +598,11 @@ ST: {4}
|
|
|
|
|
|
#region Expiry and Device Removal
|
|
|
|
|
|
- private Task RemoveExpiredDevicesFromCacheAsync()
|
|
|
- {
|
|
|
- return Task.Run(() =>
|
|
|
- {
|
|
|
- RemoveExpiredDevicesFromCache();
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
private void RemoveExpiredDevicesFromCache()
|
|
|
{
|
|
|
if (this.IsDisposed) return;
|
|
|
|
|
|
- IEnumerable<DiscoveredSsdpDevice> expiredDevices = null;
|
|
|
+ DiscoveredSsdpDevice[] expiredDevices = null;
|
|
|
lock (_Devices)
|
|
|
{
|
|
|
expiredDevices = (from device in _Devices where device.IsExpired() select device).ToArray();
|