Asterisk™: будущее телефонии Второе издание
Шрифт:
Хранение записей параметров вызовов
Записи параметров вызовов (Call Detail Records, CDR) содержат информацию о вызовах, прошедших через систему Asterisk. Более подробно они обсуждаются в главе 13. Хранение CDR - один из самых популярных примеров использования баз данных в Asterisk, потому что в этом случае с CDR проще работать (например, можно отслеживать несколько систем Asterisk в одной таблице).
Создадим в нашей базе данных таблицу для хранения CDR. Зарегистрируемся на сервере PostgreSQL с помощью приложения psql: # psql -U asterisk -h localhost asterisk
Password:
И создадим таблицу asterisk_cdr:
asterisk=> CREATE TABLE asterisk_cdr (
id bigserial NOT NULL, calldate timestamptz,
Задание
CDR состоят из уникального идентификатора и нескольких полей информации о вызове (включая источник и канал назначения, продолжительность вызова, приложение, выполняемое последним, и т. д.). В кластере серверов Asterisk теоретически возможно дублирование уникальных идентификаторов, поскольку каждая система Asterisk учитывает только саму себя. Чтобы решить эту проблему, можно автоматически добавлять идентификатор системы в начало уникального ID. Для этого введем дополнительную опцию в файл /etc/asterisk/asterisk.conf и зададим идентификатор для каждого из серверов: [options]
systemname=toronto
clid varchar(80), src varchar(80), dst varchar(80), dcontext varchar(80), channel varchar(80), dstchannel varchar(80), lastapp varchar(80), lastdata varchar(80), duration int8, billsec int8, disposition varchar(45), amaflags int8, accountcode varchar(20), uniqueid varchar(40), userfield varchar(255),
CONSTRAINT asterisk_cdr_id_pk PRIMARY KEY (id)
)
WITHOUT OIDS;
Убедиться в том, что таблица создана, можно с помощью команды \dt (describe tables):
asterisk=> \dt asterisk_cdr
List of relations
Schema | Name | Type | Owner + + +
public | asterisk_cdr | table | asterisk (1 row)
Далее конфигурируем Asterisk на хранение ее CDR в базе данных. Это выполняется в файле /etc/ asterisk/cdr_odbc.conf с помощью следующих настроек:
[global]
dsn=asterisk-connector
username=asterisk password=welcome loguniqueid=yes table=asterisk_cdr
Если Asterisk уже запущена, из интерфейса командной строки Asterisk выполняем команду module reload cdr_odbc.so. Также можно просто ввести reload, чтобы выполнить полную перезагрузку. *CLI> reload
Проверим статус CDR. Для этого введем следующую команду и найдем в выводе строку CDR registered backend: ODBC:
*CLI> cdr status
CDR logging: enabled CDR mode: simple
CDR registered backend: cdr-custom
CDR registered backend: cdr_manager
CDR registered backend: ODBC
Теперь выполним вызов через сервер Asterisk, а потом проверим наличие данных о нем в таблице asterisk_cdr. Самый простой способ протестировать вызов - использовать CLI-команду Asterisk console dial (предполагается, что имеется звуковая карта и установлен модуль chan_oss). Однако для выполнения тестового звонка можно использовать любой имеющийся в распоряжении метод: *CLI> console dial 100@default
– - Executing [100@default:1] Playback("OSS/dsp", "tt-weasels") in new stack -- <OSS/dsp> Playing 'tt-weasels' (language 'en')
Затем установим соединение с базой данных и выполним запрос SELECT для проверки наличия данных в таблице asterisk_cdr. Также можно выполнить команду SELECT * FROM asterisk_cdr;, но в этом случае будет возвращено намного больше данных: # psql -U asterisk -h localhost asterisk Password:
asterisk=> SELECT id,dst,channel,uniqueid,calldate FROM asterisk_cdr;
id | dst | channel | uniqueid | calldate
– --+ + + +
1 | 100 | OSS/dsp | toronto-1171611019.0 | 2007-02-16 02:30:19-05 (1 rows)
Ощутим могущество func_odbc: система «горячих столов»
Функция диалплана func_odbc является, наверное, самой замечательной и мощной в Asterisk. Она позволяет создавать и применять довольно простые функции диалплана для извлечения и использования информации из баз данных непосредственно в диалплане. Ее можно использовать в очень многих случаях, например для управления пользователями или обеспечения
func_odbc позволяет описывать SQL-запросы и присваивать им имена функций. В результате создаются специальные функции, которые получают свои результаты, выполняя запросы к базе данных. Взаимосвязи между именами создаваемых функций и выражениями SQL, которые они должны выполнять, описываются в файле func_odbc.conf. Используя именованные функции в диалплане, можно извлекать и обновлять значения в базе данных.
Хотя применение внешнего сценария для взаимодействия с базой данных (из которой создается плоский файл для Asterisk) имеет свои преимущества (если база данных дает сбой, система будет продолжать функционировать и сценарий просто не будет обновлять файлы до восстановления соединения с базой данных), основной недостаток в этом случае в том, что любые изменения, вносимые вами для пользователя, остаются недоступными, пока не будет выполнен сценарий обновления. Возможно, это не является большой проблемой для маленьких систем, но в больших системах ожидание вступления в силу внесенных изменений может привести к неприятностям, таким как прерывание активного вызова на время загрузки или синтаксического разбора большого файла. Ослабить негативные эффекты можно, применяя систему баз данных с дублированием. В версии Asterisk, следующей за 1.4 (в настоящее время эта версия готовится к выпуску [115] ) синтаксис файла func_odbc.conf изменится не сильно, но обеспечит возможность в случае отказа перейти к другой СУБД. Таким образом, можно будет кластеризовать серверную часть базы данных, используя отношение ведущий-ведущий (pgcluster; Slony-II) или систему дублирования ведущий-ведомый (Slony-I).
115
Сейчас уже доступна версия 1.6.
– Примеч. науч.ред.
Чтобы вы получили правильное представление о рассматриваемом далее материале, представьте себе дагвудовский сэндвич [116] . Можно ли описать всю гамму впечатлений от такого блюда, только представив изображение помидора или помахав перед носом кусочком сыра? Вряд ли. С этой же проблемой мы сталкиваемся, пытаясь придумать хороший пример, объясняющий, в чем мощь func_odbc. Поэтому мы решили «приготовить сэндвич полностью». Рецепт довольно сложен, но, попробовав этот сэндвич, вы не захотите ничего другого. Для нашего примера мы решили реализовать то, что, по нашему мнению, могло бы иметь практическое применение. Представим небольшую компанию, в отделе продаж которой насчитывается пять человек и им приходится делить между собой два рабочих стола. Это не так ужасно, как может показаться, потому что эти ребята большую часть времени находятся в разъездах и проводят в офисе максимум один день в неделю.
116
А если вы не знаете, что это такое, как раз для этого случая и существует Википедия. Я вовсе не шучу.
Тем не менее, когда они в офисе, они бы хотели, чтобы система знала, за каким столом они работают, чтобы звонки, адресованные им, направлялись именно туда. Также руководитель хочет иметь возможность отслеживать, когда они находятся в офисе, и управлять привилегиями звонков, производимых с этих телефонов, в их отсутствие.
Решением в такой ситуации, как правило, является использование так называемой системы «горячих столов» (hot-desking). Мы реализовали такую функцию для вас, чтобы продемонстрировать мощь func_odbc. Начнем с простого и создадим два настольных телефона в файле sip.conf.