Asterisk без внешних компонент?


Да, не вопрос! Причем, это делается просто до безобразия! И сейчас, мы с этим  безобразием разберемся. К тому же, у безобразия есть нюансы. Заодно, разберемся с особенностями AMI поверх HTTP.

Будет много текста, да еще и без картинок. Заранее благодарен тем, кто дочитает статью до конца. Постараюсь как минимум не быть нудным 🙂

 

Раздел для тех, кто не в теме.

 

Кто уже читал мои предыдущие статьи и знает про AMI (Asterisk Manager Interface) и AJAM, может смело пропустить этот раздел.

AMI – это интерфейс управления Asterisk-ом. Но, подключения к AMI, как и девушки, бывают разные. Два основных:

  1. AMI поверх TCP, который часто называют просто AMI
  2. AMI поверх HTTP, его еще называют AJAM (Asynchronous Javascript Asterisk Manager). Хотя, особой асинхронности я там не увидел.

Если объяснять на пальцах, то разница между 1 и 2, как между толстым и веб-клиентом. Ссылка для тех, кто-то хочет накуриться правильных английских мануалов.

Внешняя компонента ROM-Asterisk может использовать оба способа подключения.
Внешняя компонента от МИКО использует только AJAM.
Но нам, они пока не нужны – мы будем подключаться без них.

 

Настройка AJAM на стороне Asterisk

 

Ребята из МИКО написали хорошую статью о том, как выполнить настройку AJAM в Asterisk. Вдаваться в детали настройки мы не будем, это больше для админа, дайте ему ссылку, пусть настраивает.

 

Кодировщики AJAM

 

Что еще нам нужно знать про AJAM? В нем есть разные типы кодировщиков ответов:

  1. rawman – самый простой, которым мы и будем пользоваться
  2. arawman – тоже самое, что и rawman, плюс использование более навороченной HTTP-digest аутентификации с MD5-хешами
  3. mxml – ответы сервера кодируются в XML
  4. manager – кодирует ответы в простые HTML-формы. Этот кодировщик годится разве что на побаловаться вначале

Схема работы с AJAM

 

Те, кто уже работал с HTTP-сервером, этот раздел могут пропустить.
Важно понимать, что мы работаем с HTTP-сервером. Понятно, что сразу после получения нами HTTP-ответа, сервер разорвет соединение.

Схема будет такой: Connect -> Запрос -> Ответ -> Disconnect

Если хочется еще что-то спросить у Asterisk-а, тогда добро пожаловать в новую итерацию. Это вам не AMI поверх TCP, когда можно 1 раз «зацепиться» за сервер и просто слушать события.

 

Алгоритм наших действий

 

Не менее важно понимать сам алгоритм наших действий. По шагам:

  1. Устанавливаем HTTP-соединение
  2. Авторизуемся. При удачной авторизации, сервер вернет нам Cookie, который мы прихраним для использования в следующем HTTP-запросе
  3. Выполняем нужный нам HTTP-запрос, обновляем Cookie.

Реализация

 

Считаем, что админ уже все настроил и можно приступать.
Все, что нам нужно – это HTTPСоединение и ровные руки, чтобы отправлять ровные запросы.

Код работы с Asterisk настолько тривиальный, что его нет смысла здесь приводить. Все сводится к элементарной отправке и чтению HTTP-запросов. Не верите? Смотрите сами:

Организация соединения:

Соединение=Новый HTTPСоединение(IP,Port,,,,Таймаут,);

Отправка и чтение запроса:

ТекстКоманды=«/asterisk/rawman?action=…бла-бла-бла»;
Запрос=Новый HTTPЗапрос();
Запрос.АдресРесурса=ТекстКоманды;
Ответ=Соединение.Получить(Запрос);

Это все 🙂

 

Ложка дегтя

 

Когда мы сами являемся источником события, то все вроде бы как хорошо. А вот, когда мы являемся потребителями и хотим просто слушать, то не все так гладко.

Перефразируя мем «нельзя просто так взять и получать события по AJAM». При работе через AJAM нам нужно будет периодически задалбывать HTTP-сервер запросами типа «Сервер, там для меня случайно нет событий?».

