Selaa lähdekoodia

update udp sockets

Luke Pulverenti 8 vuotta sitten
vanhempi
sitoutus
44336488f3

+ 1 - 0
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));

+ 2 - 9
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);

+ 23 - 7
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()

+ 8 - 12
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<GenericEventArgs<UpnpDeviceInfo>> DeviceDiscovered;
         public event EventHandler<GenericEventArgs<UpnpDeviceInfo>> 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)

+ 8 - 9
RSSDP/SsdpCommunicationsServer.cs

@@ -170,12 +170,11 @@ namespace Rssdp.Infrastructure
         /// <summary>
         /// Sends a message to the SSDP multicast address and port.
         /// </summary>
-        /// <param name="messageData">A byte array containing the data to send.</param>
-        /// <exception cref="System.ArgumentNullException">Thrown if the <paramref name="messageData"/> argument is null.</exception>
-        /// <exception cref="System.ObjectDisposedException">Thrown if the <see cref="DisposableManagedObjectBase.IsDisposed"/> property is true (because <seealso cref="DisposableManagedObjectBase.Dispose()" /> has been called previously).</exception>
-        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();
+                    }
                 }
             }
         }