mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-06-01 05:18:27 +01:00
update SocketHttpListener
This commit is contained in:
@@ -89,63 +89,6 @@ namespace Emby.Server.Implementations.Net
|
||||
Socket.Bind(nativeEndpoint);
|
||||
}
|
||||
|
||||
private SocketAcceptor _acceptor;
|
||||
public void StartAccept(Action<IAcceptSocket> onAccept, Func<bool> isClosed)
|
||||
{
|
||||
_acceptor = new SocketAcceptor(_logger, Socket, onAccept, isClosed, DualMode);
|
||||
|
||||
_acceptor.StartAccept();
|
||||
}
|
||||
|
||||
public Task SendFile(string path, byte[] preBuffer, byte[] postBuffer, CancellationToken cancellationToken)
|
||||
{
|
||||
var options = TransmitFileOptions.UseDefaultWorkerThread;
|
||||
|
||||
var completionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
var result = Socket.BeginSendFile(path, preBuffer, postBuffer, options, new AsyncCallback(FileSendCallback), new Tuple<Socket, string, TaskCompletionSource<bool>>(Socket, path, completionSource));
|
||||
|
||||
return completionSource.Task;
|
||||
}
|
||||
|
||||
public IAsyncResult BeginSendFile(string path, byte[] preBuffer, byte[] postBuffer, AsyncCallback callback, object state)
|
||||
{
|
||||
var options = TransmitFileOptions.UseDefaultWorkerThread;
|
||||
|
||||
return Socket.BeginSendFile(path, preBuffer, postBuffer, options, new AsyncCallback(FileSendCallback), state);
|
||||
}
|
||||
|
||||
public void EndSendFile(IAsyncResult result)
|
||||
{
|
||||
Socket.EndSendFile(result);
|
||||
}
|
||||
|
||||
private void FileSendCallback(IAsyncResult ar)
|
||||
{
|
||||
// Retrieve the socket from the state object.
|
||||
Tuple<Socket, string, TaskCompletionSource<bool>> data = (Tuple<Socket, string, TaskCompletionSource<bool>>)ar.AsyncState;
|
||||
|
||||
var client = data.Item1;
|
||||
var path = data.Item2;
|
||||
var taskCompletion = data.Item3;
|
||||
|
||||
// Complete sending the data to the remote device.
|
||||
try
|
||||
{
|
||||
client.EndSendFile(ar);
|
||||
taskCompletion.TrySetResult(true);
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
_logger.Info("Socket.SendFile failed for {0}. error code {1}", path, ex.SocketErrorCode);
|
||||
taskCompletion.TrySetException(ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
taskCompletion.TrySetException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Socket.Dispose();
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
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