mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-03-15 22:56:18 +00:00
merge common implementations and server implementations
This commit is contained in:
127
Emby.Server.Implementations/Net/SocketAcceptor.cs
Normal file
127
Emby.Server.Implementations/Net/SocketAcceptor.cs
Normal file
@@ -0,0 +1,127 @@
|
||||
using System;
|
||||
using System.Net.Sockets;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Net;
|
||||
|
||||
namespace Emby.Server.Implementations.Net
|
||||
{
|
||||
public class SocketAcceptor
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly Socket _originalSocket;
|
||||
private readonly Func<bool> _isClosed;
|
||||
private readonly Action<IAcceptSocket> _onAccept;
|
||||
private readonly bool _isDualMode;
|
||||
|
||||
public SocketAcceptor(ILogger logger, Socket originalSocket, Action<IAcceptSocket> onAccept, Func<bool> isClosed, bool isDualMode)
|
||||
{
|
||||
if (logger == null)
|
||||
{
|
||||
throw new ArgumentNullException("logger");
|
||||
}
|
||||
if (originalSocket == null)
|
||||
{
|
||||
throw new ArgumentNullException("originalSocket");
|
||||
}
|
||||
if (onAccept == null)
|
||||
{
|
||||
throw new ArgumentNullException("onAccept");
|
||||
}
|
||||
if (isClosed == null)
|
||||
{
|
||||
throw new ArgumentNullException("isClosed");
|
||||
}
|
||||
|
||||
_logger = logger;
|
||||
_originalSocket = originalSocket;
|
||||
_isClosed = isClosed;
|
||||
_isDualMode = isDualMode;
|
||||
_onAccept = onAccept;
|
||||
}
|
||||
|
||||
public void StartAccept()
|
||||
{
|
||||
Socket dummy = null;
|
||||
StartAccept(null, ref dummy);
|
||||
}
|
||||
|
||||
public void StartAccept(SocketAsyncEventArgs acceptEventArg, ref Socket accepted)
|
||||
{
|
||||
if (acceptEventArg == null)
|
||||
{
|
||||
acceptEventArg = new SocketAsyncEventArgs();
|
||||
acceptEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(AcceptEventArg_Completed);
|
||||
}
|
||||
else
|
||||
{
|
||||
// acceptSocket must be cleared since the context object is being reused
|
||||
acceptEventArg.AcceptSocket = null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
bool willRaiseEvent = _originalSocket.AcceptAsync(acceptEventArg);
|
||||
|
||||
if (!willRaiseEvent)
|
||||
{
|
||||
ProcessAccept(acceptEventArg);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (accepted != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
#if NET46
|
||||
accepted.Close();
|
||||
#else
|
||||
accepted.Dispose();
|
||||
#endif
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
accepted = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This method is the callback method associated with Socket.AcceptAsync
|
||||
// operations and is invoked when an accept operation is complete
|
||||
//
|
||||
void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs e)
|
||||
{
|
||||
ProcessAccept(e);
|
||||
}
|
||||
|
||||
private void ProcessAccept(SocketAsyncEventArgs e)
|
||||
{
|
||||
if (_isClosed())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/system.net.sockets.acceptSocket.acceptasync%28v=vs.110%29.aspx
|
||||
// Under certain conditions ConnectionReset can occur
|
||||
// Need to attept to re-accept
|
||||
if (e.SocketError == SocketError.ConnectionReset)
|
||||
{
|
||||
_logger.Error("SocketError.ConnectionReset reported. Attempting to re-accept.");
|
||||
Socket dummy = null;
|
||||
StartAccept(e, ref dummy);
|
||||
return;
|
||||
}
|
||||
|
||||
var acceptSocket = e.AcceptSocket;
|
||||
if (acceptSocket != null)
|
||||
{
|
||||
//ProcessAccept(acceptSocket);
|
||||
_onAccept(new NetAcceptSocket(acceptSocket, _logger, _isDualMode));
|
||||
}
|
||||
|
||||
// Accept the next connection request
|
||||
StartAccept(e, ref acceptSocket);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user