Ejemplo n.º 1
0
        async Task <Result> ProcessAndResponse(
            TcpClient tcpClient,
            Action close_action,
            ZServerChannel channel,
            BerTree request,
            CancellationToken token)
        {
            string name  = "";
            string ip    = "";
            bool   error = false;

            try
            {
                name = channel.GetDebugName(tcpClient);
                ip   = TcpServer.GetClientIP(tcpClient);

                byte[] response = null;
                if (this.ProcessRequest == null)
                {
                    response = await DefaultProcessRequest(channel, request).ConfigureAwait(false);  // 2018/10/10 add configure
                }
                else
                {
                    ProcessRequestEventArgs e = new ProcessRequestEventArgs();
                    e.Request = request;
                    this.ProcessRequest(channel, e);
                    response = e.Response;
                }

                channel.Touch();
                if (token != null && token.IsCancellationRequested)
                {
                    error = true;
                    return(new Result {
                        Value = -1, ErrorInfo = "Cancelled"
                    });
                }

                // 注意调用返回 result.Value == -1 情况下,要及时 Close TcpClient
                Result result = await ZProcessor.SendResponse(response, tcpClient).ConfigureAwait(false); // 2018/10/10 add configure

                channel.Touch();
                if (result.Value == -1)
                {
                    Console.WriteLine("error on response " + name + ": " + result.ErrorInfo);
                    error = true;
                    return(result);
                }

                return(new Result());
            }
            catch (Exception ex)
            {
                if (ex is UnknownApduException ||
                    ex is BadApduException)
                {
                    IpTable.SetInBlackList(ip, TimeSpan.FromHours(1));
                    LibraryManager.Log?.Info(string.Format("IP 地址 {0} 已被加入黑名单,时限一个小时", ip));
                }

                if (channel != null)
                {
                    channel.Close();
                    if (close_action != null)
                    {
                        close_action.Invoke();
                    }
                    LogException(ex, channel, name);
                    channel = null;
                }
                else
                {
                    LogException(ex, channel, name);
                }

                return(new Result {
                    Value = -1, ErrorInfo = "Cancelled"
                });
            }
            finally
            {
                if (error == true &&
                    channel != null)
                {
                    channel.Close();
                    if (close_action != null)
                    {
                        close_action.Invoke();
                    }
                }
            }
        }
Ejemplo n.º 2
0
        // 处理一个通道的通讯活动
        public async override void HandleClient(TcpClient tcpClient,
                                                Action close_action,
                                                CancellationToken token)
        {
            List <byte> cache = new List <byte>();

            ZServerChannel channel = _tcpChannels.Add(tcpClient, () => { return(new ZServerChannel()); }) as ZServerChannel;

            // 允许对 channel 做额外的初始化
            if (this.ChannelOpened != null)
            {
                this.ChannelOpened(channel, new EventArgs());
            }
            try
            {
                string ip = "";

                try
                {
                    ip = GetClientIP(tcpClient);
                    channel.Touch();

                    int  i       = 0;
                    bool running = true;
                    while (running)
                    {
                        if (token != null && token.IsCancellationRequested)
                        {
                            return;
                        }
                        // 注意调用返回后如果发现返回 null 或者抛出了异常,调主要主动 Close 和重新分配 TcpClient
                        BerTree request = await ZProcessor.GetIncomingRequest(
                            cache,
                            tcpClient,
                            () => channel.Touch()).ConfigureAwait(false);  // 2018/10/10 add configure

                        if (request == null)
                        {
                            Console.WriteLine("client close on request " + i);
                            break;
                        }
                        Console.WriteLine("request " + i);

                        channel.Touch();
                        if (token != null && token.IsCancellationRequested)
                        {
                            return;
                        }

                        byte[] response = null;
                        if (this.ProcessRequest == null)
                        {
                            response = await DefaultProcessRequest(channel, request).ConfigureAwait(false);  // 2018/10/10 add configure
                        }
                        else
                        {
                            ProcessRequestEventArgs e = new ProcessRequestEventArgs();
                            e.Request = request;
                            this.ProcessRequest(channel, e);
                            response = e.Response;
                        }

                        channel.Touch();
                        if (token != null && token.IsCancellationRequested)
                        {
                            return;
                        }

                        // 注意调用返回 result.Value == -1 情况下,要及时 Close TcpClient
                        Result result = await ZProcessor.SendResponse(response, tcpClient).ConfigureAwait(false); // 2018/10/10 add configure

                        channel.Touch();
                        if (result.Value == -1)
                        {
                            Console.WriteLine("error on response " + i + ": " + result.ErrorInfo);
                            break;
                        }

                        i++;
                    }
                }
                catch (Exception ex)
                {
                    if (ex.InnerException != null && ex.InnerException is ObjectDisposedException)
                    {
                        // 这种情况一般是 server 主动清理闲置通道导致的,不记入日志
                    }
                    else if (ex is ObjectDisposedException)
                    {
                        // 这种情况一般是 client close 通道导致,不记入日志
                    }
                    else
                    {
                        string strName = "ip:" + ip
                                         + channel == null ? "(null)" : " channel:" + channel.GetHashCode();
                        string strError = strName + " HandleClient() 异常: " + ExceptionUtil.GetExceptionText(ex);
                        LibraryManager.Log?.Error(strError);
                        // Console.WriteLine(strError);
                    }
                }
                finally
                {
#if NO
                    outputStream.Flush();
                    outputStream.Close();
                    outputStream = null;

                    inputStream.Close();
                    inputStream = null;
#endif

                    // tcpClient.Close();

                    // 清除全局结果集
                }
            }
            finally
            {
                _tcpChannels.Remove(channel);
#if NO
                if (this.ChannelClosed != null)
                {
                    ChannelClosedEventArgs e = new ChannelClosedEventArgs();
                    e.Channel = channel;
                    this.ChannelClosed(channel, e);
                }
#endif
                channel.Close();
                if (close_action != null)
                {
                    close_action.Invoke();
                }
            }
        }
