private async Task AddLog(TcpDuplexAcceptContext token) { TcpDuplexListenerLog log = new TcpDuplexListenerLog() { IsError = !token.ExecuteSuccess, ErrorMessage = token.ExecuteError ?? string.Empty, ExecuteDuration = (int)token.Watch.ElapsedMilliseconds, ListenerName = _listener.Name, RequestContent = UTF8Encoding.UTF8.GetString(token.RequestData.ToArray()), RequestTime = token.RequestDateTime, ResponseContent = token.ResponseBytes == null ? string.Empty : UTF8Encoding.UTF8.GetString(token.ResponseBytes.ToArray()), ResponseTime = DateTime.UtcNow }; var t = Task.Run(async() => { try { await log.Add(); } catch (Exception ex) { LoggerHelper.LogError(LogCategoryName, $"TcpDuplexListener {_listener.Name}, AddLog Error,message:{ex.Message},stack:{ex.StackTrace}"); } }); await Task.FromResult(0); }
//数据发送处理 private async Task ProcessSend(SocketAsyncEventArgs e) { TcpDuplexAcceptContext token = (TcpDuplexAcceptContext)e.UserToken; if (e.SocketError == SocketError.Success) { token.LatestRunning = DateTime.UtcNow; lock (token.LockObj) { token.Status = 1; } token.ReleaseSendSemaphore(); } else { lock (token.LockObj) { token.Status = -1; } token.ReleaseReceiveSemaphore(); token.ReleaseSendSemaphore(); } await Task.FromResult(0); }
private void CloseClientSocket(SocketAsyncEventArgs e) { TcpDuplexAcceptContext token = (TcpDuplexAcceptContext)e.UserToken; lock (token) { Socket currentSocket = e.AcceptSocket; try { if (currentSocket != null) { currentSocket.Close(); } } catch { } //重新设置连接上下文 token.SocketAsyncEventArgs = null; token.Status = 0; token.RequestData.Clear(); token.ReleaseReceiveSemaphore(); token.ReleaseSendSemaphore(); _tcpDuplexAcceptContextPool.Return(token); } }
private async Task <InnerDoProcessReceiveResult> InnerDoProcessReceive(SocketAsyncEventArgs e, bool useSocket = false, byte[] buffer = null) { InnerDoProcessReceiveResult result = new InnerDoProcessReceiveResult(); TcpDuplexAcceptContext token = (TcpDuplexAcceptContext)e.UserToken; if (!useSocket) { //将数据加入到接收上下文中 token.RequestData.AddRange(e.Buffer.Take(e.BytesTransferred)); } else { var bufferLength = e.AcceptSocket.Receive(buffer); token.RequestData.AddRange(buffer.Take(bufferLength)); } //如果有尚未接收完成的数据,继续接收 if (e.AcceptSocket.Available > 0) { if (buffer == null) { buffer = new byte[e.Buffer.Length]; } result.Complete = false; result.Buffer = buffer; return(await Task.FromResult(result)); } else { result.Complete = true; result.Buffer = buffer; return(await Task.FromResult(result)); } }
/// <summary> /// 开始接受连接 /// </summary> /// <param name="listenSocket"></param> /// <param name="acceptEventArg"></param> private async Task StartAccept(Socket listenSocket) { var t = Task.Run(async() => { while (_start) { TcpDuplexAcceptContext acceptContext = null; try { acceptContext = await _tcpDuplexAcceptContextPool.GetAsync(true); await _acceptSemaphore.WaitAsync(); bool willRaiseEvent = listenSocket.AcceptAsync(acceptContext.SocketAsyncEventArgs); if (!willRaiseEvent) { //Logger.WriteLog("AcceptAsync direct", EventLogEntryType.Information); await ProcessAccept(acceptContext.SocketAsyncEventArgs); } } catch (Exception ex) { ReleaseAcceptSemaphore(); if (acceptContext != null) { CloseClientSocket(acceptContext.SocketAsyncEventArgs); } await AddLog($"StartAccept Error,message:{ex.Message},stack:{ex.StackTrace}", DateTime.UtcNow); LoggerHelper.LogError(LogCategoryName, $"TcpDuplexListener {_listener.Name},StartAccept Error,message:{ex.Message},stack:{ex.StackTrace}"); break; } } }); await Task.FromResult(0); }
private async Task DoProcessReceive(SocketAsyncEventArgs e, bool useSocket = false, byte[] buffer = null) { TcpDuplexAcceptContext token = (TcpDuplexAcceptContext)e.UserToken; var innerResult = await InnerDoProcessReceive(e, useSocket, buffer); while (!innerResult.Complete) { innerResult = await InnerDoProcessReceive(e, true, innerResult.Buffer); } //如果收到的是空字节,表示客户端已经关闭,服务端也需要关闭 if (token.RequestData.Count == 0) { lock (token.LockObj) { token.Status = -1; } token.ReleaseReceiveSemaphore(); token.ReleaseSendSemaphore(); return; } if (!_tcpDuplexDataExecuteFactories.TryGetValue(_listener.ExecuteDataFactoryType, out IFactory <ITcpDuplexDataExecute> tcpDataExecuteFactory)) { lock (_tcpDuplexDataExecuteFactories) { Type tcpDataExecuteFactoryType = Type.GetType(_listener.ExecuteDataFactoryType); if (!_tcpDuplexDataExecuteFactories.TryGetValue(_listener.ExecuteDataFactoryType, out tcpDataExecuteFactory)) { object objTcpDataExecuteFactory; if (_listener.ExecuteDataFactoryTypeUseDI == true) { //通过DI容器创建 objTcpDataExecuteFactory = DIContainerContainer.Get(tcpDataExecuteFactoryType); } else { //通过反射创建 objTcpDataExecuteFactory = tcpDataExecuteFactoryType.Assembly.CreateInstance(tcpDataExecuteFactoryType.FullName); } if (!(objTcpDataExecuteFactory is IFactory <ITcpDataExecute>)) { var fragment = new TextFragment() { Code = TextCodes.TcpDuplexDataExecuteTypeError, DefaultFormatting = "双工Tcp监听{0}中,数据处理的工厂类型{1}未实现接口IFactory<ITcpDuplexDataExecute>", ReplaceParameters = new List <object>() { _listener.Name, _listener.ExecuteDataFactoryType } }; throw new UtilityException((int)Errors.TcpDuplexDataExecuteTypeError, fragment); } tcpDataExecuteFactory = (IFactory <ITcpDuplexDataExecute>)objTcpDataExecuteFactory; _tcpDuplexDataExecuteFactories.Add(_listener.ExecuteDataFactoryType, tcpDataExecuteFactory); } } } var tcpDataExecute = tcpDataExecuteFactory.Create(); var byteResult = await tcpDataExecute.Execute(token.RequestData.ToArray(), token.Connection, GetConnections()); //标识处理状态为成功,并停止计时 token.ExecuteSuccess = true; token.Watch.Stop(); await AddLog(token); //更新状态,解除接收锁 token.LatestRunning = DateTime.UtcNow; token.RequestData.Clear(); token.RequestData.AddRange(byteResult.RestRequestData); lock (token.LockObj) { token.Status = 1; } token.ReleaseReceiveSemaphore(); //向要发送的连接发送返回信息 if (byteResult.ResponseData != null && byteResult.ResponseData.Length > 0) { List <TcpDuplexAcceptContext> sendContexts = null; if (byteResult.ResponseAll) { sendContexts = GetAllAcceptContext(); } else { sendContexts = GetAcceptContext(byteResult.ResponseConnections); } if (sendContexts != null) { foreach (var itemSendContext in sendContexts) { await itemSendContext.ReceiveSemaphore.WaitAsync(); itemSendContext.SocketAsyncEventArgs.SetBuffer(byteResult.ResponseData, 0, byteResult.ResponseData.Length); try { var willRaiseEvent = itemSendContext.SocketAsyncEventArgs.AcceptSocket.SendAsync(itemSendContext.SocketAsyncEventArgs); if (!willRaiseEvent) { await ProcessSend(itemSendContext.SocketAsyncEventArgs); } } catch (Exception ex) { CloseClientSocket(itemSendContext.SocketAsyncEventArgs); await AddLog($"Send Error,message:{ex.Message},stack:{ex.StackTrace}", DateTime.UtcNow); LoggerHelper.LogError(LogCategoryName, $"TcpDuplexListener {_listener.Name},Send Error,message:{ex.Message},stack:{ex.StackTrace}"); } } } } }
/// <summary> /// 数据接收处理 /// </summary> /// <param name="e"></param> private async Task ProcessReceive(SocketAsyncEventArgs e) { TcpDuplexAcceptContext token = (TcpDuplexAcceptContext)e.UserToken; //从开始接受数据计时,默认执行状态设置为false token.ExecuteSuccess = false; token.ExecuteError = string.Empty; token.RequestDateTime = DateTime.UtcNow; token.Watch = new Stopwatch(); token.Watch.Start(); if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success) { //判断是否已经处于关闭状态,是,直接关闭,否,将状态改为正在处理 bool needClose = false; lock (token.LockObj) { if (token.Status == -1) { needClose = true; } else { token.Status = 2; token.LatestRunning = DateTime.UtcNow; } } if (needClose) { token.ReleaseReceiveSemaphore(); token.ReleaseSendSemaphore(); return; } var t = Task.Run(async() => { try { await DoProcessReceive(e); } catch (Exception ex) { token.ExecuteError = $"error message:{ex.Message},stack:{ex.StackTrace}"; token.Watch.Stop(); lock (token.LockObj) { token.Status = -1; } await AddLog(token); token.ReleaseReceiveSemaphore(); token.ReleaseSendSemaphore(); } } ); } else { lock (token.LockObj) { token.Status = -1; } token.ReleaseReceiveSemaphore(); token.ReleaseSendSemaphore(); } await Task.FromResult(0); }
/// <summary> /// 连接处理 /// </summary> /// <param name="e"></param> private async Task ProcessAccept(SocketAsyncEventArgs e) { TcpDuplexAcceptContext token = (TcpDuplexAcceptContext)e.UserToken; ReleaseAcceptSemaphore(); if (e.SocketError == SocketError.Success) { lock (token.LockObj) { token.Status = 1; token.LatestRunning = DateTime.UtcNow; } while (true) { await token.ReceiveSemaphore.WaitAsync(); //判断是否已经处于关闭状态 bool needClose = false; lock (token.LockObj) { if (token.Status == -1) { needClose = true; } } if (needClose) { CloseClientSocket(e); break; } //设置缓冲区最大字节数 var bufferCount = _listener.MaxBufferCount; byte[] buffer = new byte[bufferCount]; e.SetBuffer(buffer, 0, bufferCount); try { bool willRaiseEvent = e.AcceptSocket.ReceiveAsync(e); if (!willRaiseEvent) { await ProcessReceive(e); } } catch (Exception ex) { CloseClientSocket(e); await AddLog($"ProcessAccept Error,message:{ex.Message},stack:{ex.StackTrace}", DateTime.UtcNow); LoggerHelper.LogError(LogCategoryName, $"TcpDuplexListener {_listener.Name},ProcessAccept Error,message:{ex.Message},stack:{ex.StackTrace}"); break; } } } else { //await AddLog($"ProcessAccept Error", DateTime.UtcNow); //LoggerHelper.LogError(_loggerFactory, LogCategoryName, $"TcpListener {_listener.Name},ProcessAccept Error"); CloseClientSocket(e); } }
public async Task Start(TcpDuplexListener listener) { if (!_tcpDuplexDataExecuteFactories.TryGetValue(_listener.ExecuteDataFactoryType, out IFactory <ITcpDuplexDataExecute> tcpDataExecuteFactory)) { lock (_tcpDuplexDataExecuteFactories) { Type tcpDataExecuteFactoryType = Type.GetType(_listener.ExecuteDataFactoryType); if (!_tcpDuplexDataExecuteFactories.TryGetValue(_listener.ExecuteDataFactoryType, out tcpDataExecuteFactory)) { object objTcpDataExecuteFactory; if (_listener.ExecuteDataFactoryTypeUseDI == true) { //通过DI容器创建 objTcpDataExecuteFactory = DIContainerContainer.Get(tcpDataExecuteFactoryType); } else { //通过反射创建 objTcpDataExecuteFactory = tcpDataExecuteFactoryType.Assembly.CreateInstance(tcpDataExecuteFactoryType.FullName); } if (!(objTcpDataExecuteFactory is IFactory <ITcpDataExecute>)) { var fragment = new TextFragment() { Code = TextCodes.TcpDuplexDataExecuteTypeError, DefaultFormatting = "双工Tcp监听{0}中,数据处理的工厂类型{1}未实现接口IFactory<ITcpDuplexDataExecute>", ReplaceParameters = new List <object>() { _listener.Name, _listener.ExecuteDataFactoryType } }; throw new UtilityException((int)Errors.TcpDuplexDataExecuteTypeError, fragment); } tcpDataExecuteFactory = (IFactory <ITcpDuplexDataExecute>)objTcpDataExecuteFactory; _tcpDuplexDataExecuteFactories.Add(_listener.ExecuteDataFactoryType, tcpDataExecuteFactory); } } } _listener = listener; if (!_start) { //设置监听Socket IPEndPoint localPoint = new IPEndPoint(IPAddress.Any, listener.Port); _listenSocket = new Socket(SocketType.Stream, ProtocolType.Tcp); _listenSocket.Bind(localPoint); _listenSocket.Listen(listener.MaxConcurrencyCount); //设置连接参数池 _tcpDuplexAcceptContextPool = new Pool <TcpDuplexAcceptContext>($"TcpDuplexListener-{listener.Name}-AcceptContexts", null, null, null, null, async() => { var connection = new TcpDuplexListenerConnection(Guid.NewGuid(), await tcpDataExecuteFactory.Create().GetInitExtensionInfo()); var context = new TcpDuplexAcceptContext(connection.ID) { ListenSocket = _listenSocket, Connection = connection }; var acceptEventArg = new SocketAsyncEventArgs() { UserToken = context }; acceptEventArg.Completed += new EventHandler <SocketAsyncEventArgs>(IO_Completed); context.SocketAsyncEventArgs = acceptEventArg; return(await Task.FromResult(context)); }, async(item) => { return(await Task.FromResult(true)); }, null, null , listener.MaxConcurrencyCount); _start = true; //启动定时检查Tcp连接 var t = Task.Run(async() => { while (_start) { try { await ValidateConnection(); } catch (Exception ex) { LoggerHelper.LogError(LogCategoryName, $"TcpDuplexListener {_listener.Name},ValidateConnection Error,message:{ex.Message},stack:{ex.StackTrace}"); } System.Threading.Thread.Sleep(100); } }); await StartAccept(_listenSocket); } }