Допустим, нам нужно получить инфу о том, что на нас идет входящий звонок. Тогда нам нужен какой-то обработчик ожидания, который периодически будет опрашивать HTTP-сервер.

Именно для такого случая, придумали AMI-команду WaitEvent. Она делает следующую вещь — говорит Asterisk-у: «Мол, я тут событие жду. Не разрывай пож-та соединение пока оно не придет. Я готов ждать максимум 30 секунд». Asterisk конечно же так и поступит.

Но, все это время, пока мы ждем событие, наш HTTP-запрос будет находиться в «висячем» состоянии и клиентское окно 1С будет выглядеть зависшим.

  1. Пользователю, независимо от пола, «висячее» состояние вряд ли понравится
  2. Сервер тратит свои ресурсы на поддержание открытой сессии

Вы спросите, а может делать частые HTTP-запросы, допустим каждые 10 секунд, с таймаутом ожидания 10 секунд?
Может быть… Я же не знаю вашей нагрузки на Asterisk и на 1С.
ИМХО, здесь важно найти оптимальный баланс — и сервер не задолбать, и не пропустить важное событие AMI.

 

И что с этим делать?

 

Думаю, нужно подбирать решение по конкретной ситуации. Обращайтесь – помогу, если смогу.

В качестве абстрактных рекомендаций, могу сказать следующее:

  1. Ищите, тестируйте и найдете. Весь инструмент во вложенной к статье обработке. Поиграйтесь с частотой запросов и с таймаутом ответа.
  2. Пофильтруйте события – хотя бы уберите лишние классы событий. Об этом написано в других моих статьях.

Если пользователь использует толстый клиент, то скорее всего, он сидит внутри сети. Тогда нечего заморачиваться, можно использовать обычный AMI через TCP. Подключаем этого пользователя через ROM-Asterisk и пусть себе работает.

Если пользователь использует тонкий клиент и сидит внутри сети, тогда тоже самое – AMI поверх TCP и ROM-Asterisk. Кстати, тонкому клиенту удаленному, но с хорошим каналом, это тоже подойдет.

Если пользователь использует веб-клиент или же тонкий клиент на нестабильном канале, тогда однозначно AJAM.

 

Небольшой хак

 

Если у пользователя НЕ веб-клиент, но вы хотите использовать именно AJAM, а не AMI, тогда могу вам дать хорошую подсказку, как уйти от «висячего» HTTP-запроса.

Вместо объекта HTTPСоединение можно использовать соединение ROM-Asterisk, а вместо объекта HTTPЗапрос использовать метод ВыполнитьКоманду. В этом случае, подмерзания не будет – ответ придет асинхронно, как внешнее событие. Вы отдали команду и забыли, когда придет ответ – Asterisk вам сам скажет.
Выложу реализацию этого хозяйства в отдельной статье.

 

Выводим выводы

 

Подключаться к AJAM без внешних компонент можно и это совершенно не сложно. Хотя, с точки зрения производительности, это не всегда оптимально. Иногда вместо HTTP-соединения, правильнее использовать соединение по TCP. Может в будущем в 1С появится объект TCPСоединение, а пока для этого нужны внешние компоненты.

Использовать AJAM лучше там, где это действительно нужно. Если можно использовать AMI поверх TCP – используйте, с ним проще. На нем можно делать всякие потрясающие штуки. Зато, AJAM – отличное решение для веб-клиента или плохих каналов.

К статье приложена внешняя обработка AJAM, которая будет работать как в режиме управляемого приложения, так и в обычном режиме.

Успешной вам разработки!

