예제 #1
0
        static int DEFAULT_CLEAR_SECONDS = 10;  // TCP 连接后,登录以前,能存活的秒数。超过这个秒数就可能被管理线程 Close 和清除

        // 处理一个通道的通讯活动
        public async override void HandleClient(TcpClient tcpClient,
                                                Action close_action,
                                                CancellationToken token)
        {
            SipChannel channel = _tcpChannels.Add(tcpClient, () => { return(new SipChannel()); }) as SipChannel;

            channel.Timeout = TimeSpan.FromSeconds(DEFAULT_CLEAR_SECONDS);  // 在登录以前,TCP 连接可以存活 DEFAULT_CLEAR_SECONDS 秒。DEFAULT_CLEAR_SECONDS 秒以后还不接到登录请求,TCP 连接会被自动清除。登录后,Timeout 则会被设置为实例参数 AutoClearSeconds 值

            List <byte> cache = new List <byte>();

            try
            {
                string ip = "";

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

                    int  i       = 0;
                    bool running = true;
                    while (running)
                    {
                        if (token != null && token.IsCancellationRequested)
                        {
                            return;
                        }

                        byte[] response = null;

                        {
                            // TODO: 也可以在这里等待多少秒,然后超时以后,条件符合时,自动清除 TCP 通道。可以弥补管理线程轮次不及时的缺点
                            // 注意调用返回后如果发现返回 null 或者抛出了异常,调主要主动 Close 和重新分配 TcpClient
                            RecvResult result = await TcpChannel.SimpleRecvTcpPackage(tcpClient,
                                                                                      cache,
                                                                                      (package, start, length) =>
                            {
                                return(FindTerminator(package, start, length));
                            },
                                                                                      this.MaxPackageLength).ConfigureAwait(false); // 2018/10/10 add configure

                            if (result.Value == -1)
                            {
                                if (result.ErrorCode == "ConnectionAborted")
                                {
                                    Console.WriteLine("client close on request " + i);
                                }
                                else
                                {
                                    Console.WriteLine("recv error on request " + i + ": " + result.ErrorInfo);
                                }
                                break;
                            }
                            channel.Terminator = (byte)result.Terminator;
                            Console.WriteLine("request " + i);

                            // byte [] 转换为 string

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

                            ProcessSipRequestEventArgs e = new ProcessSipRequestEventArgs();
                            e.Request = result.Package;
                            this.ProcessRequest(channel, e);
                            response = e.Response;
                        }

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

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

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

                        i++;
                    }
                }
                catch (Exception ex)
                {
                    string strError = "ip:" + ip + " HandleClient() 异常: " + ExceptionUtil.GetExceptionText(ex);
                    LibraryManager.Log?.Error(strError);
                    // Console.WriteLine(strError);
                }
                finally
                {
                    // tcpClient.Close();

                    // 清除全局结果集
                }
            }
            finally
            {
                _tcpChannels.Remove(channel);
                channel.Close();
                if (close_action != null)
                {
                    close_action.Invoke();
                }
            }
        }