В этой небольшой статье ничего не будет про план нумерации астериска. Речь пойдет про ARI — гибкий интерфейс управления Астериском.
Как только в астериск приходит инвайт, и вызов уходит в нашу программу (Stasis) мы получаем возможность для низкоуровневого построения звонка.
Взаимодействие с ARI происходит через прием событий по websocket от астериска, обработку и создания новых событий через HTTP REST API в сторону ARI.
StasisStart
Событие, которое получает наша программа, когда канал вошел в стазис контекст. StasisStart может сигнализировать, например о начале исходящего либо входящего звонка, в результате чего мы запускаем низкоуровневую логику по созданию канала в сторону другого абонента, добавлению его в бридж с каналом инициатором и дозвону.
Упрощенная схема обычного звонка
- Получили инвайт (StasisStart) событие от ARI, что сигнализирует о созданном канале A
- Создали канал B с эндпоинтом в сторону сип пира, либо в локальный прокси. (пример. SIP/MY_PEER/79001231122)
- Канал А из п.1 и B из п.2 объядинили в bridge
- Сделали дозвон (dial) в канал B
- Подождали ARI событие ChannelStateChange для канала B. И в случае если state — ‘Up’, запускаем ответ в канал A и звонок диалог начинается.
- При получении события ChannelHangupRequest для канала A либо B разрушаем звонок.
Сессия звонка
Созданных каналов может быть множество и есть необходимость знать, к каким звонкам относятся события по каким каналам. Поэтому при создании каналов в сторону другого абонента, можно записывать в стор для созданного канала указатель на id канала A, а в сторе для канала A хранить все данные, включая CDR и прочую техническую информацию.
В качестве хранилища я бы рекомендовал использовать redis, так как при больших cps и интенсивных запросах в базу данных может образоваться существенная нагрузка на жесткие диски и просесть производительность.
Оптимизация
Для оптимальной работы вашего ARI приложения под большим cps, я бы рекомендовал свести к минимуму запросы в реляционную базу данных. В своей практике я использовал запросы для небольшой ограничительной логики в момент инициализации звонка и для записи CDR после окончания звонка. Все остальные запросы выполняются в рэдис.
Тест производительности
Для тестирования я использовал консольную утилиту baresip, инициировав баш скриптом 200 дозвонов по пулу тестовых номеров, которые отвечают tt-monkeys.
200 параллельно запущенных звонков сумарно потребили около 5% загрузки на CPU. Все звонки завершились успешно, включая записанные CDR.