22 Comments

  1. asved.ru

    А WaitEvent можно отправить в фоновое задание.

    Reply
  2. zfilin

    Хотел тебе ссылку отправить, мол, смотри какая крутецкая статья по Asterisk. А это ты ее и написал. =)))

    Reply
  3. oleg.rizvanov

    (1) asved.ru,

    Наверное можно. Всегда считал, что фоновое задание выполняется на стороне сервера, а нам вроде как надо клиенту результат отдать…

    Не до конца понимаю, как фоновое задание использовать для данной задачи? Приведете пример?

    Reply
  4. oleg.rizvanov

    (2) zfilin,

    Привет, Саша. Стараюсь для сообщества 🙂

    Reply
  5. asved.ru

    (3) честно говоря, разбираться некогда, суть в том, что этим мы избежим «зависания» на стороне пользователя. Правда, инициализировать проверку результата все равно придется со стороны клиента, через ОбработкаОжидания(), к примеру. Но это уже в рамках 1С, что, я полагаю, существенный плюс.

    Reply
  6. oleg.rizvanov

    (5) asved.ru,

    А в именно чем плюс? Какая разница кого периодически опрашивать HTTP-сервер или 1С-сервер?

    Тогда уже лучше не париться с родным объектом HTTPСоединение, а использовать XMLHTTPRequest

    Reply
  7. shmellevich

    Если пользоваться

    Ответ=Соединение.Получить(Запрос);

    для получения ответа от сервера, то нужно автору уточнить, что версия платформы должна быть не ниже 8.2.18, ибо только в этом релизе уже есть HTTPОтвет.

    Reply
  8. oleg.rizvanov

    (7) shmellevich,

    Да, действительно, этот момент я как-то упустил.

    Спасибо за важное уточнение.

    Reply
  9. shmellevich

    (8)

    Пожалуйста, конструкция сразу глаз начала резать 😉

    К хорошему быстро привыкаешь, тестил 8.3, да так увлекся, что начал теряться, где что работает )))

    Reply
  10. oleg1979

    Подскажите пожалуйста, можно ли в 1С 8.2 при дозвонке на какой либо номер через Asterisk определять статусы звонков «занято», «нет ответа», «трубка поднята»?

    Reply
  11. oleg.rizvanov

    (10) oleg1979,

    Можно. Поднимите ветку с этим вопросом в форуме Simplit — вам ответят

    Reply
  12. Aspirant

    когда будет кросс платформенное решение ? Очень хочется на линукс пересесть..

    Reply
  13. Aspirant

    еще какой командой можно выцепить имя файла записи разговора?

    Reply
  14. Aspirant

    в веб клиенте не получится? Там не работает HTTPСоединение

    Reply
  15. oleg.rizvanov

    (14) Aspirant,

    Для веб-клиента этот объект недоступен. Попробуйте обойти через сервер.

    Reply
  16. Rustig

    (0) подскажите, пож-та, скачал вашу обработку, при указании айпи-адреса, логина и пароля, не логинится сервер. выдается ошибка

    <!DOCTYPE HTML PUBLIC «-//IETF//DTD HTML 2.0//EN»>

    <html><head>

    <title>404 Not Found</title>

    </head><body>

    <h1>Not Found</h1>

    <p>The requested URL was not found on this server.</p>

    <hr />

    <address>Asterisk Server</address>

    </body></html>

    Reply
  17. kuzz

    (16) Добрый день! Получаю такую же ошибку. Удалось ли решить проблему?

    Reply
  18. Rustig

    (17) ее решил сисадмин, который настраивал ами

    Reply
  19. kuzz

    (18) Спасибо! Да, верно. Эта ошибка, всего навсего, вызвана отсутствием доступа к сервису AJAM на стороне сервера. Требовалось корректно настроить сервер

    Reply
  20. Zixxx

    А как организована запись звонка, и получение его по какому-то идентификатору?

    Reply
  21. Denanhel

    Ризванову огромный респект. Данна публикация позволила организовать полноценную конфигурацию для колл-центра. Причем, что примечательно без всяких внешних компонент. Именно колл-центр только звонки, только хардкор. Всем советую обратить внимание на следующую страницу http://wiki.simplit.info/doku.php/doc/ami/action . Все методы работают так что получите и распишитесь.

    Reply
  22. user986187

    Здравствуйте, интересует вопрос интеграции 1С УНФ с астериск (FREE PBX).

    Как с вами связаться.

    wrofdt@ya.ru

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *