AsterNet中ConnectionState异常:断网后IsConnected仍返回true
解决AsterNET ManagerConnection网络断开后状态检测不准确的问题
问题根源
TCP连接在底层网络断开(比如拔网线)时,不会立即触发连接状态变更——如果没有数据交互,系统无法感知连接已失效。IsConnected()仅检查本地连接状态标记,无法实时验证网络连通性,这就是它返回true的原因。
解决方案
1. 启用AsterNET内置心跳机制
AsterNET的ManagerConnection支持心跳包配置,定期发送检测请求确认连接有效性,心跳超时后会自动更新状态并触发ConnectionStateEvent。修改你的StartManager方法:
using AsterNET.Manager; using AsterNET.Manager.Event; using AsterNET.Manager.Action; private ManagerConnection manager; private bool StartManager() { manager = new ManagerConnection( Properties.Resources.amiAddress, int.Parse(Properties.Resources.amiPort), Properties.Resources.amiLogin, Properties.Resources.amiPass ); // 启用心跳配置 manager.SendHeartbeat = true; manager.HeartbeatInterval = 5000; // 每5秒发送一次心跳 manager.HeartbeatTimeout = 10000; // 10秒未收到响应则判定断开 manager.ConnectionState += ConnectionState; try { manager.Login(); return true; } catch { return false; } }
2. 优化连接状态事件处理
不要仅依赖IsConnected(),直接使用ConnectionStateEvent的State属性判断,它能给出更明确的连接状态:
private void ConnectionState(object sender, ConnectionStateEvent e) { switch (e.State) { case ConnectionState.Connected: MessageBox.Show("连接已建立"); notifyIcon1.Icon = Properties.Resources.phone_on; break; case ConnectionState.Disconnected: MessageBox.Show("连接已断开"); notifyIcon1.Icon = Properties.Resources.phone_off; break; case ConnectionState.Attempting: // 可选:添加正在重连的提示 break; } }
3. 主动发送测试命令验证连接(可选)
如果心跳机制不够满足需求,可以定期主动发送轻量AMI命令(如Ping)验证连接,失败则主动更新状态:
private async Task<bool> CheckConnectionValidity() { if (!manager.IsConnected()) return false; try { // 发送Ping命令,Asterisk会响应Pong var pingResponse = await manager.SendActionAsync(new PingAction()); return pingResponse != null; } catch { // 发送失败,主动断开并更新状态 if (manager.IsConnected()) { manager.Logoff(); } return false; } }
可以用定时器定期执行检查(比如每10秒一次):
private System.Timers.Timer connectionCheckTimer; // 在StartManager成功后初始化定时器 private void InitializeConnectionChecker() { connectionCheckTimer = new System.Timers.Timer(10000); connectionCheckTimer.Elapsed += async (s, e) => await CheckConnectionValidity(); connectionCheckTimer.AutoReset = true; connectionCheckTimer.Start(); }
关键提示
- TCP的“半开连接”是核心问题,必须通过主动数据交互(心跳或测试命令)才能检测到底层网络断开。
- 启用内置心跳是最简便的方案,AsterNET会自动处理心跳发送和超时判定,无需额外编写大量代码。
- 事件处理优先使用
ConnectionStateEvent.State,它是AsterNET内部根据连接状态变更触发的,比直接调用IsConnected()更可靠。
内容的提问来源于stack exchange,提问作者Dmitriy G
相关产品推荐
相关产品推荐

