From 0c2eea9c07f4afb4ef1718116cc9dd6d7662b359 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 14 Nov 2016 14:26:51 -0500 Subject: [PATCH 1/7] update DirectRecorder --- .../LiveTv/EmbyTV/DirectRecorder.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs index 6bb06843a3..6d527c1cfb 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs @@ -31,13 +31,12 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV public async Task Record(MediaSourceInfo mediaSource, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken) { - var httpRequestOptions = new HttpRequestOptions() + var httpRequestOptions = new HttpRequestOptions { - Url = mediaSource.Path + Url = mediaSource.Path, + BufferContent = false }; - httpRequestOptions.BufferContent = false; - using (var response = await _httpClient.SendAsync(httpRequestOptions, "GET").ConfigureAwait(false)) { _logger.Info("Opened recording stream from tuner provider"); From fdb67f17840182b7285424f771ac3583398cd5b5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 14 Nov 2016 14:27:21 -0500 Subject: [PATCH 2/7] update HttpListenerResponse --- SocketHttpListener.Portable/Net/HttpListenerResponse.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SocketHttpListener.Portable/Net/HttpListenerResponse.cs b/SocketHttpListener.Portable/Net/HttpListenerResponse.cs index fb3bc2bdb3..880473c0a2 100644 --- a/SocketHttpListener.Portable/Net/HttpListenerResponse.cs +++ b/SocketHttpListener.Portable/Net/HttpListenerResponse.cs @@ -413,8 +413,8 @@ namespace SocketHttpListener.Net * HttpStatusCode.InternalServerError 500 * HttpStatusCode.ServiceUnavailable 503 */ - bool conn_close = (status_code == 400 || status_code == 408 || status_code == 411 || - status_code == 413 || status_code == 414 || status_code == 500 || + bool conn_close = (status_code == 408 || status_code == 411 || + status_code == 413 || status_code == 414 || status_code == 503); if (conn_close == false) From c2e9df41dc288c3a57e98cb8d89c6c49ecb59814 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 14 Nov 2016 14:27:37 -0500 Subject: [PATCH 3/7] fix PathSeparator --- Emby.Common.Implementations/IO/ManagedFileSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emby.Common.Implementations/IO/ManagedFileSystem.cs b/Emby.Common.Implementations/IO/ManagedFileSystem.cs index 83bb50f942..4fb70d4e24 100644 --- a/Emby.Common.Implementations/IO/ManagedFileSystem.cs +++ b/Emby.Common.Implementations/IO/ManagedFileSystem.cs @@ -61,7 +61,7 @@ namespace Emby.Common.Implementations.IO { get { - return Path.DirectorySeparatorChar; + return Path.PathSeparator; } } From 180ab02edc62ad6e73ece198bd2f9887468eb159 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 14 Nov 2016 14:32:43 -0500 Subject: [PATCH 4/7] update msearch --- RSSDP/ISsdpCommunicationsServer.cs | 3 +- RSSDP/RSSDP.csproj | 1 + RSSDP/SsdpDeviceLocator.cs | 2 +- RSSDP/SsdpDeviceLocatorBase.cs | 70 +++++++++--------------- RSSDP/SsdpDevicePublisher.cs | 4 +- RSSDP/SsdpHelper.cs | 88 ++++++++++++++++++++++++++++++ 6 files changed, 119 insertions(+), 49 deletions(-) create mode 100644 RSSDP/SsdpHelper.cs diff --git a/RSSDP/ISsdpCommunicationsServer.cs b/RSSDP/ISsdpCommunicationsServer.cs index b1e84dc9f5..462f33fe67 100644 --- a/RSSDP/ISsdpCommunicationsServer.cs +++ b/RSSDP/ISsdpCommunicationsServer.cs @@ -51,8 +51,7 @@ namespace Rssdp.Infrastructure /// /// Sends a message to the SSDP multicast address and port. /// - /// A byte array containing the data to send. - Task SendMulticastMessage(byte[] messageData); + Task SendMulticastMessage(string message); #endregion diff --git a/RSSDP/RSSDP.csproj b/RSSDP/RSSDP.csproj index fb4d67e1ab..d60f6ea441 100644 --- a/RSSDP/RSSDP.csproj +++ b/RSSDP/RSSDP.csproj @@ -65,6 +65,7 @@ + diff --git a/RSSDP/SsdpDeviceLocator.cs b/RSSDP/SsdpDeviceLocator.cs index 01c96463fe..3ea17237df 100644 --- a/RSSDP/SsdpDeviceLocator.cs +++ b/RSSDP/SsdpDeviceLocator.cs @@ -21,7 +21,7 @@ namespace Rssdp /// Default constructor. Constructs a new instance using the default and implementations for this platform. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification="Can't expose along exception paths here (exceptions should be very rare anyway, and probably fatal too) and we shouldn't dipose the items we pass to base in any other case.")] - public SsdpDeviceLocator(ISocketFactory socketFactory, ITimerFactory timerFacatory) : base(new SsdpCommunicationsServer(socketFactory), timerFacatory) + public SsdpDeviceLocator(ISsdpCommunicationsServer communicationsServer, ITimerFactory timerFacatory) : base(communicationsServer, timerFacatory) { // This is not the problem you are looking for; // Yes, this is poor man's dependency injection which some call an anti-pattern. diff --git a/RSSDP/SsdpDeviceLocatorBase.cs b/RSSDP/SsdpDeviceLocatorBase.cs index ed4c087cda..b6276e4997 100644 --- a/RSSDP/SsdpDeviceLocatorBase.cs +++ b/RSSDP/SsdpDeviceLocatorBase.cs @@ -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 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(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 expiredDevices = null; + DiscoveredSsdpDevice[] expiredDevices = null; lock (_Devices) { expiredDevices = (from device in _Devices where device.IsExpired() select device).ToArray(); diff --git a/RSSDP/SsdpDevicePublisher.cs b/RSSDP/SsdpDevicePublisher.cs index 56f27b3a29..1c17c78372 100644 --- a/RSSDP/SsdpDevicePublisher.cs +++ b/RSSDP/SsdpDevicePublisher.cs @@ -26,8 +26,8 @@ namespace Rssdp /// Uses the default implementation and network settings for Windows and the SSDP specification. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "No way to do this here, and we don't want to dispose it except in the (rare) case of an exception anyway.")] - public SsdpDevicePublisher(ISocketFactory socketFactory, ITimerFactory timerFactory, string osName, string osVersion) - : base(new SsdpCommunicationsServer(socketFactory), timerFactory, osName, osVersion) + public SsdpDevicePublisher(ISsdpCommunicationsServer communicationsServer, ITimerFactory timerFactory, string osName, string osVersion) + : base(communicationsServer, timerFactory, osName, osVersion) { } diff --git a/RSSDP/SsdpHelper.cs b/RSSDP/SsdpHelper.cs new file mode 100644 index 0000000000..2eacf3c11b --- /dev/null +++ b/RSSDP/SsdpHelper.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using MediaBrowser.Model.Net; +using MediaBrowser.Model.Text; + +namespace RSSDP +{ + public class SsdpHelper + { + private readonly ITextEncoding _encoding; + + public SsdpHelper(ITextEncoding encoding) + { + _encoding = encoding; + } + + public SsdpMessageInfo ParseSsdpResponse(byte[] data) + { + using (var ms = new MemoryStream(data)) + { + using (var reader = new StreamReader(ms, _encoding.GetASCIIEncoding())) + { + var proto = (reader.ReadLine() ?? string.Empty).Trim(); + var method = proto.Split(new[] { ' ' }, 2)[0]; + var headers = new Dictionary(StringComparer.OrdinalIgnoreCase); + for (var line = reader.ReadLine(); line != null; line = reader.ReadLine()) + { + line = line.Trim(); + if (string.IsNullOrEmpty(line)) + { + break; + } + var parts = line.Split(new[] { ':' }, 2); + + if (parts.Length >= 2) + { + headers[parts[0]] = parts[1].Trim(); + } + } + + return new SsdpMessageInfo + { + Method = method, + Headers = headers, + Message = data + }; + } + } + } + + public static string BuildMessage(string header, Dictionary values) + { + var builder = new StringBuilder(); + + const string argFormat = "{0}: {1}\r\n"; + + builder.AppendFormat("{0}\r\n", header); + + foreach (var pair in values) + { + builder.AppendFormat(argFormat, pair.Key, pair.Value); + } + + builder.Append("\r\n"); + + return builder.ToString(); + } + } + + public class SsdpMessageInfo + { + public string Method { get; set; } + + public IpEndPointInfo EndPoint { get; set; } + + public Dictionary Headers { get; set; } + + public IpEndPointInfo LocalEndPoint { get; set; } + public byte[] Message { get; set; } + + public SsdpMessageInfo() + { + Headers = new Dictionary(StringComparer.OrdinalIgnoreCase); + } + } +} From 75ae9f2dc15cee4d869ba8d4703d6c7724666e39 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 14 Nov 2016 14:33:15 -0500 Subject: [PATCH 5/7] update message building --- RSSDP/SsdpDevicePublisherBase.cs | 43 ++++++++------------------------ 1 file changed, 11 insertions(+), 32 deletions(-) diff --git a/RSSDP/SsdpDevicePublisherBase.cs b/RSSDP/SsdpDevicePublisherBase.cs index b3c28aab71..7737733f7b 100644 --- a/RSSDP/SsdpDevicePublisherBase.cs +++ b/RSSDP/SsdpDevicePublisherBase.cs @@ -6,6 +6,7 @@ using System.Text; using System.Threading.Tasks; using MediaBrowser.Model.Net; using MediaBrowser.Model.Threading; +using RSSDP; namespace Rssdp.Infrastructure { @@ -344,7 +345,7 @@ namespace Rssdp.Infrastructure values["USN"] = uniqueServiceName; values["LOCATION"] = rootDevice.Location.ToString(); - var message = BuildMessage(header, values); + var message = SsdpHelper.BuildMessage(header, values); try { @@ -384,19 +385,15 @@ namespace Rssdp.Infrastructure return isDuplicateRequest; } - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "t", Justification = "Capturing task to local variable avoids compiler warning, but value is otherwise not required.")] private void CleanUpRecentSearchRequestsAsync() { - var t = Task.Run(() => + lock (_RecentSearchRequests) { - lock (_RecentSearchRequests) + foreach (var requestKey in (from r in _RecentSearchRequests where r.Value.IsOld() select r.Key).ToArray()) { - foreach (var requestKey in (from r in _RecentSearchRequests where r.Value.IsOld() select r.Key).ToArray()) - { - _RecentSearchRequests.Remove(requestKey); - } + _RecentSearchRequests.Remove(requestKey); } - }); + } } #endregion @@ -481,31 +478,13 @@ namespace Rssdp.Infrastructure values["NT"] = notificationType; values["USN"] = uniqueServiceName; - var message = BuildMessage(header, values); + var message = SsdpHelper.BuildMessage(header, values); - _CommsServer.SendMulticastMessage(System.Text.UTF8Encoding.UTF8.GetBytes(message)); + _CommsServer.SendMulticastMessage(message); WriteTrace(String.Format("Sent alive notification"), device); } - private string BuildMessage(string header, Dictionary values) - { - var builder = new StringBuilder(); - - const string argFormat = "{0}: {1}\r\n"; - - builder.AppendFormat("{0}\r\n", header); - - foreach (var pair in values) - { - builder.AppendFormat(argFormat, pair.Key, pair.Value); - } - - builder.Append("\r\n"); - - return builder.ToString(); - } - #endregion #region ByeBye @@ -543,9 +522,9 @@ namespace Rssdp.Infrastructure values["NT"] = notificationType; values["USN"] = uniqueServiceName; - var message = BuildMessage(header, values); + var message = SsdpHelper.BuildMessage(header, values); - return _CommsServer.SendMulticastMessage(System.Text.UTF8Encoding.UTF8.GetBytes(message)); + return _CommsServer.SendMulticastMessage(message); //WriteTrace(String.Format("Sent byebye notification"), device); } @@ -686,7 +665,7 @@ namespace Rssdp.Infrastructure { if (this.IsDisposed) return; - if (e.Message.Method.Method == SsdpConstants.MSearchMethod) + if (string.Equals(e.Message.Method.Method, SsdpConstants.MSearchMethod, StringComparison.OrdinalIgnoreCase)) { //According to SSDP/UPnP spec, ignore message if missing these headers. // Edit: But some devices do it anyway From 44336488f375adcdd5aa696790706b38483381fe Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 14 Nov 2016 14:48:01 -0500 Subject: [PATCH 6/7] update udp sockets --- .../Net/SocketFactory.cs | 1 + Emby.Common.Implementations/Net/UdpSocket.cs | 11 ++----- Emby.Dlna/Main/DlnaEntryPoint.cs | 30 ++++++++++++++----- Emby.Dlna/Ssdp/DeviceDiscovery.cs | 20 +++++-------- RSSDP/SsdpCommunicationsServer.cs | 17 +++++------ 5 files changed, 42 insertions(+), 37 deletions(-) diff --git a/Emby.Common.Implementations/Net/SocketFactory.cs b/Emby.Common.Implementations/Net/SocketFactory.cs index f261376834..c65593242e 100644 --- a/Emby.Common.Implementations/Net/SocketFactory.cs +++ b/Emby.Common.Implementations/Net/SocketFactory.cs @@ -131,6 +131,7 @@ namespace Emby.Common.Implementations.Net #else retVal.ExclusiveAddressUse = false; #endif + //retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true); retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, multicastTimeToLive); retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse(ipAddress), _LocalIP)); diff --git a/Emby.Common.Implementations/Net/UdpSocket.cs b/Emby.Common.Implementations/Net/UdpSocket.cs index eca82034b0..b9b7d8a2db 100644 --- a/Emby.Common.Implementations/Net/UdpSocket.cs +++ b/Emby.Common.Implementations/Net/UdpSocket.cs @@ -63,7 +63,7 @@ namespace Emby.Common.Implementations.Net } }, state); #else - _Socket.BeginReceiveFrom(state.Buffer, 0, state.Buffer.Length, SocketFlags.None, ref state.EndPoint, new AsyncCallback(this.ProcessResponse), state); + _Socket.BeginReceiveFrom(state.Buffer, 0, state.Buffer.Length, SocketFlags.None, ref state.EndPoint, ProcessResponse, state); #endif return tcs.Task; @@ -99,7 +99,7 @@ namespace Emby.Common.Implementations.Net _Socket.EndSend(result); taskSource.TrySetResult(true); } - catch (SocketException ex) + catch (Exception ex) { taskSource.TrySetException(ex); } @@ -200,13 +200,6 @@ namespace Emby.Common.Implementations.Net { state.TaskCompletionSource.SetCanceled(); } - catch (SocketException se) - { - if (se.SocketErrorCode != SocketError.Interrupted && se.SocketErrorCode != SocketError.OperationAborted && se.SocketErrorCode != SocketError.Shutdown) - state.TaskCompletionSource.SetException(se); - else - state.TaskCompletionSource.SetCanceled(); - } catch (Exception ex) { state.TaskCompletionSource.SetException(ex); diff --git a/Emby.Dlna/Main/DlnaEntryPoint.cs b/Emby.Dlna/Main/DlnaEntryPoint.cs index ef27c029dc..49bb9a74f2 100644 --- a/Emby.Dlna/Main/DlnaEntryPoint.cs +++ b/Emby.Dlna/Main/DlnaEntryPoint.cs @@ -55,6 +55,8 @@ namespace Emby.Dlna.Main private readonly ISocketFactory _socketFactory; private readonly IEnvironmentInfo _environmentInfo; + private ISsdpCommunicationsServer _communicationsServer; + public DlnaEntryPoint(IServerConfigurationManager config, ILogManager logManager, IServerApplicationHost appHost, @@ -152,10 +154,18 @@ namespace Emby.Dlna.Main { try { - StartPublishing(); + if (_communicationsServer == null) + { + _communicationsServer = new SsdpCommunicationsServer(_socketFactory) + { + IsShared = true + }; + } + + StartPublishing(_communicationsServer); _ssdpHandlerStarted = true; - StartDeviceDiscovery(); + StartDeviceDiscovery(_communicationsServer); } catch (Exception ex) { @@ -165,20 +175,20 @@ namespace Emby.Dlna.Main private void LogMessage(string msg) { - //_logger.Debug(msg); + _logger.Debug(msg); } - private void StartPublishing() + private void StartPublishing(ISsdpCommunicationsServer communicationsServer) { SsdpDevicePublisherBase.LogFunction = LogMessage; - _Publisher = new SsdpDevicePublisher(_socketFactory, _timerFactory, _environmentInfo.OperatingSystemName, _environmentInfo.OperatingSystemVersion); + _Publisher = new SsdpDevicePublisher(communicationsServer, _timerFactory, _environmentInfo.OperatingSystemName, _environmentInfo.OperatingSystemVersion); } - private void StartDeviceDiscovery() + private void StartDeviceDiscovery(ISsdpCommunicationsServer communicationsServer) { try { - ((DeviceDiscovery)_deviceDiscovery).Start(); + ((DeviceDiscovery)_deviceDiscovery).Start(communicationsServer); } catch (Exception ex) { @@ -374,6 +384,12 @@ namespace Emby.Dlna.Main DisposeDlnaServer(); DisposePlayToManager(); DisposeSsdpHandler(); + + if (_communicationsServer != null) + { + _communicationsServer.Dispose(); + _communicationsServer = null; + } } public void DisposeDlnaServer() diff --git a/Emby.Dlna/Ssdp/DeviceDiscovery.cs b/Emby.Dlna/Ssdp/DeviceDiscovery.cs index 6f58429680..1cd19d010c 100644 --- a/Emby.Dlna/Ssdp/DeviceDiscovery.cs +++ b/Emby.Dlna/Ssdp/DeviceDiscovery.cs @@ -15,6 +15,7 @@ using MediaBrowser.Model.Events; using MediaBrowser.Model.Net; using MediaBrowser.Model.Threading; using Rssdp; +using Rssdp.Infrastructure; namespace Emby.Dlna.Ssdp { @@ -29,7 +30,7 @@ namespace Emby.Dlna.Ssdp public event EventHandler> DeviceDiscovered; public event EventHandler> DeviceLeft; - private SsdpDeviceLocator _DeviceLocator; + private SsdpDeviceLocator _deviceLocator; private readonly ITimerFactory _timerFactory; private readonly ISocketFactory _socketFactory; @@ -45,9 +46,9 @@ namespace Emby.Dlna.Ssdp } // Call this method from somewhere in your code to start the search. - public void BeginSearch() + public void Start(ISsdpCommunicationsServer communicationsServer) { - _DeviceLocator = new SsdpDeviceLocator(_socketFactory, _timerFactory); + _deviceLocator = new SsdpDeviceLocator(communicationsServer, _timerFactory); // (Optional) Set the filter so we only see notifications for devices we care about // (can be any search target value i.e device type, uuid value etc - any value that appears in the @@ -55,8 +56,8 @@ namespace Emby.Dlna.Ssdp //_DeviceLocator.NotificationFilter = "upnp:rootdevice"; // Connect our event handler so we process devices as they are found - _DeviceLocator.DeviceAvailable += deviceLocator_DeviceAvailable; - _DeviceLocator.DeviceUnavailable += _DeviceLocator_DeviceUnavailable; + _deviceLocator.DeviceAvailable += deviceLocator_DeviceAvailable; + _deviceLocator.DeviceUnavailable += _DeviceLocator_DeviceUnavailable; // Perform a search so we don't have to wait for devices to broadcast notifications // again to get any results right away (notifications are broadcast periodically). @@ -72,9 +73,9 @@ namespace Emby.Dlna.Ssdp try { // Enable listening for notifications (optional) - _DeviceLocator.StartListeningForNotifications(); + _deviceLocator.StartListeningForNotifications(); - await _DeviceLocator.SearchAsync().ConfigureAwait(false); + await _deviceLocator.SearchAsync().ConfigureAwait(false); } catch (Exception ex) { @@ -130,11 +131,6 @@ namespace Emby.Dlna.Ssdp EventHelper.FireEventIfNotNull(DeviceLeft, this, args, _logger); } - public void Start() - { - BeginSearch(); - } - public void Dispose() { if (!_disposed) diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs index c0b9c6542d..4de47f3d33 100644 --- a/RSSDP/SsdpCommunicationsServer.cs +++ b/RSSDP/SsdpCommunicationsServer.cs @@ -170,12 +170,11 @@ namespace Rssdp.Infrastructure /// /// Sends a message to the SSDP multicast address and port. /// - /// A byte array containing the data to send. - /// Thrown if the argument is null. - /// Thrown if the property is true (because has been called previously). - public async Task SendMulticastMessage(byte[] messageData) + public async Task SendMulticastMessage(string message) { - if (messageData == null) throw new ArgumentNullException("messageData"); + if (message == null) throw new ArgumentNullException("messageData"); + + byte[] messageData = Encoding.UTF8.GetBytes(message); ThrowIfDisposed(); @@ -294,21 +293,19 @@ namespace Rssdp.Infrastructure // Tasks are captured to local variables even if we don't use them just to avoid compiler warnings. var t = Task.Run(async () => { - var cancelled = false; while (!cancelled) { try { - var result = await socket.ReceiveAsync(); + var result = await socket.ReceiveAsync().ConfigureAwait(false); if (result.ReceivedBytes > 0) { // Strange cannot convert compiler error here if I don't explicitly // assign or cast to Action first. Assignment is easier to read, // so went with that. - Action processWork = () => ProcessMessage(System.Text.UTF8Encoding.UTF8.GetString(result.Buffer, 0, result.ReceivedBytes), result.RemoteEndPoint); - var processTask = Task.Run(processWork); + ProcessMessage(System.Text.UTF8Encoding.UTF8.GetString(result.Buffer, 0, result.ReceivedBytes), result.RemoteEndPoint); } } catch (ObjectDisposedException) @@ -330,7 +327,9 @@ namespace Rssdp.Infrastructure lock (_SendSocketSynchroniser) { if (_SendSocket == null) + { _SendSocket = CreateSocketAndListenForResponsesAsync(); + } } } } From 420fa8bf7fc3b656207fcc9d41d11ab7d4d906d0 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 14 Nov 2016 15:05:38 -0500 Subject: [PATCH 7/7] update GetEnvironmentInfo --- MediaBrowser.Server.Mono/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Server.Mono/Program.cs b/MediaBrowser.Server.Mono/Program.cs index 7fc3ff22e4..f490a829a2 100644 --- a/MediaBrowser.Server.Mono/Program.cs +++ b/MediaBrowser.Server.Mono/Program.cs @@ -291,7 +291,7 @@ namespace MediaBrowser.Server.Mono { public bool IsBsd { get; set; } - public virtual string GetUserId() + public override string GetUserId() { return Syscall.getuid().ToString(CultureInfo.InvariantCulture); }