batinduz/ami-react

异步、事件驱动的Asterisk管理接口(AMI)访问

v0.3.0 2015-03-31 21:41 UTC

This package is not auto-updated.

Last update: 2024-09-20 19:04:25 UTC


README

简单的异步、事件驱动的Asterisk管理接口(AMI)访问

Asterisk PBX是一种流行的开源电话解决方案,提供了一系列的电话功能。《a href="https://wiki.asterisk.org/wiki/display/AST/The+Asterisk+Manager+TCP+IP+API" rel="nofollow noindex noopener external ugc">Asterisk管理接口(AMI)允许您控制和管理PBX。除了其他功能外,它可以用来发起新的呼叫,执行Asterisk命令或监控订阅者、通道或队列的状态。

  • 异步执行操作 - 向Asterisk并行发送任意数量的操作(命令),并尽快处理结果。基于Promise的设计提供了一个合理的接口来处理超出范围的响应。
  • 事件驱动核心 - 注册您的事件处理程序回调,以响应传入的事件,如来电或订阅者状态的改变。
  • 轻量级、SOLID设计 - 提供了一个足够好的薄层抽象,不会干扰您,未来的或自定义的操作和事件不需要进行任何更改即可得到支持。
  • 良好的测试覆盖率 - 配备了自动测试套件,并定期测试,以支持Asterisk 1.8+等旧版本。

快速入门示例

安装后,您可以使用以下代码访问您的本地Asterisk电话实例,并通过AMI发出一些简单的命令:

$loop = React\EventLoop\Factory::create();
$factory = new Factory($loop);

$factory->createClient('user:secret@localhost')->then(function (Client $client) {
    echo 'Client connected' . PHP_EOL;
    
    $sender = new ActionSender($client);
    $sender->listCommands()->then(function (Response $response) {
        echo 'Available commands:' . PHP_EOL;
        var_dump($response);
    });
});

$loop->run();

另请参阅示例

用法

工厂

Factory负责创建您的Client实例。它还负责将所有内容注册到主要的EventLoop

$loop = \React\EventLoop\Factory::create();
$factory = new Factory($loop);

如果您需要自定义DNS或代理设置,您可以显式传递一个自定义的ConnectorInterface实例。

$factory = new Factory($loop, $connector);

createClient()

createClient($amiUrl)方法可用于创建新的Client实例。它有助于建立到AMI的纯TCP/IP或安全SSL/TLS连接,并发出初始的login操作。

$factory->createClient('user:secret@localhost')->then(
    function (Client $client) {
        // client connected and authenticated
    },
    function (Exception $e) {
        // an error occured while trying to connect or authorize client
    }
);

注意:给定的$amiUrl 必须包含主机,它应该包含用户名和密码,它可以包含方案(tcp/ssl)和端口号定义。

Client

Client负责与Asterisk管理接口交换消息,并跟踪待处理操作。

如果您想发送外出操作,请参阅下面的ActionSender类。

on()

使用on($eventName, $eventHandler)方法可以注册新的事件处理程序。传入的事件和错误将被转发到已注册的事件处理程序回调。

$client->on('event', function (Event $event) {
    // process an incoming AMI event (see below)
});
$client->on('close', function () {
    // the connection to the AMI just closed
});
$client->on('error', function (Exception $e) {
    // and error has just been detected, the connection will terminate...
});

close()

使用close()方法可以强制关闭AMI连接并拒绝所有待处理操作。

end()

使用end()方法可以在所有待处理操作完成后软关闭AMI连接。

高级

创建Action对象,通过AMI发送它们,并等待接收到的Response对象,通常隐藏在ActionSender接口后面。

如果您需要自定义或不受支持的行动,也可以按照以下步骤手动执行。不过,建议提交一个PR :)

createAction()

createAction($name, $fields)方法可用于构建自定义AMI行动。会自动添加一个唯一值到"ActionID"字段(用于匹配接收到的响应)。

request()

可以使用request(Action $action)方法将给定的消息排队发送通过AMI,并等待与"ActionID"字段值匹配的Response对象。

ActionSender

ActionSender包装一个给定的Client实例,提供一种简单的方式来执行常见操作。此类表示执行操作并等待相应响应的主要接口。

$sender = new ActionSender($client);

Actions

所有公共方法与其各自的AMI行动相似。

$sender->ping()->then(function (Response $response) {
    // response received for ping action
});

此处不列出所有可用的行动,请参阅类轮廓

处理

发送行动是异步的(非阻塞),因此您实际上可以并行发送多个行动请求。AMI将针对每个行动以Response对象的形式作出响应。顺序没有保证。发送行动使用基于Promise的接口,这使得在行动履行(即成功解决或因错误而拒绝)时作出反应变得容易。

$sender->ping()->then(
    function (Response $response) {
        // response received for ping action
    },
    function (Exception $e) {
        // an error occured while executing the action
        
        if ($e instanceof ErrorException) {
            // we received a valid error response (such as authorization error)
            $response = $e->getResponse();
        } else {
            // we did not receive a valid response (likely a transport issue)
        }
    }
});

自定义行动

使用ActionSender不是强制性的,但推荐用于执行常见操作。

如果您需要新的或不受支持的行动,或者需要额外的参数,也可以手动执行。有关详细信息,请参阅上述高级Client使用。非常感谢更新ActionSender的PR :)

消息

MessageResponseActionEvent值对象的抽象基类。它为这三种消息类型提供了一种公共接口。

每个Message由任意数量的字段组成,每个字段都有一个名称和一个或多个值。字段名称不区分大小写。值的解释是特定于应用程序的。

getFieldValue()

可以使用getFieldValue($key)方法获取给定字段键的第一个值。如果没有找到值,则返回null

getFieldValues()

可以使用getFieldValues($key)方法获取给定字段键的所有值的列表。如果没有找到值,则返回一个空的array()

getFields()

可以使用getFields()方法获取所有字段的数组。

getActionId()

可以使用getActionId()方法获取此消息的唯一行动ID。这是获取"ActionID"字段值的快捷方式。

响应

Response值对象表示从AMI接收到的响应。它共享Message父类的所有属性。

getCommandOutput()

getCommandOutput() 方法可以用来获取 "命令" Action 的输出结果。如果这是对 "命令" 动作的响应,则此值可用,否则默认为 null

$sender->command('help')->then(function (Response $response) {
    echo $response->getCommandOutput();
});

Action

Action 值对象代表要发送到 AMI 的出站动作消息。它继承了 Message 父类的所有属性。

Event

Event 值对象代表从 AMI 收到的入站事件。它继承了 Message 父类的所有属性。

getName()

getName() 方法可以用来获取事件的名称。这是获取 "Event" 字段值的快捷方式。

安装

推荐通过 composer 来安装此库。 对 composer 不熟悉?

{
    "require": {
        "clue/ami-react": "~0.3.0"
    }
}

测试

为了运行测试,您需要 PHPUnit

$ phpunit

测试套件包含单元测试和功能集成测试。功能测试需要访问一个运行中的 Asterisk 服务器实例,默认情况下将跳过这些测试。如果您还想运行功能测试,您需要在环境变量中提供 您自己的 AMI 登录详细信息,如下所示

$ LOGIN=username:password@localhost phpunit

许可

MIT