====== Прослушивание событий, передаваемых сервером Asterisk из 1С ======
После инициализации и авторизации компонента на сервере Asterisk между компонентом и сервером устанавливается HTTP соединение, по которому сервер телефонии передает информацию о текущем состоянии каналов, вызовов, а так же результат выполнения различных команд. Полученные ответы разбираются компонентом при помощи встроенного XML парсера и вызывают в сеансе 1С:Предприятия встроенную функцию *ВнешнееСобытие*.
Вызов функции возникает при посылке внешним приложением сообщения, сформированного в специальном формате. Внешнее событие сначала обрабатывается всеми открытыми формами, имеющими обработчик этого события, а затем может быть обработано в процедуре модуля обычного приложения с именем ОбработкаВнешнегоСобытия.
Таким образом, все события компонента можно обработать в любой открытой форме или в модуле обычного приложения. В качестве переменных используются 3 строковых параметра:
* Источник - Источник внешнего события.
* Событие - Наименование события.
* Данные - Данные для события.
В параметр *Источник* всегда передается строка //MikoAjamEvent// которая позволяет однозначно идентифицировать события отправленные компонентой.
В параметр *Событие* передается наименование [[kb:asterisk:events|события Asterisk]] или строки //Error//, //Exeption//, свидетельствующие о возникновении нештатной ситуации, например разрыв связи с Asterisk.
В параметр *Данные* передается XML строка, содержащая весь пакет данных, полученных от сервера Acterisk без каких либо модификаций или техническую информацию о ошибке в работе компонента.
Стандартный вид обработки внешнего события компоненты выглядит так:
Процедура ВнешнееСобытие(Источник, Событие, Данные)
Если Источник="MikoAjamEvent" Тогда // проверим ответ от нашей ли компоненты?
Если Событие="Error"
Возврат; // тут надо разбираться в причинах сбоя, иногда они штатные и требуют просто переподключения компоненты.
КонецЕсли;
//ПРИМЕР ОТВЕТА
Попытка
Если Событие="Hangup" Тогда //Положили трубку
//ПРИМЕР ОТВЕТА В ПЕРЕМЕННОЙ "ДАННЫЕ"
//
ИначеЕсли Событие="Bridge" Тогда //2 абонента соединились и разговаривают
//ПРИМЕР ОТВЕТА В ПЕРЕМЕННОЙ "ДАННЫЕ" исходящий звонок с 263 на 04
//
//Пример ответа Входящий звонок с 79265557842 на мультифонтранк
//
ИначеЕсли Событие="Unlink" Тогда
//ПРИМЕР ОТВЕТА В ПЕРЕМЕННОЙ "ДАННЫЕ"
//
ИначеЕсли Событие="Dial" Тогда //Входящий звонок до поднятия трубочки
//ПРИМЕР ОТВЕТА В ПЕРЕМЕННОЙ "ДАННЫЕ" при внешнем входящем звонке с номера 79265557842 на мультифон транк
//
ИначеЕсли Событие="PeerStatus" Тогда
//ПРИМЕР ОТВЕТА В ПЕРЕМЕННОЙ "ДАННЫЕ"
//
ИначеЕсли Событие="VarSet" Тогда
//ПРИМЕР ОТВЕТА В ПЕРЕМЕННОЙ "ДАННЫЕ"
//
ИначеЕсли Событие="Newchannel" Тогда
//ПРИМЕР ОТВЕТА В ПЕРЕМЕННОЙ "ДАННЫЕ" Звоню с номера 263 на номер 17
//
// />
//ПРИМЕР ОТВЕТА В ПЕРЕМЕННОЙ "ДАННЫЕ" Звоню с номера 74997623634 на номер 229-30-42 оператора МАНГО
//
ИначеЕсли Событие="Newstate" Тогда
//ПРИМЕР ОТВЕТА В ПЕРЕМЕННОЙ "ДАННЫЕ"
//
ИначеЕсли Событие="Newexten" Тогда
//ПРИМЕР ОТВЕТА В ПЕРЕМЕННОЙ "ДАННЫЕ"
//
ИначеЕсли Событие="NewCallerid" Тогда
//ПРИМЕР ОТВЕТА В ПЕРЕМЕННОЙ "ДАННЫЕ"
//
ИначеЕсли Событие="Registry" Тогда
//ПРИМЕР ОТВЕТА В ПЕРЕМЕННОЙ "ДАННЫЕ"
//
ИначеЕсли Событие="ExtensionStatus" Тогда
//ПРИМЕР ОТВЕТА В ПЕРЕМЕННОЙ "ДАННЫЕ"
//
ИначеЕсли Событие="Cdr" Тогда
//ПРИМЕР ОТВЕТА В ПЕРЕМЕННОЙ "ДАННЫЕ"
//
ИначеЕсли Событие="SkypeBuddyStatus" Тогда
//ПРИМЕР ОТВЕТА В ПЕРЕМЕННОЙ "ДАННЫЕ"
//
ИначеЕсли Событие="SkypeChatMessage" Тогда
//ПРИМЕР ОТВЕТА В ПЕРЕМЕННОЙ "ДАННЫЕ"
//
ИначеЕсли Событие="ReceiveFAX" Тогда
//ПРИМЕР ОТВЕТА В ПЕРЕМЕННОЙ "ДАННЫЕ"
//
ИначеЕсли Событие="SendFAX" Тогда
//ПРИМЕР ОТВЕТА В ПЕРЕМЕННОЙ "ДАННЫЕ"
//
ИначеЕсли Событие="RTPReceiverStat" Тогда
//ПРИМЕР ОТВЕТА В ПЕРЕМЕННОЙ "ДАННЫЕ"
//
ИначеЕсли Событие="RTPSenderStat" Тогда
//ПРИМЕР ОТВЕТА В ПЕРЕМЕННОЙ "ДАННЫЕ"
//
ИначеЕсли Событие="ChannelUpdate" Тогда
//ПРИМЕР ОТВЕТА В ПЕРЕМЕННОЙ "ДАННЫЕ"
//
КонецЕсли; // По виду события
КонецЕсли;
КонецПроцедуры
В приведенном выше коде мы проиллюстрировали возможный вариант обработки внешних событий компонента. Данные, переданные в параметр *Данные*, представляют из себя XML структуру, которую можно разобрать, используя функцию ЧтениеXML языка 1С:Предприятие 8.
Пример разбора ответа используя объект ЧтениеXML:
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(Данные);
CallerID1 = ЧтениеXML.ЗначениеАтрибута("Callerid1");
CallerID2 = ЧтениеXML.ЗначениеАтрибута("Callerid2");
Channel1 = ЧтениеXML.ЗначениеАтрибута("Channel1");
Channel2 = ЧтениеXML.ЗначениеАтрибута("Channel2");
UniqueID1 = ЧтениеXML.ЗначениеАтрибута("Uniqueid1");
UniqueID2 = ЧтениеXML.ЗначениеАтрибута("Uniqueid2");
Объект ЧтениеXML не доступен в режиме веб клиента, потому при использовании такого режима нужно обходиться другими способами разбора строк.
Например, при использовании WEB клиента Mozilla Firefox мы реализовали разбор ответа следующим образом:
&НаКлиенте
Процедура ВнешнееСобытие(Источник, Событие, Данные)
Если Источник="MikoAjamEvent" Тогда // проверим ответ от нашей ли компоненты?
СтруктураПолей=РазобратьОтветАстериска(Данные);
CallerID1 = СтруктураПолей.Получить("callerid1");
CallerID2 = СтруктураПолей.Получить("callerid2");
channel1 = СтруктураПолей.Получить("channel1");
КонецЕсли;
Конецпроцедуры;
&НаКлиенте
// разбирает строку XML в соответсвие ключ - значение
Функция РазобратьОтветАстериска(Данные)
СимволДвоеточиеПробел="=";
МассивПодстрок=РазложитьСтрокуВМассивПодстрок(Данные," ");
ПараметрыОтвета=Новый Соответствие;
Для к=0 по МассивПодстрок.Количество()-1 Цикл
СтрокаДляРазбора = СокрЛП(МассивПодстрок[к]);
ПозицияРазделителя = Найти(СтрокаДляРазбора,СимволДвоеточиеПробел);
ДлинаСтроки = СтрДлина(СтрокаДляРазбора);
Если ПозицияРазделителя<>0 Тогда
Параметр=Лев(СтрокаДляРазбора,ПозицияРазделителя-1);
Значение=Прав(СтрокаДляРазбора,ДлинаСтроки-ПозицияРазделителя-1);
Значение=Лев(Значение,СтрДлина(Значение)-1);
ПараметрыОтвета.Вставить(Параметр,Значение);
КонецЕсли;
КонецЦикла;
Возврат ПараметрыОтвета;
КонецФункции //РазобратьОтветАстериска
&НаКлиенте
//Переданную строку, разбивает в массив
Функция РазложитьСтрокуВМассивПодстрок(Знач Стр, Разделитель = ",") Экспорт
МассивСтрок = Новый Массив();
Если Разделитель = " " Тогда
Стр = СокрЛП(Стр);
Пока Истина Цикл
Поз = Найти(Стр,Разделитель);
Если Поз=0 Тогда
МассивСтрок.Добавить(Стр);
Возврат МассивСтрок;
КонецЕсли;
МассивСтрок.Добавить(Лев(Стр,Поз-1));
Стр = СокрЛ(Сред(Стр,Поз));
КонецЦикла;
Иначе
ДлинаРазделителя = СтрДлина(Разделитель);
Пока Истина Цикл
Поз = Найти(Стр,Разделитель);
Если Поз=0 Тогда
МассивСтрок.Добавить(Стр);
Возврат МассивСтрок;
КонецЕсли;
МассивСтрок.Добавить(Лев(Стр,Поз-1));
Стр = Сред(Стр,Поз+ДлинаРазделителя);
КонецЦикла;
КонецЕсли;
КонецФункции // РазложитьСтрокуВМассивПодстрок
===== Полезные ссылки =====
* [[doc:1cajam|SDK: Компонента связи 1C и Asterisk]]
* [[doc:1cajam:api|Описание функций реализованных в SDK: Компонента связи 1С и Asterisk]]
* [[kb:asterisk:events|Asterisk Manager: Events]]
===== Комментарии =====
~~DISQUS~~