artem
13.03.2018
883

Скрипт-парсер AMI событий.

Чтобы создать нового пользователя для AMI можете ознакомиться со статьей: https://voxlink.ru/kb/freepbx/asterisk-manager-interface-v-FreePBX%2013/

Мы же остановимся на программной реализации самого парсера. За основу будет взят серверный скриптовый язык PHP. Выбор обоснован простотой реализации и демонстрации результата пользователю.

Непосредственно код скрипта. Его можно сразу же использовать, заменив соответствующие поля для доступа к AMI на собственные. Так же внимательный читатель может обратить внимание на указание доступов к бд mysql. Все верно. Если нам необходимо не только видеть происходящие на сервере события но и, скажем, демонизировать парсер и установить ответную реакцию на события, то следует добавить это в скрипт. В данном примере будет переписываться состояние пиров в базе.

Перейдем непосредственно к пояснениям по скрипту:

На момент запуска скрипта необходимо убедиться в создании базы, таблицы и верности полей, которые будут использоваться

MariaDB [(none)]> CREATE DATABASE phoenix;
MariaDB [(none)]> USE phoenix;
MariaDB [phoenix]> CREATE TABLE extens_status(
exten VARCHAR(100) NOT NULL,
status VARCHAR(100) NOT NULL,
last_update VARCHAR(100) NOT NULL);

Обратите внимание, поля в таблице только обновляются! Поэтому перед использованием таблицу необходимо заполнить значениями по умолчанию. Для этого выполняем по всем внутренним номерам:

MariaDB [phoenix]> INSERT INTO extens_status VALUES (‘SIP/103′,’-‘,’-‘);

В итоге должно получится что-то аналогичное:

Подготовка БД к работе

Указываем параметры подключения к базе данных mysql:

define(‘bd_host’,’localhost’);
define(‘bd_user’,’login’);
define(‘bd_pass’,’password’);

Указываем параметры подключения к AMI

define(‘ami_host’,’localhost’);
define(‘ami_port’,’5038′);
define(‘ami_user’,’fromami’);
define(‘ami_pass’,’testamiconnecter’);

Функция облегчающая обращения из PHP в mysql и возвращающая результат. Если в процессе работы парсера есть необходимость выводить SQL код запроса можно снять комментарий «//» перед «echo».

function bd_bridge($db,$q){
                    $link = mysqli_connect(bd_host,bd_user,bd_pass,$db) or die(«Ошибка: «.mysqli_connect_error($link));
                    $rs = mysqli_query($link, $q) or die(«Ошибка: «.mysqli_error($link));
                    if($rs){                                          //echo «Запрос выполнен успешно: rn $q rn»;
                                         return $rs;
                                         mysqli_free_result($result);
                    }
                    else{
                                         echo «Запрос не выполнен: rn $q rn»;
                    }
                    mysqli_close($link);
}

Функция ответной реакции. Вызывает делает обращение в базу данных посредством описанной выше функции bd_bridge.

function peers_status_update($status,$peer){
                    bd_bridge(‘phoenix’,’UPDATE extens_status SET status=»‘.$status.'»,last_update=»‘.date(«Y-m-d_H:i:s»).'» where exten=»‘.$peer.'» ;’);
}

Приготовления завершены, переходим к AMI событиям. Первым делом нам нужно объявить элемент сокета, а для этого открыть соединения по предустановленным параметрам подключения.

$socket = fsockopen(ami_host,ami_port, $errno, $errstr, 1500 );
Следующим шагом проходим авторизацию, чтобы получить доступ к терминалу AMI.
fputs($socket, «Action: Loginrn»);
fputs($socket, «Username: «.ami_user.»rn»);
fputs($socket, «Secret: «.ami_pass.»rnrn»);

На этом моменте, мы должны при выполнении скрипта увидеть в консоли ответ о подключении к сокету и успешной авторизации:

Успешная авторизация

Запускаем бесконечный цикл прослушивания сокета:

while (!feof($socket)) {
                    $m=array();
                    $mm=array();
                    $res=array();
                    $content=»;
                    $j=0;
 
                    $content .= fread($socket,1024);
                    $mm = explode («rn»,$content);

И приступаем к самому интересному: разбору конвейера событий:

                    for($i=0;$i<count($mm);$i++){
                                         $m=explode(«:»,$mm[$i]);
                                         if (isset($m[1])){
                                                             if(trim($m[0])==’Event’){
                                                                                 $j++;
                                                             }
                                                             $res[$j][trim($m[0])]=trim($m[1]);
                                         }
                    }

Но в предыдущем пункте мы лишь сформировали массив из событий. Для удобства эксплуатации массив ассоциативный, вида «оператор : параметр».

                    foreach($res as $massiv){
                                         switch ($massiv[‘Event’]) {
                                                             case ‘PeerStatus’:
                                                                                 peers_status_update($massiv[‘PeerStatus’],$massiv[‘Peer’]);
                                                                                 echo $massiv[‘PeerStatus’];
                                                             break;
                                         }
                                         print_r($massiv);
                    }

Здесь обрабатывается ответная реакция если в сообщении будет заголовок со словом «Event» (событие). И вызывается соответствующая ему функция с передачей ей параметров из события.

                    sleep(0.005);
}

Поскольку бесконечный цикл может израсходовать все процессорное время, необходимо установить задержку в некоторый минимальный интервал времени.

fputs($socket, «Action: Logoffrnrn»);
fclose($socket);

И по завершении работы скрипта, хорошо бы все закрыть, для корректности работы и валидности кода.

 

И в итоге скрипт-парсинга AMI целиком. При использовании указывать свои данные для регистрации.

<?php
 
define(‘bd_host’,’localhost’);
define(‘bd_user’,’root’);
define(‘bd_pass’,’wsad’);
define(‘ami_host’,’localhost’);
define(‘ami_port’,’5038′);
define(‘ami_user’,’fromami’);
define(‘ami_pass’,’testamiconnecter’);
 
function bd_bridge($db,$q){
                    $link = mysqli_connect(bd_host,bd_user,bd_pass,$db) or die(«Ошибка: «.mysqli_connect_error($link));
                    $rs = mysqli_query($link, $q) or die(«Ошибка: «.mysqli_error($link));
                    if($rs){
                                        //echo «Запрос выполнен успешно: rn $q rn»;
                                         return $rs;
                                         mysqli_free_result($result);
                    }
                    else{
                                         echo «Запрос не выполнен: rn $q rn»;
                    }
                    mysqli_close($link);
}
 
function peers_status_update($status,$peer){
                    bd_bridge(‘phoenix’,’UPDATE extens_status SET status=»‘.$status.'»,last_update=»‘.date(«Y-m-d_H:i:s»).'» where exten=»‘.$peer.'» ;’);
}
 
$socket = fsockopen(ami_host,ami_port, $errno, $errstr, 1500 );
 
fputs($socket, «Action: Loginrn»);
fputs($socket, «Username: «.ami_user.»rn»);
fputs($socket, «Secret: «.ami_pass.»rnrn»);
 
while (!feof($socket)) {
                    $m=array();
                    $mm=array();
                    $res=array();
                    $content=»;
                    $j=0;
 
                    $content .= fread($socket,1024);
                    $mm = explode («rn»,$content);
 
                    for($i=0;$i<count($mm);$i++){
                                         $m=explode(«:»,$mm[$i]);
                                         if (isset($m[1])){
                                                             if(trim($m[0])==’Event’){
                                                                                 $j++;
                                                             }
                                                             $res[$j][trim($m[0])]=trim($m[1]);
                                         }
                    }
 
                    foreach($res as $massiv){
                                         switch ($massiv[‘Event’]) {
                                                             print_r($massiv);
                                                             case ‘PeerStatus’:
                                                                                 peers_status_update($massiv[‘PeerStatus’],$massiv[‘Peer’]);
                                                                                 echo $massiv[‘PeerStatus’];
                                                             break;
                                         }
                    }
                    sleep(0.005);
}
fputs($socket, «Action: Logoffrnrn»);
fclose($socket);
?>

 
avatar
  Подписаться  
Уведомление о

Остались вопросы?

Я - Першин Артём, менеджер компании Voxlink. Хотите уточнить детали или готовы оставить заявку? Укажите номер телефона, я перезвоню в течение 3-х секунд.

VoIP оборудование

ближайшие курсы

ближайшие Вебинары

ONLINE

Why Choose HUGE?

Unlimited pre-designed elements

Each and every design element is designed for retina ready display on all kind of devices

User friendly interface and design

Each and every design element is designed for retina ready display on all kind of devices

100% editable layered PSD files

Each and every design element is designed for retina ready display on all kind of devices

Created using shape layers

Each and every design element is designed for retina ready display on all kind of devices