07

Связи компонентов

Матрица «функция → компонент», диаграмма взаимодействий и полная последовательность обработки вызова.

Матрица «Функция → Компонент»

Матрица показывает, какой компонент за какую функцию отвечает. — основная ответственность (Primary): компонент является главным исполнителем функции. — участие (Secondary): компонент вспомогательно участвует в реализации. Пустая ячейка — компонент не задействован.

Категория функций Kamailio FreeSWITCH RTPEngine Go API PostgreSQL Redis NATS React
Управление вызовами
Переводы
Многосторонние
IVR
Очереди (ACD)
Голосовая почта
Маршрутизация
Супервизор
Запись / Аналитика
Статусы / Presence
Автообзвон
Интеграции
WebRTC
Безопасность
Отказоустойчивость
Администрирование
Как читать матрицу

По строкам видно, какие компоненты нужны для каждой функции. По столбцам — зона ответственности каждого компонента. Например, FreeSWITCH — основной исполнитель большинства телефонных функций, а Go API отвечает за бизнес-логику, аналитику и интеграции.

Кто с кем говорит

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

                    ┌───────────┐           ┌────────────┐
                    │  Браузер  │           │ IP-телефон │
                    │(SIP.js)   │           │  (SIP)     │
                    └─────┬─────┘           └──────┬─────┘
                          │                        │
                     WSS/SIP                  UDP/SIP
                          │                        │
                    ┌─────▼────────────────────────▼─────┐
                    │            Kamailio               │
                    │     SIP Proxy / Registrar           │
                    └──┬─────────┬──────────┬──────────┬──┘
                       │         │          │          │
                  SIPng ctrlSQLHEP │
                       │         │          │          │
                       ▼         ▼          ▼          ▼
               ┌────────────┐ ┌──────────┐ ┌──────────┐ ┌───────┐
               │ FreeSWITCH │ │ RTPEngine│ │PostgreSQL│ │ Homer │
               │  (B2BUA)   │ │ (Media)  │ │  (Data)  │ │(SIP   │
               │            │ │          │ │          │ │ мон.) │
               └──┬───┬──┬──┘ └──────────┘ └─────▲────┘ └───▲───┘
                  │   │  │                          │        │
             RTP │   │  │HEP                     │        │
                  │   │  └─────────────────────────────────►─┘
                  ▼   │
          ┌──────────┐S3 API              ┌──────────────────┐
          │ RTPEngine││     Go API       │
          │ (Media   ││ REST + WebSocket │
          │  proxy)  │└──┬───┬───┬───┬───┘
          └──────────┘ ┌──────┐               │   │   │   │
                      │MinIO │          ESL/│   │SQL│   │NATS
                      │(S3)  │          TCP │   │   │   │
                      └──────┘               │   │   │   │
                                               ▼   ▼   ▼   ▼
               ┌────────────┐ ┌──────────┐ ┌─────┐ ┌──────────┐
               │ FreeSWITCH │ │PostgreSQL│ │NATS │ │  Redis   │
               └────────────┘ └──────────┘ └──┬──┘ └──────────┘события
                                                │
                                                ▼
                                         ┌───────────┐
                                         │   React   │
                                         │ Dashboard │
                                         └───────────┘
Рис. 9 — Карта всех межкомпонентных соединений с указанием протоколов

Сводная таблица всех соединений:

Источник Назначение Протокол Назначение соединения
Браузер (SIP.js) Kamailio WSS/SIP SIP-сигнализация через WebSocket (регистрация, звонки)
IP-телефон Kamailio UDP/SIP SIP-сигнализация (регистрация, звонки)
Kamailio FreeSWITCH SIP Маршрутизация вызовов к медиа-серверу
Kamailio RTPEngine ng control Управление медиа-проксированием (offer/answer SDP)
FreeSWITCH RTPEngine RTP Голосовые потоки к медиа-прокси
Go API FreeSWITCH ESL/TCP Управление вызовами, получение событий (Event Socket)
Go API PostgreSQL SQL Чтение/запись данных (пользователи, CDR, настройки)
Go API Redis Redis protocol Кеш, сессии, статусы, блокировки
Go API NATS NATS Публикация и подписка на события (real-time)
Go API React HTTP/WS REST API и WebSocket для реалтайм-обновлений
Kamailio PostgreSQL SQL Таблицы маршрутизации, регистрации, ACL
Kamailio Homer HEP Зеркалирование SIP-трафика для мониторинга
FreeSWITCH Homer HEP Зеркалирование SIP-трафика для мониторинга
FreeSWITCH MinIO S3 API Сохранение записей разговоров и голосовой почты
Важно для файрволла и сети

Каждое соединение из таблицы выше требует открытых портов и сетевых правил. При развёртывании убедитесь, что все указанные протоколы и порты разрешены между соответствующими хостами. Особое внимание — UDP-портам RTP (10000–20000), которые часто блокируются по умолчанию.

