====== Прослушивание событий, передаваемых сервером 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~~