Ejemplo n.º 3
0
        // 处理一个通道的通讯活动
        public async void HandleClient(TcpClient tcpClient,
                                       CancellationToken token)
        {
            ZServerChannel channel = _zChannels.Add(tcpClient);

            // 允许对 channel 做额外的初始化
            if (this.ChannelOpened != null)
            {
                this.ChannelOpened(channel, new EventArgs());
            }
            try
            {
                //List<byte> cache = new List<byte>();
                string ip = "";
                //Stream inputStream = tcpClient.GetStream();
                //Stream outputStream = tcpClient.GetStream();

                try
                {
                    ip = GetClientIP(tcpClient);
                    channel.Touch();

                    int  i       = 0;
                    bool running = true;
                    while (running)
                    {
                        // 注意调用返回后如果发现返回 null 或者抛出了异常,调主要主动 Close 和重新分配 TcpClient
                        BerTree request = await ZProcessor.GetIncomingRequest(tcpClient);

                        if (request == null)
                        {
                            Console.WriteLine("client close on request " + i);
                            break;
                        }
                        Console.WriteLine("request " + i);

                        channel.Touch();

                        byte[] response = null;
                        if (this.ProcessRequest == null)
                        {
                            response = await DefaultProcessRequest(channel, request);
                        }
                        else
                        {
                            ProcessRequestEventArgs e = new ProcessRequestEventArgs();
                            e.Request = request;
                            this.ProcessRequest(channel, e);
                            response = e.Response;
                        }

                        channel.Touch();

                        // 注意调用返回 result.Value == -1 情况下,要及时 Close TcpClient
                        Result result = await ZProcessor.SendResponse(response, tcpClient);

                        channel.Touch();
                        if (result.Value == -1)
                        {
                            Console.WriteLine("error on response " + i + ": " + result.ErrorInfo);
                            break;
                        }

                        i++;
                    }
                }
                catch (Exception ex)
                {
                    // 2016/11/14
                    ZManager.Log?.Error("ip:" + ip + " HandleClient() 异常: " + ExceptionUtil.GetExceptionText(ex));
                }
                finally
                {
#if NO
                    outputStream.Flush();
                    outputStream.Close();
                    outputStream = null;

                    inputStream.Close();
                    inputStream = null;
#endif

                    // tcpClient.Close();

                    // 清除全局结果集
                }
            }
            finally
            {
                _zChannels.Remove(channel);
#if NO
                if (this.ChannelClosed != null)
                {
                    ChannelClosedEventArgs e = new ChannelClosedEventArgs();
                    e.Channel = channel;
                    this.ChannelClosed(channel, e);
                }
#endif
                channel.Close();
            }
        }