...

воскресенье, 27 октября 2013 г.

YATE. Messages

Всем привет!

Сегодня я хотел бы рассказать о сообщениях (сигналах). Они являются одной из основных составляющих YATE.



Если Вам интересно, прошу под кат.



Сообщения




YATE использует их для обмена данными между модулями. Благодаря этому, Yate имеет большую гибкость, чем при использовании функций (в основном из-за того, что сообщения могут иметь разное количество параметров). Если какой-то из модулей изменился, другие модули, работающие с данным сообщением, не требуют изменений. Также это упрощает дебаг, т.к. известно какие модули общаются между собой и какие данные при этом передаются. На рисунке изображена архитектура Yate.


Структура сообщений




Сообщения содержат в себе имя, возвращаемое значение, время и параметры. Все сообщения внутри YATE бинарные. Для обмена данными используется совместное использование памяти (memory sharing). Прежде чем сообщения попадают во внешние модули, они конвертируются в escape последовательности, что позволяет передавать любые символы, которые только могут быть в данных сигнала.

Обработка сообщений




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

Порядок вызова обработки устанавливается во время инициализации (установки) обработчиков и зависит от приоритета. Приоритет — целое число и чем он меньше, тем раньше будет вызван обработчик. Нет никаких гарантий в каком порядке будут вызваны обработчики с одинаковыми приоритетами. На данный момент применяются следующие правила:

— порядок обработки не меняется от сигнала к сигналу

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


Очереди сообщений




В YATE есть такое понятие как очереди сообщений. Сообщение сортируются по очередям в зависимости от своих имен. Это позволяет уменьшить нагрузку на основную очередь, а также предоставить направленную обработку сигналов. От имени сигнала и списка используемых фильтров зависит то, в какую очередь попадут его данные. Сигналы с разными именами не могут быть в одной очереди, но несколько очередей может быть создано для одинаковых сигналов с разными фильтрами. Т.е. сообщение добавляется в очередь, если его имя и данные совпадает с именем очереди и установленными фильтрами соответственно. Модули могут добавлять сообщения в очереди.

Пример




Давайте рассмотрим небольшой пример. У меня настроена YATE на работу с MySQL (по этой статье). И добавлено два аккаунта test и test2.

В базе это выглядит так:






















usernamepasswordlocation
expires
oconnection_id
testtestNULLNULLNULL
test2test2NULLNULLNULL

Открываем софтфон и добавляем эти аккаунты. По умолчанию все обработчики сообщений модуля register установлены с приоритетом 50. После того как прошла регистрация, записи приняли следующий вид:























usernamepasswordlocation
expires
oconnection_id
testtestsip/sip:test@127.0.0.1:564292013-10-26 22:32:41tcp:127.0.0.1:5060-127.0.0.1:56429
test2test2sip/sip:test2@127.0.0.1:444962013-10-26 22:32:41general

Теперь немного изменим приоритеты для user.register (т.е. для регистрации). Откроем файл regfile.conf. Отредактируем секцию general, что бы она приняла следующий вид:

[general]

register=10

И добавим пользователя test2:

[test2]

password=test2


Перезапустим YATE и перерегистрируем аккаунты, после чего смотри в базу.
























usernamepasswordlocation
expires
oconnection_id
testtestsip/sip:test@127.0.0.1:564612013-10-26 22:38:12tcp:127.0.0.1:5060-127.0.0.1:56461
test2test2NULLNULLNULL



Как видим, данные о регистрации аккаунта test2 не были обновлены. Все из-за приоритетов. В последнем случае сообщение регистрации обработал модуль regfile.

Message flow




Напоследок хотел бы рассмотреть что происходит при звонке. YATE настроен на работу только с модулем regfile.



Начинается телефонный вызов и генерируется сообщение user.auth, которое обрабатывается модулем regfile. После этого YATE генерирует сообщение chan.startup и модуль создает экземпляр канала. Далее вызывается сообщение call.preroute. На данном этапе модуль regeroute определяет к какому контексту относится звонок, после чего генерируется сообщение call.route, и ищет куда перенаправлять звонок в зависимости от контекста. После получения направления для маршрутизации, видим сообщение call.execute (для входящих вызовов), которое соединяет два канала (канал звонящего и канал звонящему). Но так как вызываемый канал еще не создан, генерируется еще один chan.statup. После чего происходит соединение и посылается сообщение call.ringing (в данный момент приходит 180 Ringing sip-меседж). После того, как вызываемый номер берет трубку генерируется сообщение call.answered. После этого можно отлавливать сообщения тонального набора и определять какие кнопки жмут абоненты.

Когда разговор окончен, для той стороны, которая положила трубку, вызывается chan.hangup. После чего вызывается chan.disconnected и chan.hangup для вызывающей стороны. Во время chan.disconnected, вы можете спасти положение и, например, сделать вызов на какой-то номер, что бы соединить звонящего с кем-то.чем-то.


Спасибо за внимание. В следующем посте рассмотрю работу с внешними модулями и мы с Вами напишем простенький модуль. После чего сможем видеть message flow в реальном времени, а также сможем наблюдать какие данные приходят и попробуем манипулировать ими.


Ссылки:

docs.yate.ro/wiki/Messages

docs.yate.ro/wiki/Standard_Messages

docs.yate.ro/wiki/Message_Flows


P.S. Постарался открыть вопрос как можно шире и наиболее простым текстом. Если что-то не понятно, буду рад ответить на Ваши вопросы.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at fivefilters.org/content-only/faq.php#publishers. Five Filters recommends:



Комментариев нет:

Отправить комментарий