You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 16:52:48