我一直在使用C#构建一个WinForms桌面应用程序,它使用Aster.NET(以前/从Asterisk.NET派生)与Asterisk连接。我们在可靠地识别和跟踪与单个分机/用户相关的呼叫方面遇到了麻烦。
我们遇到的问题是由于Asterisk发起/触发的事件具有不可预测/模糊的特性,根据呼叫在到达扩展名之前的路由方式,它们会发生巨大变化。
例如,事件序列/格式在以下情况下是不同的:呼叫在盲目转移之前命中IVR;如果一个电话在转发之前就打到了IVR;如果通话直接转到用户的分机号。
Asterisk使用不同的唯一ID跟踪呼叫的每一侧的方式进一步阻碍了这一点(例如,呼叫的呼入侧具有与呼叫的接收侧不同的UID)。虽然我们已经设法在(随后丑陋的!)代码中解释了这一点,但我们仍然遇到了考虑调用可以采用的不同路由路径的问题。
因此,我正在寻找有关如何执行以下操作的任何建议:
因为我们现在有一个非常复杂的事件处理程序链,它们的运行方式取决于应用程序的“当前状态”。
举一个例子:如果我们检测到ChannelState为6('Up')的NewStateEvent,我们会检查进程和中是否有正在进行的调用UID匹配,如果是那时当前的电话已经回答了。如果UID不匹配,但其他因素(例如频道,连接线等),则我们将其选为呼叫的“另一侧”(即接收侧或接收侧)。
我不确定API或AMI是否存在问题 - 但不管它是什么导致我们一些真正的麻烦。
任何建议都非常感谢。
答案 0 :(得分:2)
您是否可以更新到Asterisk 12? AMI中的频道名称现在在Asterisk 12中稳定。
https://wiki.asterisk.org/wiki/display/AST/AMI+v2+Specification
答案 1 :(得分: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...");
}
}