示例#1
0
        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);
        }
示例#2
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);
        }
示例#3
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);
            }
        }
示例#4
0
        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));
            }
        }
示例#5
0
        /// <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);
        }
示例#6
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}");
                        }
                    }
                }
            }
        }
示例#7
0
        /// <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);
        }
示例#8
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);
            }
        }
示例#9
0
        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);
            }
        }