Полная последовательность входящего вызова

Входящий вызов из PSTN — все 15 шагов через все компоненты

Детальная последовательность обработки входящего звонка, проходящего через каждый компонент системы: от поступления SIP INVITE из телефонной сети до обновления дашборда в реальном времени. Каждый шаг указывает задействованный компонент и выполняемое действие.

1
SIP INVITE из PSTN — SIP-транк отправляет INVITE с номером вызывающего (CID) и набранным номером (DID). SIP-транк
2
Kamailio принимает на порту 5060 — SIP proxy получает INVITE и начинает обработку в route[MAIN]. Kamailio
3
Аутентификация транка (IP ACL) — Kamailio проверяет IP-адрес отправителя по списку разрешённых IP-адресов транков. Kamailio
4
Проверка DID в PostgreSQL — Kamailio запрашивает базу данных: какому тенанту/маршруту принадлежит набранный номер. Kamailio PostgreSQL
5
Offer SDP → RTPEngine — Kamailio отправляет SDP-часть INVITE в RTPEngine для подготовки медиа-проксирования. Kamailio RTPEngine
6
RTPEngine выделяет медиа-порты — RTPEngine резервирует пару UDP-портов для приёма и отправки голосового трафика. RTPEngine
7
Маршрутизация INVITE к FreeSWITCH — Kamailio выбирает целевой FreeSWITCH-сервер (по нагрузке) и перенаправляет INVITE. Kamailio FreeSWITCH
8
FreeSWITCH обрабатывает диалплан — по DID определяется контекст и extension; вызов направляется на IVR-приложение. FreeSWITCH
9
IVR отвечает, проигрывает приветствие — FreeSWITCH отвечает 200 OK, проигрывает аудиофайл: «Нажмите 1 для продаж, 2 для поддержки...» FreeSWITCH
10
Клиент нажимает DTMF 2 → очередь «Поддержка» — FreeSWITCH распознаёт DTMF и переводит вызов в очередь mod_callcenter. FreeSWITCH
11
mod_callcenter находит оператора — алгоритм «longest idle» выбирает оператора, который дольше всех свободен. Статус берётся из Redis. FreeSWITCH Redis
12
INVITE к оператору через Kamailio — FreeSWITCH отправляет новый INVITE на SIP-адрес оператора; Kamailio находит его регистрацию и доставляет вызов. FreeSWITCH Kamailio
13
Оператор отвечает → 200 OK — телефон оператора отправляет 200 OK; цепочка подтверждений (ACK) проходит обратно через Kamailio и FreeSWITCH. Оператор
14
RTPEngine соединяет медиа-потоки — голос теперь идёт: SIP-транк (PSTN) ↔ RTPEngine ↔ телефон оператора. Транскодирование при необходимости. RTPEngine
15
CDR + событие + дашборд — Go Backend получает событие через ESL, записывает CDR в PostgreSQL. NATS публикует событие. React-дашборд обновляется через WebSocket. Go API PostgreSQL NATS React
Весь путь за миллисекунды

Несмотря на 15 шагов и участие 8 компонентов, весь процесс от поступления INVITE до звонка телефона оператора занимает менее 500 мс при нормальной нагрузке. SIP-сигнализация передаётся в виде текстовых сообщений и обрабатывается каждым компонентом за единицы миллисекунд.

Диаграмма последовательности (sequence diagram) в текстовом формате
PSTN      Kamailio    RTPEngine   FreeSWITCH    Redis     Оператор   Go API    NATS    React
  │          │            │           │           │          │          │         │        │
  │─INVITE─▶│            │           │           │          │          │         │        │
  │          │──offer──▶│           │           │          │          │         │        │
  │          │◀─answer──│           │           │          │          │         │        │
  │          │──INVITE─────────────▶│           │          │          │         │        │
  │          │           │           │──IVR─────▶│          │          │         │        │
  │          │           │           │◀─DTMF 2──│          │          │         │        │
  │          │           │           │──query───▶│          │          │         │        │
  │          │           │           │◀─agent───│          │          │         │        │
  │          │◀─INVITE──────────────│           │          │          │         │        │
  │          │──────────────────────────────────▶│          │          │         │        │
  │          │◀──────────────────────────────────│ 200 OK   │          │         │        │
  │          │──answer──▶│           │           │          │          │         │        │
  │          │           │═══RTP═══▶│═══════════│══════════│          │         │        │
  │═══RTP══▶│═══════════│◀══RTP═══│           │          │          │         │        │
  │          │           │           │──event──────────────────────▶│         │        │
  │          │           │           │           │          │          │──pub──▶│        │
  │          │           │           │           │          │          │         │──WS──▶│
Рис. 10 — Последовательность сообщений входящего вызова через все компоненты системы