Как SMPP-шлюз помогает сократить число неотвеченных OTP-кодов

OTP-код живёт секунды. Если он пришёл с задержкой в 30–40 секунд или не пришёл вовсе — пользователь либо запросит повторный код, либо уйдёт. SMPP-шлюз решает эту проблему на уровне протокола: постоянное TCP-соединение вместо HTTP-запроса на каждое сообщение убирает задержки на установку сессии и даёт прямой контроль над статусами доставки. В статье разберём, где именно теряются OTP-коды и что конкретно настроить, чтобы этого не происходило.
Почему OTP-коды теряются ещё до пользователя?
Большинство потерь происходит не у оператора, а раньше — между вашим сервером и SMS-шлюзом. HTTP API при каждой отправке заново устанавливает соединение: DNS-резолвинг, TCP-handshake, TLS-согласование. На это уходит от 200 мс до нескольких секунд, и при всплеске нагрузки запросы начинают вставать в очередь или падать по таймауту.
SMPP работает иначе. Соединение устанавливается один раз при старте и держится постоянно. Сообщение уходит в шлюз через уже открытый канал — задержка на отправку падает до единиц миллисекунд. Для OTP это принципиально: разница между «код пришёл сразу» и «код пришёл через минуту» — это разница между завершённой транзакцией и потерянным клиентом.
Вторая точка потерь — отсутствие квитанций о доставке. Без delivery receipt сервер не знает, дошёл ли код. Повторный запрос пользователя уходит в пустоту, потому что система считает первый код доставленным. SMPP передаёт deliver_sm с реальным статусом доставки от оператора, и при правильно настроенном fallback-маршруте сервер может автоматически повторить отправку через другой маршрут, если первый вернул ошибку.
Что конкретно настроить в SMPP для OTP-трафика?
Первое — тип привязки. Для OTP нужен transceiver (bind_transceiver): он одновременно отправляет сообщения и принимает квитанции о доставке. Если использовать только transmitter, статусы не придут и вы будете работать вслепую.
Второе — размер окна (window size). Это количество сообщений, которые можно отправить без ожидания ответа на предыдущие. Для OTP-трафика с короткими сообщениями оптимальное значение подбирается под реальный профиль нагрузки: слишком маленькое окно создаёт искусственную очередь, слишком большое — перегружает шлюз и оператора (источник: quicktel.ru). Перед тем как фиксировать значение, стоит провести нагрузочное тестирование на реальных объёмах.
Третье — enquire_link. Это keepalive-пакет, который проверяет, живо ли соединение. Без него «упавший» канал обнаруживается только в момент следующей отправки — то есть OTP-код просто не уходит. Интервал enquire_link обычно ставят от 30 до 60 секунд.
Четвёртое — кодировка. Кириллица в OTP-коде встречается редко, но если шаблон содержит хотя бы один символ вне GSM-7 таблицы, сообщение уйдёт в UCS-2 и максимальная длина сократится со 160 до 70 символов. OTP-шаблон вида «Ваш код: 4821» лучше держать в латинице и цифрах — это гарантирует GSM-7 и одиночный сегмент. Подробнее о выборе кодировки — в материале про UCS-2 и GSM-7 в SMPP.
| Параметр | HTTP API | SMPP |
|---|---|---|
| Установка соединения | На каждый запрос | Один раз при старте |
| Задержка отправки | 200 мс — несколько секунд | Единицы миллисекунд |
| Квитанции о доставке | Через вебхук, возможны потери | deliver_sm в том же соединении |
| Пиковая нагрузка | Очередь и таймауты | Контролируется через window size |
| Обнаружение обрыва | По ошибке следующего запроса | enquire_link каждые 30–60 сек |
Как проверить, что шлюз справляется с нагрузкой?
Нагрузочное тестирование SMPP показывает, сколько сообщений в секунду выдерживает конкретное соединение, когда растёт очередь и как шлюз реагирует на ошибки (источник: smpp.by). Без такого теста нельзя утверждать, что SMPP-канал лучше API: преимущество подтверждается измерением, а не ожиданием (источник: quicktel.ru).
Для теста достаточно инструмента, который умеет открывать SMPP-сессию и слать submit_sm с заданным TPS. Фиксируйте три показателя: время от submit_sm до submit_sm_resp, время до получения deliver_sm и процент сообщений без квитанции за контрольный период. Если deliver_sm не приходит на 5% и более сообщений — проблема либо в window size, либо в маршруте до оператора.
Отдельно проверьте поведение при обрыве TCP. Шлюз должен переподключиться автоматически и без потери сообщений из очереди. Если этого не происходит — смотрите на настройки reconnect-логики на стороне вашего SMPP-клиента.
Типичные ошибки при настройке OTP через SMPP
- Используют bind_transmitter вместо transceiver — квитанции о доставке не приходят, повторные отправки не работают.
- Ставят enquire_link с интервалом больше 5 минут или отключают совсем — «упавшее» соединение обнаруживается только при следующей отправке.
- Не тестируют кодировку шаблона — один кириллический символ в тексте переключает всё сообщение в UCS-2 и сокращает лимит до 70 символов.
- Игнорируют TPS-лимиты оператора — шлюз принимает сообщения быстрее, чем оператор их обрабатывает, и часть OTP-кодов встаёт в очередь на минуты.
- Не настраивают fallback-маршрут — при сбое одного оператора коды просто не доходят вместо автоматического переключения.
Когда SMPP оправдан, а когда достаточно HTTP API?
HTTP API удобен для старта: меньше кода, проще документация, не нужно держать постоянное соединение. Для объёмов до нескольких сотен OTP в сутки разница в скорости доставки практически незаметна. Если же у вас пиковые нагрузки — регистрация на акцию, ночные рассылки кодов подтверждения, вход нескольких тысяч пользователей одновременно — HTTP API начинает подводить именно в самый неподходящий момент.
SMPP оправдан, когда задержка доставки больше 3–5 секунд уже ощущается пользователем как сбой. Интернет-магазин с пиком заказов в выходные, логистический сервис с подтверждением слотов доставки, медицинская запись с напоминаниями о визите — во всех этих случаях потерянный OTP стоит реального клиента. Настроить приоритет SMS-трафика через SMPP можно отдельно для OTP-очереди, чтобы она не конкурировала с маркетинговыми рассылками за пропускную способность канала.
3 шага, которые можно сделать на этой неделе:
- Проверьте тип привязки в своём SMPP-клиенте — должен быть transceiver, иначе квитанции о доставке не приходят.
- Запустите нагрузочный тест на реальном объёме OTP-трафика и зафиксируйте процент сообщений без deliver_sm за 10 минут.
- Проверьте все OTP-шаблоны на наличие кириллицы — если она есть, переведите текст в латиницу и цифры, чтобы гарантировать GSM-7 и одиночный сегмент.


