6

我一直在使用 C# 构建一个 WinForms 桌面应用程序,该应用程序使用 Aster.NET(以前/从 Asterisk.NET 派生)与 Asterisk 接口。我们在可靠地识别和跟踪与单个分机/用户相关的呼叫时遇到了真正的麻烦。

我们遇到的问题是由于 Asterisk 触发/触发的事件的不可预测性/模糊性,它们的变化很大,具体取决于呼叫在到达扩展之前的路由方式。

例如,在以下情况下,事件顺序/格式会有所不同: 呼叫在盲转之前到达 IVR;如果呼叫在有人转接之前到达 IVR;如果呼叫直接转到用户的分机。

Asterisk 使用不同的唯一 ID 跟踪呼叫的每一方的方式进一步阻碍了这一点(例如,呼叫的传入侧与呼叫的接收侧具有不同的 UID)。虽然我们已经设法在(随后变得丑陋!)代码中考虑到这一点,但我们仍然遇到了考虑调用可以采用的不同路由路径的问题。

因此,我正在寻找有关我们如何执行以下操作的任何建议:

  1. 可靠地识别用户分机的来电
    • 我们需要能够识别被呼叫的分机和主叫方 ID(在盲转或有人值守转接和来自外部的直接呼叫之后)
    • 可靠地跟踪来电的唯一 ID,因为它用于链接到通话记录
  2. 可靠地识别来自用户分机的拨出电话
    • 考虑到与上述相同的警告

就目前而言,我们有一个极其复杂的事件处理程序链,它们的操作方式取决于应用程序的“当前状态”。

举一个例子:如果我们检测到一个 ChannelState 为 6 ('Up') 的 NewStateEvent,我们检查是否有正在进行的呼叫,并且UID 匹配,如果是,则当前呼叫已被应答。如果 UID 不匹配,但其他因素匹配(例如 channel、connectedlinenum 等),那么我们将其视为呼叫的“另一端”(即接收端或传入端)。

我不确定问题出在 API 上还是 AMI 上——但不管是哪一个,它都让我们非常头疼。

非常感谢任何建议。

4

2 回答 2

2

您可以更新到 Asterisk 12 吗?AMI 中的通道名称现在在 Asterisk 12 中是稳定的。

https://wiki.asterisk.org/wiki/display/AST/AMI+v2+Specification

于 2014-02-01T06:08:47.760 回答
1

我在 c# 中使用包 Aster.NET。首先安装最新的 aster.net 软件包,而
不是检查代码。这段代码对我来说非常完美。

        manager = new ManagerConnection(address, port, user, password);
        manager.UnhandledEvent += new ManagerEventHandler(manager_Events);
        manager.NewState += new NewStateEventHandler(Monitoring_NewState);
        try
        {
            // Uncomment next 2 line comments to Disable timeout (debug mode)
            // manager.DefaultResponseTimeout = 0;
            // manager.DefaultEventTimeout = 0;


            manager.Login();

            if (manager.IsConnected())
            {



                Console.WriteLine("user name  : " + manager.Username);






                Console.ReadLine();

            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error connect\n" + ex.Message);
            manager.Logoff();
            Console.ReadLine();

        }
        void manager_Events(object sender, ManagerEvent e)
        {
            Console.WriteLine("Event : " + e.GetType().Name);

        }

           void Monitoring_NewState(object sender, NewStateEvent e)
              {
            string state = e.State;
            string callerID = e.CallerId;

            Console.WriteLine("caller  num ...", e.CallerIdNum);

            //Console.WriteLine("state =", state);

            //Console.WriteLine("callerID =", callerID);



            if ((state == "Ringing") | (e.ChannelState == "5"))
            {

                Console.WriteLine("hello rining your phone now ...");

                String connectedLineNum;
                String connectedLineName;

                Dictionary<String, String> attributes = e.Attributes;

                attributes.TryGetValue("connectedlinenum", out connectedLineNum);
                attributes.TryGetValue("connectedlinename", out connectedLineName);
                // "callerID" - called phone number
                // "connectedLineNum" - calling phone number



                // CallIn. Incoming call
            }
            else if ((state == "Ring") | (e.ChannelState == "4"))
            {

                Console.WriteLine("hello out going your call ...");
                // CallOut. Outcoming call
            }
            else if ((state == "Up") | (e.ChannelState == "6"))
            {
                String connectedLineNum;
                String connectedLineName;


                Dictionary<String, String> attributes = e.Attributes;

                attributes.TryGetValue("connectedlinenum", out connectedLineNum);
                attributes.TryGetValue("connectedlinename", out connectedLineName);
                // "callerID" - called phone number
                // "connectedLineNum" - calling phone number

                // human lifted up the phone right no

                Console.WriteLine("human lifted up the phone...");



            }

        }
于 2019-09-23T06:10:51.220 回答