anders / ami-react
异步、事件驱动的 Asterisk 管理接口 (AMI) 访问
Requires
- php: >=5.3
- evenement/evenement: ~1.0|~2.0
- react/event-loop: 0.3.*|0.4.*
- react/promise: ~1.0|~2.0
- react/socket-client: 0.3.*|0.4.*
This package is auto-updated.
Last update: 2024-09-29 05:07:36 UTC
README
简单的异步、事件驱动的 Asterisk 管理接口 (AMI) 访问 自定义版本
Asterisk PBX 是一种流行的开源电话解决方案,提供了一系列电话功能。 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(string $amiUrl): PromiseInterface<Client>
方法创建一个新的 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
负责与 Asterisk 管理接口交换消息,并跟踪挂起的动作。
如果您要发送外出动作,请参阅下面的 ActionSender
类。
on()
可以使用 on(string $eventName, callable $eventHandler): void
方法来注册新的事件处理器。传入的事件和错误将被转发到已注册的事件处理器回调中。
$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(): void
方法强制关闭 AMI 连接并拒绝所有挂起操作。
end()
可以使用 end(): void
方法在所有挂起操作完成后软关闭 AMI 连接。
高级
创建 Action
对象,通过 AMI 发送它们,并等待传入的 Response
对象通常隐藏在 ActionSender
接口中。
如果你需要自定义或不受支持的操作,你也可以手动进行。不过,考虑提交一个 PR 吧 :)
createAction()
可以使用 createAction(string $name, array $fields): Action
方法来构建自定义 AMI 操作。会自动添加一个唯一值到 "ActionID" 字段(用于匹配传入的响应)。
request()
可以使用 request(Action $action): PromiseInterface<Response>
方法将给定的消息排队通过 AMI 发送,并等待一个匹配其 "ActionID" 字段值的 Response
对象。
ActionSender
ActionSender
将一个给定的 Client
实例包装起来,提供一种简单的方式来执行常见操作。这个类代表执行操作和等待相应响应的主要接口。
$sender = new ActionSender($client);
动作
所有公共方法都与它们各自的 AMI 操作相对应。
$sender->ping()->then(function (Response $response) { // response received for ping action });
在此处列出所有可用的操作超出了范围,请参阅 类概要。
处理
发送操作是异步的(非阻塞的),因此你实际上可以并行发送多个操作请求。AMI 将对每个操作响应一个 Response
对象。顺序没有保证。发送操作使用基于 Promise 的接口,这使得在操作 fulfilled(即成功解决或因错误而拒绝)时做出反应变得容易。
$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 :)
消息
Message
是 Response
、Action
和 Event
值对象的抽象基类。它为这三种消息类型提供了一个通用接口。
每个 Message
由任意数量的字段组成,每个字段都有一个名称和一个或多个值。字段名称不区分大小写。值的解释是应用特定的。
getFieldValue()
可以使用 getFieldValue(string $key): ?string
方法来获取给定字段键的第一个值。如果没有找到值,则返回 null
。
getFieldValues()
可以使用 getFieldValues(string $key): string[]
方法来获取给定字段键的所有值的列表。如果没有找到值,则返回一个空的 array()
。
getFields()
可以使用 getFields(): array
方法来获取所有字段的数组。
getActionId()
可以使用 getActionId(): string
方法来获取此消息的唯一操作 ID。这是获取 "ActionID" 字段值的快捷方式。
响应
《Response》值对象表示从 AMI 收到的入站响应。它共享Message
父类的所有属性。
getCommandOutput()
可以使用 getCommandOutput(): ?string
方法来获取 "command" Action
的输出结果。如果这个响应实际上是对 "command" 动作的响应,则此值可用;否则默认为 null
。
$sender->command('help')->then(function (Response $response) { echo $response->getCommandOutput(); });
动作
《Action》值对象表示要发送到 AMI 的出站动作消息。它共享Message
父类的所有属性。
事件
《Event》值对象表示从 AMI 收到的入站事件。它共享Message
父类的所有属性。
getName()
可以使用 getName(): ?string
方法来获取事件的名称。这是获取 "Event" 字段值的快捷方式。
安装
推荐通过 Composer 安装此库。 初次使用 Composer?
这将安装最新支持的版本
$ composer require clue/ami-react:^0.3
有关版本升级的详细信息,请参阅变更日志。
测试
为了运行测试,您需要 PHPUnit
$ phpunit
测试套件包含单元测试和功能集成测试。功能测试需要访问正在运行的 Asterisk 服务器实例,并且默认会跳过。如果您还想运行功能测试,您需要提供类似以下的 您自己的 AMI 登录详情到环境变量中
$ LOGIN=username:password@localhost phpunit
许可
MIT