move classes to new server project

This commit is contained in:
Luke Pulverenti 2016-11-04 14:56:47 -04:00
parent a7b11c8ee9
commit 72aaecb279
25 changed files with 186 additions and 308 deletions

View File

@ -37,22 +37,46 @@ namespace Emby.Common.Implementations.Net
#region ISocketFactory Members
/// <summary>
/// Creates a new UDP socket that is a member of the SSDP multicast local admin group and binds it to the specified local port.
/// Creates a new UDP socket and binds it to the specified local port.
/// </summary>
/// <param name="localPort">An integer specifying the local port to bind the socket to.</param>
/// <returns>An implementation of the <see cref="IUdpSocket"/> interface used by RSSDP components to perform socket operations.</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "The purpose of this method is to create and returns a disposable result, it is up to the caller to dispose it when they are done with it.")]
public IUdpSocket CreateUdpSocket(int localPort)
{
if (localPort < 0) throw new ArgumentException("localPort cannot be less than zero.", "localPort");
var retVal = new Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp);
try
{
retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
return new UdpSocket(retVal, localPort, _LocalIP);
}
catch
{
if (retVal != null)
retVal.Dispose();
throw;
}
}
/// <summary>
/// Creates a new UDP socket that is a member of the SSDP multicast local admin group and binds it to the specified local port.
/// </summary>
/// <param name="localPort">An integer specifying the local port to bind the socket to.</param>
/// <returns>An implementation of the <see cref="IUdpSocket"/> interface used by RSSDP components to perform socket operations.</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "The purpose of this method is to create and returns a disposable result, it is up to the caller to dispose it when they are done with it.")]
public IUdpSocket CreateSsdpUdpSocket(int localPort)
{
if (localPort < 0) throw new ArgumentException("localPort cannot be less than zero.", "localPort");
var retVal = new Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp);
try
{
retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 4);
retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse("239.255.255.250"), _LocalIP));
return new UdpSocket(retVal, localPort, _LocalIP.ToString());
return new UdpSocket(retVal, localPort, _LocalIP);
}
catch
{
@ -97,7 +121,7 @@ namespace Emby.Common.Implementations.Net
retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse(ipAddress), _LocalIP));
retVal.MulticastLoopback = true;
return new UdpSocket(retVal, localPort, _LocalIP.ToString());
return new UdpSocket(retVal, localPort, _LocalIP);
}
catch
{

View File

@ -24,19 +24,13 @@ namespace Emby.Common.Implementations.Net
#region Constructors
public UdpSocket(System.Net.Sockets.Socket socket, int localPort, string ipAddress)
public UdpSocket(System.Net.Sockets.Socket socket, int localPort, IPAddress ip)
{
if (socket == null) throw new ArgumentNullException("socket");
_Socket = socket;
_LocalPort = localPort;
IPAddress ip = null;
if (String.IsNullOrEmpty(ipAddress))
ip = IPAddress.Any;
else
ip = IPAddress.Parse(ipAddress);
_Socket.Bind(new IPEndPoint(ip, _LocalPort));
if (_LocalPort == 0)
_LocalPort = (_Socket.LocalEndPoint as IPEndPoint).Port;
@ -46,11 +40,11 @@ namespace Emby.Common.Implementations.Net
#region IUdpSocket Members
public Task<ReceivedUdpData> ReceiveAsync()
public Task<SocketReceiveResult> ReceiveAsync()
{
ThrowIfDisposed();
var tcs = new TaskCompletionSource<ReceivedUdpData>();
var tcs = new TaskCompletionSource<SocketReceiveResult>();
System.Net.EndPoint receivedFromEndPoint = new IPEndPoint(IPAddress.Any, 0);
var state = new AsyncReceiveState(_Socket, receivedFromEndPoint);
@ -74,22 +68,30 @@ namespace Emby.Common.Implementations.Net
return tcs.Task;
}
public Task SendTo(byte[] messageData, IpEndPointInfo endPoint)
public Task SendAsync(byte[] buffer, int size, IpEndPointInfo endPoint)
{
ThrowIfDisposed();
if (messageData == null) throw new ArgumentNullException("messageData");
if (buffer == null) throw new ArgumentNullException("messageData");
if (endPoint == null) throw new ArgumentNullException("endPoint");
#if NETSTANDARD1_6
_Socket.SendTo(messageData, new System.Net.IPEndPoint(IPAddress.Parse(endPoint.IpAddress.ToString()), endPoint.Port));
if (size != buffer.Length)
{
byte[] copy = new byte[size];
Buffer.BlockCopy(buffer, 0, copy, 0, size);
buffer = copy;
}
_Socket.SendTo(buffer, new System.Net.IPEndPoint(IPAddress.Parse(endPoint.IpAddress.ToString()), endPoint.Port));
return Task.FromResult(true);
#else
var taskSource = new TaskCompletionSource<bool>();
try
{
_Socket.BeginSendTo(messageData, 0, messageData.Length, SocketFlags.None, new System.Net.IPEndPoint(IPAddress.Parse(endPoint.IpAddress.ToString()), endPoint.Port), result =>
_Socket.BeginSendTo(buffer, 0, size, SocketFlags.None, new System.Net.IPEndPoint(IPAddress.Parse(endPoint.IpAddress.ToString()), endPoint.Port), result =>
{
try
{
@ -160,11 +162,11 @@ namespace Emby.Common.Implementations.Net
var ipEndPoint = state.EndPoint as IPEndPoint;
state.TaskCompletionSource.SetResult(
new ReceivedUdpData()
new SocketReceiveResult()
{
Buffer = state.Buffer,
ReceivedBytes = bytesRead,
ReceivedFrom = ToIpEndPointInfo(ipEndPoint)
RemoteEndPoint = ToIpEndPointInfo(ipEndPoint)
}
);
}
@ -215,11 +217,11 @@ namespace Emby.Common.Implementations.Net
var ipEndPoint = state.EndPoint as IPEndPoint;
state.TaskCompletionSource.SetResult(
new ReceivedUdpData()
new SocketReceiveResult
{
Buffer = state.Buffer,
ReceivedBytes = bytesRead,
ReceivedFrom = ToIpEndPointInfo(ipEndPoint)
RemoteEndPoint = ToIpEndPointInfo(ipEndPoint)
}
);
}
@ -258,7 +260,7 @@ namespace Emby.Common.Implementations.Net
public System.Net.Sockets.Socket Socket { get; private set; }
public TaskCompletionSource<ReceivedUdpData> TaskCompletionSource { get; set; }
public TaskCompletionSource<SocketReceiveResult> TaskCompletionSource { get; set; }
}

View File

@ -8,6 +8,7 @@ using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Threading.Tasks;
using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.Net;
namespace Emby.Common.Implementations.Networking
{
@ -382,5 +383,35 @@ namespace Emby.Common.Implementations.Networking
return hosts[0];
}
public IpAddressInfo ParseIpAddress(string ipAddress)
{
IpAddressInfo info;
if (TryParseIpAddress(ipAddress, out info))
{
return info;
}
throw new ArgumentException("Invalid ip address: " + ipAddress);
}
public bool TryParseIpAddress(string ipAddress, out IpAddressInfo ipAddressInfo)
{
IPAddress address;
if (IPAddress.TryParse(ipAddress, out address))
{
ipAddressInfo = new IpAddressInfo
{
Address = address.ToString(),
IsIpv6 = address.AddressFamily == AddressFamily.InterNetworkV6
};
return true;
}
ipAddressInfo = null;
return false;
}
}
}

View File

@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
namespace MediaBrowser.Server.Implementations.Connect
namespace Emby.Server.Implementations.Connect
{
public class ConnectData
{

View File

@ -7,16 +7,12 @@ using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Net;
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Threading;
namespace MediaBrowser.Server.Implementations.Connect
namespace Emby.Server.Implementations.Connect
{
public class ConnectEntryPoint : IServerEntryPoint
{
@ -59,7 +55,7 @@ namespace MediaBrowser.Server.Implementations.Connect
private async void TimerCallback(object state)
{
IPAddress validIpAddress = null;
IpAddressInfo validIpAddress = null;
foreach (var ipLookupUrl in _ipLookups)
{
@ -68,7 +64,7 @@ namespace MediaBrowser.Server.Implementations.Connect
validIpAddress = await GetIpAddress(ipLookupUrl).ConfigureAwait(false);
// Try to find the ipv4 address, if present
if (validIpAddress.AddressFamily == AddressFamily.InterNetwork)
if (!validIpAddress.IsIpv6)
{
break;
}
@ -83,7 +79,7 @@ namespace MediaBrowser.Server.Implementations.Connect
}
// If this produced an ipv6 address, try again
if (validIpAddress != null && validIpAddress.AddressFamily == AddressFamily.InterNetworkV6)
if (validIpAddress != null && validIpAddress.IsIpv6)
{
foreach (var ipLookupUrl in _ipLookups)
{
@ -92,7 +88,7 @@ namespace MediaBrowser.Server.Implementations.Connect
var newAddress = await GetIpAddress(ipLookupUrl, true).ConfigureAwait(false);
// Try to find the ipv4 address, if present
if (newAddress.AddressFamily == AddressFamily.InterNetwork)
if (!newAddress.IsIpv6)
{
validIpAddress = newAddress;
break;
@ -115,7 +111,7 @@ namespace MediaBrowser.Server.Implementations.Connect
}
}
private async Task<IPAddress> GetIpAddress(string lookupUrl, bool preferIpv4 = false)
private async Task<IpAddressInfo> GetIpAddress(string lookupUrl, bool preferIpv4 = false)
{
// Sometimes whatismyipaddress might fail, but it won't do us any good having users raise alarms over it.
var logErrors = false;
@ -140,7 +136,7 @@ namespace MediaBrowser.Server.Implementations.Connect
{
var addressString = await reader.ReadToEndAsync().ConfigureAwait(false);
return IPAddress.Parse(addressString);
return _networkManager.ParseIpAddress(addressString);
}
}
}
@ -150,7 +146,7 @@ namespace MediaBrowser.Server.Implementations.Connect
get { return Path.Combine(_appPaths.DataPath, "wan.txt"); }
}
private void CacheAddress(IPAddress address)
private void CacheAddress(IpAddressInfo address)
{
var path = CacheFilePath;
@ -174,9 +170,9 @@ namespace MediaBrowser.Server.Implementations.Connect
try
{
var endpoint = _fileSystem.ReadAllText(path, Encoding.UTF8);
IPAddress ipAddress;
IpAddressInfo ipAddress;
if (IPAddress.TryParse(endpoint, out ipAddress))
if (_networkManager.TryParseIpAddress(endpoint, out ipAddress))
{
((ConnectManager)_connectManager).OnWanAddressResolved(ipAddress);
}

View File

@ -19,16 +19,13 @@ using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.IO;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.IO;
namespace MediaBrowser.Server.Implementations.Connect
namespace Emby.Server.Implementations.Connect
{
public class ConnectManager : IConnectManager
{
@ -57,7 +54,7 @@ namespace MediaBrowser.Server.Implementations.Connect
get { return _data.AccessKey; }
}
private IPAddress DiscoveredWanIpAddress { get; set; }
private IpAddressInfo DiscoveredWanIpAddress { get; set; }
public string WanIpAddress
{
@ -77,7 +74,7 @@ namespace MediaBrowser.Server.Implementations.Connect
if (string.IsNullOrWhiteSpace(address) && DiscoveredWanIpAddress != null)
{
if (DiscoveredWanIpAddress.AddressFamily == AddressFamily.InterNetworkV6)
if (DiscoveredWanIpAddress.IsIpv6)
{
address = "[" + DiscoveredWanIpAddress + "]";
}
@ -148,7 +145,7 @@ namespace MediaBrowser.Server.Implementations.Connect
_config.ConfigurationUpdated += _config_ConfigurationUpdated;
}
internal void OnWanAddressResolved(IPAddress address)
internal void OnWanAddressResolved(IpAddressInfo address)
{
DiscoveredWanIpAddress = address;

View File

@ -1,7 +1,7 @@
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Connect;
namespace MediaBrowser.Server.Implementations.Connect
namespace Emby.Server.Implementations.Connect
{
public class ServerRegistrationResponse
{

View File

@ -1,6 +1,6 @@
using System.Text.RegularExpressions;
namespace MediaBrowser.Server.Implementations.Connect
namespace Emby.Server.Implementations.Connect
{
public static class Validator
{

View File

@ -43,6 +43,11 @@
<Compile Include="Channels\RefreshChannelsScheduledTask.cs" />
<Compile Include="Collections\CollectionImageProvider.cs" />
<Compile Include="Collections\CollectionManager.cs" />
<Compile Include="Connect\ConnectData.cs" />
<Compile Include="Connect\ConnectEntryPoint.cs" />
<Compile Include="Connect\ConnectManager.cs" />
<Compile Include="Connect\Responses.cs" />
<Compile Include="Connect\Validator.cs" />
<Compile Include="Devices\DeviceManager.cs" />
<Compile Include="Dto\DtoService.cs" />
<Compile Include="EntryPoints\AutomaticRestartEntryPoint.cs" />
@ -51,6 +56,7 @@
<Compile Include="EntryPoints\RecordingNotifier.cs" />
<Compile Include="EntryPoints\RefreshUsersMetadata.cs" />
<Compile Include="EntryPoints\ServerEventNotifier.cs" />
<Compile Include="EntryPoints\UdpServerEntryPoint.cs" />
<Compile Include="EntryPoints\UsageEntryPoint.cs" />
<Compile Include="EntryPoints\UsageReporter.cs" />
<Compile Include="EntryPoints\UserDataChangeNotifier.cs" />
@ -68,6 +74,7 @@
<Compile Include="HttpServer\StreamWriter.cs" />
<Compile Include="Images\BaseDynamicImageProvider.cs" />
<Compile Include="Intros\DefaultIntroProvider.cs" />
<Compile Include="IO\FileRefresher.cs" />
<Compile Include="IO\ThrottledStream.cs" />
<Compile Include="Library\CoreResolutionIgnoreRule.cs" />
<Compile Include="Library\LibraryManager.cs" />
@ -159,6 +166,7 @@
<Compile Include="ScheduledTasks\RefreshIntrosTask.cs" />
<Compile Include="ScheduledTasks\RefreshMediaLibraryTask.cs" />
<Compile Include="ScheduledTasks\SystemUpdateTask.cs" />
<Compile Include="Security\EncryptionManager.cs" />
<Compile Include="Security\MBLicenseFile.cs" />
<Compile Include="Security\PluginSecurityManager.cs" />
<Compile Include="Security\RegRecord.cs" />
@ -217,6 +225,7 @@
<Compile Include="Sync\TargetDataProvider.cs" />
<Compile Include="TV\SeriesPostScanTask.cs" />
<Compile Include="TV\TVSeriesManager.cs" />
<Compile Include="Udp\UdpServer.cs" />
<Compile Include="Updates\InstallationManager.cs" />
<Compile Include="UserViews\CollectionFolderImageProvider.cs" />
<Compile Include="UserViews\DynamicImageProvider.cs" />

View File

@ -1,12 +1,12 @@
using System;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Server.Implementations.Udp;
using Emby.Server.Implementations.Udp;
using MediaBrowser.Model.Net;
namespace MediaBrowser.Server.Implementations.EntryPoints
namespace Emby.Server.Implementations.EntryPoints
{
/// <summary>
/// Class UdpServerEntryPoint
@ -23,10 +23,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
/// The _logger
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// The _network manager
/// </summary>
private readonly INetworkManager _networkManager;
private readonly ISocketFactory _socketFactory;
private readonly IServerApplicationHost _appHost;
private readonly IJsonSerializer _json;
@ -35,16 +32,12 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
/// <summary>
/// Initializes a new instance of the <see cref="UdpServerEntryPoint" /> class.
/// </summary>
/// <param name="logger">The logger.</param>
/// <param name="networkManager">The network manager.</param>
/// <param name="appHost">The application host.</param>
/// <param name="json">The json.</param>
public UdpServerEntryPoint(ILogger logger, INetworkManager networkManager, IServerApplicationHost appHost, IJsonSerializer json)
public UdpServerEntryPoint(ILogger logger, IServerApplicationHost appHost, IJsonSerializer json, ISocketFactory socketFactory)
{
_logger = logger;
_networkManager = networkManager;
_appHost = appHost;
_json = json;
_socketFactory = socketFactory;
}
/// <summary>
@ -52,7 +45,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
/// </summary>
public void Run()
{
var udpServer = new UdpServer(_logger, _networkManager, _appHost, _json);
var udpServer = new UdpServer(_logger, _appHost, _json, _socketFactory);
try
{

View File

@ -16,7 +16,7 @@ using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Tasks;
using MediaBrowser.Model.Threading;
namespace MediaBrowser.Server.Implementations.IO
namespace Emby.Server.Implementations.IO
{
public class FileRefresher : IDisposable
{
@ -226,11 +226,11 @@ namespace MediaBrowser.Server.Implementations.IO
private bool IsFileLocked(string path)
{
if (Environment.OSVersion.Platform != PlatformID.Win32NT)
{
// Causing lockups on linux
return false;
}
//if (Environment.OSVersion.Platform != PlatformID.Win32NT)
//{
// // Causing lockups on linux
// return false;
//}
try
{

View File

@ -2,7 +2,7 @@
using System;
using System.Text;
namespace MediaBrowser.Server.Implementations.Security
namespace Emby.Server.Implementations.Security
{
public class EncryptionManager : IEncryptionManager
{
@ -45,7 +45,7 @@ namespace MediaBrowser.Server.Implementations.Security
// Yes, this isn't good, but ProtectedData in mono is throwing exceptions, so use this for now
var bytes = Convert.FromBase64String(value);
return Encoding.UTF8.GetString(bytes);
return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
}
}
}

View File

@ -1,18 +1,16 @@
using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
using MediaBrowser.Controller;
using MediaBrowser.Model.ApiClient;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using Emby.Common.Implementations.Networking;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.Net;
namespace MediaBrowser.Server.Implementations.Udp
namespace Emby.Server.Implementations.Udp
{
/// <summary>
/// Provides a Udp Server
@ -24,14 +22,9 @@ namespace MediaBrowser.Server.Implementations.Udp
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// The _network manager
/// </summary>
private readonly INetworkManager _networkManager;
private bool _isDisposed;
private readonly List<Tuple<string, bool, Func<string, string, Encoding, Task>>> _responders = new List<Tuple<string, bool, Func<string, string, Encoding, Task>>>();
private readonly List<Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, Task>>> _responders = new List<Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, Task>>>();
private readonly IServerApplicationHost _appHost;
private readonly IJsonSerializer _json;
@ -39,46 +32,43 @@ namespace MediaBrowser.Server.Implementations.Udp
/// <summary>
/// Initializes a new instance of the <see cref="UdpServer" /> class.
/// </summary>
/// <param name="logger">The logger.</param>
/// <param name="networkManager">The network manager.</param>
/// <param name="appHost">The application host.</param>
/// <param name="json">The json.</param>
public UdpServer(ILogger logger, INetworkManager networkManager, IServerApplicationHost appHost, IJsonSerializer json)
public UdpServer(ILogger logger, IServerApplicationHost appHost, IJsonSerializer json, ISocketFactory socketFactory)
{
_logger = logger;
_networkManager = networkManager;
_appHost = appHost;
_json = json;
_socketFactory = socketFactory;
AddMessageResponder("who is EmbyServer?", true, RespondToV2Message);
AddMessageResponder("who is MediaBrowserServer_v2?", false, RespondToV2Message);
}
private void AddMessageResponder(string message, bool isSubstring, Func<string, string, Encoding, Task> responder)
private void AddMessageResponder(string message, bool isSubstring, Func<string, IpEndPointInfo, Encoding, Task> responder)
{
_responders.Add(new Tuple<string, bool, Func<string, string, Encoding, Task>>(message, isSubstring, responder));
_responders.Add(new Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, Task>>(message, isSubstring, responder));
}
/// <summary>
/// Raises the <see cref="E:MessageReceived" /> event.
/// </summary>
/// <param name="e">The <see cref="UdpMessageReceivedEventArgs"/> instance containing the event data.</param>
private async void OnMessageReceived(UdpMessageReceivedEventArgs e)
private async void OnMessageReceived(GenericEventArgs<SocketReceiveResult> e)
{
var message = e.Argument;
var encoding = Encoding.UTF8;
var responder = GetResponder(e.Bytes, encoding);
var responder = GetResponder(message.Buffer, message.ReceivedBytes, encoding);
if (responder == null)
{
encoding = Encoding.Unicode;
responder = GetResponder(e.Bytes, encoding);
responder = GetResponder(message.Buffer, message.ReceivedBytes, encoding);
}
if (responder != null)
{
try
{
await responder.Item2.Item3(responder.Item1, e.RemoteEndPoint, encoding).ConfigureAwait(false);
await responder.Item2.Item3(responder.Item1, message.RemoteEndPoint, encoding).ConfigureAwait(false);
}
catch (Exception ex)
{
@ -87,9 +77,9 @@ namespace MediaBrowser.Server.Implementations.Udp
}
}
private Tuple<string, Tuple<string, bool, Func<string, string, Encoding, Task>>> GetResponder(byte[] bytes, Encoding encoding)
private Tuple<string, Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, Task>>> GetResponder(byte[] buffer, int bytesReceived, Encoding encoding)
{
var text = encoding.GetString(bytes);
var text = encoding.GetString(buffer, 0, bytesReceived);
var responder = _responders.FirstOrDefault(i =>
{
if (i.Item2)
@ -103,10 +93,10 @@ namespace MediaBrowser.Server.Implementations.Udp
{
return null;
}
return new Tuple<string, Tuple<string, bool, Func<string, string, Encoding, Task>>>(text, responder);
return new Tuple<string, Tuple<string, bool, Func<string, IpEndPointInfo, Encoding, Task>>>(text, responder);
}
private async Task RespondToV2Message(string messageText, string endpoint, Encoding encoding)
private async Task RespondToV2Message(string messageText, IpEndPointInfo endpoint, Encoding encoding)
{
var parts = messageText.Split('|');
@ -122,7 +112,7 @@ namespace MediaBrowser.Server.Implementations.Udp
};
await SendAsync(encoding.GetBytes(_json.SerializeToString(response)), endpoint).ConfigureAwait(false);
if (parts.Length > 1)
{
_appHost.EnableLoopback(parts[1]);
@ -137,7 +127,8 @@ namespace MediaBrowser.Server.Implementations.Udp
/// <summary>
/// The _udp client
/// </summary>
private UdpClient _udpClient;
private IUdpSocket _udpClient;
private readonly ISocketFactory _socketFactory;
/// <summary>
/// Starts the specified port.
@ -145,9 +136,7 @@ namespace MediaBrowser.Server.Implementations.Udp
/// <param name="port">The port.</param>
public void Start(int port)
{
_udpClient = new UdpClient(new IPEndPoint(IPAddress.Any, port));
_udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
_udpClient = _socketFactory.CreateUdpSocket(port);
Task.Run(() => StartListening());
}
@ -158,56 +147,36 @@ namespace MediaBrowser.Server.Implementations.Udp
{
try
{
var result = await GetResult().ConfigureAwait(false);
var result = await _udpClient.ReceiveAsync().ConfigureAwait(false);
OnMessageReceived(result);
}
catch (ObjectDisposedException)
{
break;
}
catch (Exception ex)
{
_logger.ErrorException("Error in StartListening", ex);
_logger.ErrorException("Error receiving udp message", ex);
}
}
}
private Task<UdpReceiveResult> GetResult()
{
try
{
return _udpClient.ReceiveAsync();
}
catch (ObjectDisposedException)
{
return Task.FromResult(new UdpReceiveResult(new byte[] { }, new IPEndPoint(IPAddress.Any, 0)));
}
catch (Exception ex)
{
_logger.ErrorException("Error receiving udp message", ex);
return Task.FromResult(new UdpReceiveResult(new byte[] { }, new IPEndPoint(IPAddress.Any, 0)));
}
}
/// <summary>
/// Called when [message received].
/// </summary>
/// <param name="message">The message.</param>
private void OnMessageReceived(UdpReceiveResult message)
private void OnMessageReceived(SocketReceiveResult message)
{
if (message.RemoteEndPoint.Port == 0)
{
return;
}
var bytes = message.Buffer;
try
{
OnMessageReceived(new UdpMessageReceivedEventArgs
OnMessageReceived(new GenericEventArgs<SocketReceiveResult>
{
Bytes = bytes,
RemoteEndPoint = message.RemoteEndPoint.ToString()
Argument = message
});
}
catch (Exception ex)
@ -234,7 +203,7 @@ namespace MediaBrowser.Server.Implementations.Udp
if (_udpClient != null)
{
_udpClient.Close();
_udpClient.Dispose();
}
}
@ -250,71 +219,21 @@ namespace MediaBrowser.Server.Implementations.Udp
}
}
/// <summary>
/// Sends the async.
/// </summary>
/// <param name="data">The data.</param>
/// <param name="ipAddress">The ip address.</param>
/// <param name="port">The port.</param>
/// <returns>Task{System.Int32}.</returns>
/// <exception cref="System.ArgumentNullException">data</exception>
public Task SendAsync(string data, string ipAddress, int port)
{
return SendAsync(Encoding.UTF8.GetBytes(data), ipAddress, port);
}
/// <summary>
/// Sends the async.
/// </summary>
/// <param name="bytes">The bytes.</param>
/// <param name="ipAddress">The ip address.</param>
/// <param name="port">The port.</param>
/// <returns>Task{System.Int32}.</returns>
/// <exception cref="System.ArgumentNullException">bytes</exception>
public Task SendAsync(byte[] bytes, string ipAddress, int port)
public async Task SendAsync(byte[] bytes, IpEndPointInfo remoteEndPoint)
{
if (bytes == null)
{
throw new ArgumentNullException("bytes");
}
if (string.IsNullOrEmpty(ipAddress))
{
throw new ArgumentNullException("ipAddress");
}
return _udpClient.SendAsync(bytes, bytes.Length, ipAddress, port);
}
/// <summary>
/// Sends the async.
/// </summary>
/// <param name="bytes">The bytes.</param>
/// <param name="remoteEndPoint">The remote end point.</param>
/// <returns>Task.</returns>
/// <exception cref="System.ArgumentNullException">
/// bytes
/// or
/// remoteEndPoint
/// </exception>
public async Task SendAsync(byte[] bytes, string remoteEndPoint)
{
if (bytes == null)
{
throw new ArgumentNullException("bytes");
}
if (string.IsNullOrEmpty(remoteEndPoint))
if (remoteEndPoint == null)
{
throw new ArgumentNullException("remoteEndPoint");
}
try
{
// Need to do this until Common will compile with this method
var nativeNetworkManager = (BaseNetworkManager) _networkManager;
await _udpClient.SendAsync(bytes, bytes.Length, nativeNetworkManager.Parse(remoteEndPoint)).ConfigureAwait(false);
await _udpClient.SendAsync(bytes, bytes.Length, remoteEndPoint).ConfigureAwait(false);
_logger.Info("Udp message sent to {0}", remoteEndPoint);
}

View File

@ -46,6 +46,10 @@ namespace MediaBrowser.Common.Net
/// <returns><c>true</c> if [is in local network] [the specified endpoint]; otherwise, <c>false</c>.</returns>
bool IsInLocalNetwork(string endpoint);
IpAddressInfo ParseIpAddress(string ipAddress);
bool TryParseIpAddress(string ipAddress, out IpAddressInfo ipAddressInfo);
/// <summary>
/// Generates a self signed certificate at the locatation specified by <paramref name="certificatePath"/>.
/// </summary>

View File

@ -140,7 +140,7 @@
<Compile Include="Net\IpEndPointInfo.cs" />
<Compile Include="Net\ISocketFactory.cs" />
<Compile Include="Net\IUdpSocket.cs" />
<Compile Include="Net\ReceivedUdpData.cs" />
<Compile Include="Net\SocketReceiveResult.cs" />
<Compile Include="TextEncoding\IEncoding.cs" />
<Compile Include="Extensions\LinqExtensions.cs" />
<Compile Include="FileOrganization\SmartMatchInfo.cs" />

View File

@ -14,13 +14,18 @@ namespace MediaBrowser.Model.Net
/// <returns>A <see cref="IUdpSocket"/> implementation.</returns>
IUdpSocket CreateUdpSocket(int localPort);
/// <summary>
/// Createa a new multicast socket using the specified multicast IP address, multicast time to live and local port.
/// </summary>
/// <param name="ipAddress">The multicast IP address to bind to.</param>
/// <param name="multicastTimeToLive">The multicast time to live value. Actually a maximum number of network hops for UDP packets.</param>
/// <param name="localPort">The local port to bind to.</param>
/// <returns>A <see cref="IUdpSocket"/> implementation.</returns>
IUdpSocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort);
/// <summary>
/// Createa a new unicast socket using the specified local port number.
/// </summary>
IUdpSocket CreateSsdpUdpSocket(int localPort);
/// <summary>
/// Createa a new multicast socket using the specified multicast IP address, multicast time to live and local port.
/// </summary>
/// <param name="ipAddress">The multicast IP address to bind to.</param>
/// <param name="multicastTimeToLive">The multicast time to live value. Actually a maximum number of network hops for UDP packets.</param>
/// <param name="localPort">The local port to bind to.</param>
/// <returns>A <see cref="IUdpSocket"/> implementation.</returns>
IUdpSocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort);
}
}

View File

@ -15,13 +15,11 @@ namespace MediaBrowser.Model.Net
/// Waits for and returns the next UDP message sent to this socket (uni or multicast).
/// </summary>
/// <returns></returns>
Task<ReceivedUdpData> ReceiveAsync();
Task<SocketReceiveResult> ReceiveAsync();
/// <summary>
/// Sends a UDP message to a particular end point (uni or multicast).
/// </summary>
/// <param name="messageData">The data to send.</param>
/// <param name="endPoint">The <see cref="IpEndPointInfo"/> providing the address and port to send to.</param>
Task SendTo(byte[] messageData, IpEndPointInfo endPoint);
Task SendAsync(byte[] buffer, int bytes, IpEndPointInfo endPoint);
}
}

View File

@ -4,7 +4,7 @@ namespace MediaBrowser.Model.Net
/// <summary>
/// Used by the sockets wrapper to hold raw data received from a UDP socket.
/// </summary>
public sealed class ReceivedUdpData
public sealed class SocketReceiveResult
{
/// <summary>
/// The buffer to place received data into.
@ -19,6 +19,6 @@ namespace MediaBrowser.Model.Net
/// <summary>
/// The <see cref="IpEndPointInfo"/> the data was received from.
/// </summary>
public IpEndPointInfo ReceivedFrom { get; set; }
public IpEndPointInfo RemoteEndPoint { get; set; }
}
}

View File

@ -1,13 +1,13 @@
using System.Collections.Specialized;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Logging;
using MediaBrowser.Server.Implementations.Logging;
using SocketHttpListener.Net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Emby.Server.Implementations.HttpServer;
using Emby.Server.Implementations.Logging;
using MediaBrowser.Common.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Services;

View File

@ -10,13 +10,14 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Emby.Server.Implementations.IO;
using MediaBrowser.Common.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Controller;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.System;
using MediaBrowser.Model.Tasks;
using MediaBrowser.Model.Threading;
using Microsoft.Win32;
namespace MediaBrowser.Server.Implementations.IO
{
@ -142,7 +143,7 @@ namespace MediaBrowser.Server.Implementations.IO
/// <summary>
/// Initializes a new instance of the <see cref="LibraryMonitor" /> class.
/// </summary>
public LibraryMonitor(ILogManager logManager, ITaskManager taskManager, ILibraryManager libraryManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ITimerFactory timerFactory)
public LibraryMonitor(ILogManager logManager, ITaskManager taskManager, ILibraryManager libraryManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem, ITimerFactory timerFactory, ISystemEvents systemEvents)
{
if (taskManager == null)
{
@ -156,15 +157,10 @@ namespace MediaBrowser.Server.Implementations.IO
_fileSystem = fileSystem;
_timerFactory = timerFactory;
SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
systemEvents.Resume += _systemEvents_Resume;
}
/// <summary>
/// Handles the PowerModeChanged event of the SystemEvents control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="PowerModeChangedEventArgs"/> instance containing the event data.</param>
void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
private void _systemEvents_Resume(object sender, EventArgs e)
{
Restart();
}

View File

@ -1,63 +0,0 @@
using Patterns.Logging;
using System;
namespace MediaBrowser.Server.Implementations.Logging
{
public class PatternsLogger : ILogger
{
private readonly Model.Logging.ILogger _logger;
public PatternsLogger()
: this(new Model.Logging.NullLogger())
{
}
public PatternsLogger(Model.Logging.ILogger logger)
{
_logger = logger;
}
public void Debug(string message, params object[] paramList)
{
_logger.Debug(message, paramList);
}
public void Error(string message, params object[] paramList)
{
_logger.Error(message, paramList);
}
public void ErrorException(string message, Exception exception, params object[] paramList)
{
_logger.ErrorException(message, exception, paramList);
}
public void Fatal(string message, params object[] paramList)
{
_logger.Fatal(message, paramList);
}
public void FatalException(string message, Exception exception, params object[] paramList)
{
_logger.FatalException(message, exception, paramList);
}
public void Info(string message, params object[] paramList)
{
_logger.Info(message, paramList);
}
public void Warn(string message, params object[] paramList)
{
_logger.Warn(message, paramList);
}
public void Log(LogSeverity severity, string message, params object[] paramList)
{
}
public void LogMultiline(string message, LogSeverity severity, System.Text.StringBuilder additionalContent)
{
}
}
}

View File

@ -113,15 +113,9 @@
<Compile Include="Archiving\ZipClient.cs" />
<Compile Include="Collections\CollectionsDynamicFolder.cs" />
<Compile Include="Configuration\ServerConfigurationManager.cs" />
<Compile Include="Connect\ConnectData.cs" />
<Compile Include="Connect\ConnectEntryPoint.cs" />
<Compile Include="Connect\ConnectManager.cs" />
<Compile Include="Connect\Responses.cs" />
<Compile Include="Connect\Validator.cs" />
<Compile Include="Devices\DeviceRepository.cs" />
<Compile Include="Devices\CameraUploadsFolder.cs" />
<Compile Include="EntryPoints\ExternalPortForwarding.cs" />
<Compile Include="EntryPoints\UdpServerEntryPoint.cs" />
<Compile Include="HttpServer\ContainerAdapter.cs" />
<Compile Include="HttpServer\GetSwaggerResource.cs" />
<Compile Include="HttpServer\HttpListenerHost.cs" />
@ -140,7 +134,6 @@
<Compile Include="HttpServer\SocketSharp\WebSocketSharpListener.cs" />
<Compile Include="HttpServer\SocketSharp\WebSocketSharpRequest.cs" />
<Compile Include="HttpServer\SocketSharp\WebSocketSharpResponse.cs" />
<Compile Include="IO\FileRefresher.cs" />
<Compile Include="IO\LibraryMonitor.cs" />
<Compile Include="IO\MemoryStreamProvider.cs" />
<Compile Include="LiveTv\TunerHosts\SatIp\ChannelScan.cs" />
@ -166,7 +159,6 @@
<Compile Include="LiveTv\TunerHosts\SatIp\TransmissionMode.cs" />
<Compile Include="LiveTv\TunerHosts\SatIp\Utils.cs" />
<Compile Include="Localization\LocalizationManager.cs" />
<Compile Include="Logging\PatternsLogger.cs" />
<Compile Include="Persistence\BaseSqliteRepository.cs" />
<Compile Include="Persistence\DataExtensions.cs" />
<Compile Include="Persistence\IDbConnector.cs" />
@ -180,15 +172,12 @@
<Compile Include="Playlists\ManualPlaylistsFolder.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Security\AuthenticationRepository.cs" />
<Compile Include="Security\EncryptionManager.cs" />
<Compile Include="ServerApplicationPaths.cs" />
<Compile Include="Persistence\SqliteDisplayPreferencesRepository.cs" />
<Compile Include="Persistence\SqliteItemRepository.cs" />
<Compile Include="Persistence\SqliteUserDataRepository.cs" />
<Compile Include="Persistence\SqliteUserRepository.cs" />
<Compile Include="Sync\SyncRepository.cs" />
<Compile Include="Udp\UdpMessageReceivedEventArgs.cs" />
<Compile Include="Udp\UdpServer.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Emby.Server.Implementations\Emby.Server.Implementations.csproj">

View File

@ -1,21 +0,0 @@
using System;
namespace MediaBrowser.Server.Implementations.Udp
{
/// <summary>
/// Class UdpMessageReceivedEventArgs
/// </summary>
public class UdpMessageReceivedEventArgs : EventArgs
{
/// <summary>
/// Gets or sets the bytes.
/// </summary>
/// <value>The bytes.</value>
public byte[] Bytes { get; set; }
/// <summary>
/// Gets or sets the remote end point.
/// </summary>
/// <value>The remote end point.</value>
public string RemoteEndPoint { get; set; }
}
}

View File

@ -51,12 +51,9 @@ using MediaBrowser.Providers.Subtitles;
using MediaBrowser.Server.Implementations;
using MediaBrowser.Server.Implementations.Activity;
using MediaBrowser.Server.Implementations.Configuration;
using MediaBrowser.Server.Implementations.Connect;
using MediaBrowser.Server.Implementations.Devices;
using MediaBrowser.Server.Implementations.EntryPoints;
using MediaBrowser.Server.Implementations.HttpServer;
using MediaBrowser.Server.Implementations.IO;
using MediaBrowser.Server.Implementations.LiveTv;
using MediaBrowser.Server.Implementations.Localization;
using MediaBrowser.Server.Implementations.Notifications;
using MediaBrowser.Server.Implementations.Persistence;
@ -102,8 +99,10 @@ using Emby.Dlna.Ssdp;
using Emby.Server.Implementations.Activity;
using Emby.Server.Implementations.Channels;
using Emby.Server.Implementations.Collections;
using Emby.Server.Implementations.Connect;
using Emby.Server.Implementations.Devices;
using Emby.Server.Implementations.Dto;
using Emby.Server.Implementations.EntryPoints;
using Emby.Server.Implementations.FileOrganization;
using Emby.Server.Implementations.HttpServer.Security;
using Emby.Server.Implementations.Library;
@ -593,7 +592,7 @@ namespace MediaBrowser.Server.Startup.Common
var musicManager = new MusicManager(LibraryManager);
RegisterSingleInstance<IMusicManager>(new MusicManager(LibraryManager));
LibraryMonitor = new LibraryMonitor(LogManager, TaskManager, LibraryManager, ServerConfigurationManager, FileSystemManager, TimerFactory);
LibraryMonitor = new LibraryMonitor(LogManager, TaskManager, LibraryManager, ServerConfigurationManager, FileSystemManager, TimerFactory, SystemEvents);
RegisterSingleInstance(LibraryMonitor);
ProviderManager = new ProviderManager(HttpClient, ServerConfigurationManager, LibraryMonitor, LogManager, FileSystemManager, ApplicationPaths, () => LibraryManager, JsonSerializer, MemoryStreamProvider);

View File

@ -260,7 +260,7 @@ namespace Rssdp.Infrastructure
var socket = _SendSocket;
if (socket != null)
{
await _SendSocket.SendTo(messageData, destination).ConfigureAwait(false);
await _SendSocket.SendAsync(messageData, messageData.Length, destination).ConfigureAwait(false);
}
else
{
@ -290,7 +290,7 @@ namespace Rssdp.Infrastructure
private IUdpSocket CreateSocketAndListenForResponsesAsync()
{
_SendSocket = _SocketFactory.CreateUdpSocket(_LocalPort);
_SendSocket = _SocketFactory.CreateSsdpUdpSocket(_LocalPort);
ListenToSocket(_SendSocket);
@ -316,7 +316,7 @@ namespace Rssdp.Infrastructure
// 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.ReceivedFrom);
Action processWork = () => ProcessMessage(System.Text.UTF8Encoding.UTF8.GetString(result.Buffer, 0, result.ReceivedBytes), result.RemoteEndPoint);
var processTask = Task.Run(processWork);
}
}