使用AsterNet从Asterisk拨号计划获取变量值遇超时错误求助
问题分析与解决方案
核心问题原因
你遇到的timeout waiting for response to originate错误,本质是调用GetVarAction时目标通道已经被销毁:拨号计划里执行完set(result=123456)后立刻调用Hangup(),通道直接关闭,此时AMI无法找到对应通道,自然会超时。另外,调用时机错误也是关键——你大概率是在通道挂断后才触发的GetVar方法,这时候已经晚了。
解决方案
方案1:通过自定义事件主动推送变量(推荐)
不需要主动去拉取变量,而是让Asterisk在设置变量后主动把值推送给你的C#程序,这是最可靠的方式。
调整拨号计划
在set之后添加UserEvent发送自定义事件:
exten => test,1, NoOp(************ test ****************); same => n,Answer(); same => n,Playback(hellow-world); same => n,set(result=123456); same => n,UserEvent(CustomResultEvent,result:${result}); ; 发送带变量的自定义事件 same => n,Hangup();
C#代码监听事件
初始化AMI连接时注册UserEvent监听,捕获变量值:
// 初始化Manager连接后注册事件 manager.UserEvent += OnCustomResultEvent; private void OnCustomResultEvent(object sender, UserEventEventArgs e) { // 判断是否是我们定义的自定义事件 if (e.Event.EventName.Equals("CustomResultEvent", StringComparison.OrdinalIgnoreCase)) { string result = e.Event.Attributes["result"]; // 这里处理获取到的result变量 Console.WriteLine($"获取到result变量值: {result}"); } }
方案2:确保调用GetVar时通道仍存活
如果坚持要主动拉取变量,需要保证调用GetVar时通道还没挂断,同时调整拨号计划给程序留足时间。
调整拨号计划
添加Wait指令让通道保持存活一段时间:
exten => test,1, NoOp(************ test ****************); same => n,Answer(); same => n,Playback(hellow-world); same => n,set(result=123456); same => n,Wait(10); ; 等待10秒,给程序足够时间获取变量 same => n,Hangup();
修改C#代码
- 确保在通道处于活跃状态时调用
GetVar(比如在拨号发起后、Playback完成后立刻调用) - 增加超时设置,同时不要吞掉异常:
private string GetVar(string channel) { string result = ""; try { var gv = new GetVarAction(channel, "result"); // 设置5秒超时,避免无限等待 ManagerResponse mr = manager.SendAction(gv, 5000); // 检查响应是否包含result属性 if (mr.Attributes.ContainsKey("result")) { result = mr.Attributes["result"]; } } catch (Exception ex) { // 输出异常信息方便排查 Console.WriteLine($"获取变量失败: {ex.Message}"); } return result; }
方案3:检查AMI权限与连接
确保你的AMI用户拥有足够权限,在/etc/asterisk/manager.conf中配置:
[your_ami_user] secret = your_password read = all ; 至少需要读取变量的权限 write = all
同时确认manager对象已经成功连接到Asterisk的AMI端口(默认5038),连接状态正常。
内容的提问来源于stack exchange,提问作者AminRostami
相关产品推荐
相关产品推荐

