bind_transceiverОткрыть и аутентифицировать сессиюbind_transceiver_respСессия принятаsubmit_smОтправить сообщениеsubmit_sm_respПринято, возвращен ID сообщенияdeliver_smПодтверждение доставки или входящее сообщениеdeliver_sm_respПодтвержденоenquire_linkKeepalive в режиме ожидания
Что такое SMPP
SMPP — Short Message Peer-to-Peer — это бинарный, сессионный протокол, который агрегаторы и операторы предоставляют для высокообъёмного A2P-обмена сообщениями. Там, где REST API удобен и не хранит состояние, SMPP — это постоянное TCP-соединение, созданное для объёма и низкой задержки.
ESME (External Short Messaging Entity — ваша сторона) открывает сессию к SMSC и обменивается PDU (Protocol Data Units). Протокол компактен и эффективен, поэтому он остаётся основой для крупных отправителей, даже когда REST покрывает повседневное использование.
Наиболее широко распространённая версия — SMPP v3.4; v5.0 добавляет сигнализацию состояния перегрузки и расширенные параметры, но остаётся обратно совместимой. Никогда не предполагайте, что функция v5.0 доступна, пока ответ на bind не подтвердит согласованную версию.
Типы bind и сессии
Прежде чем что-либо отправить, ESME должен выполнить bind — аутентифицироваться и объявить роль. Bind типа transmitter только отправляет сообщения; bind типа receiver только принимает исходящие от абонента сообщения (mobile-originated) и отчёты о доставке; bind типа transceiver делает и то, и другое через одно соединение.
Transceiver обычно предпочтителен, поскольку вдвое сокращает число соединений и упрощает сопоставление DLR с отправленными сообщениями. Число одновременных bind и сообщений в секунду на bind (TPS) устанавливается провайдером и должно соблюдаться.
Bind передаёт system_id, password, system_type и address_range. Несовпадающий address_range незаметно ломает маршрутизацию MO и DLR на receiver-bind — классическая ошибка интеграции, которая не выдаёт ошибок, а просто теряет трафик.
PDU и submit_sm
Каждое взаимодействие по SMPP — это PDU с заголовком команды (длина, command id, статус, порядковый номер) и телом. Рабочая лошадка — submit_sm, которая переносит одно исходящее сообщение.
Две пары полей определяют адресацию: source_addr со своим TON/NPI (type-of-number / numbering-plan-indicator) и dest_addr со своим. Буквенно-цифровой sender ID использует TON 5; международный MSISDN использует TON 1, NPI 1. Ошибка здесь приводит к некорректному отображению sender ID или отклонению сообщения.
Поле data_coding задаёт кодировку — GSM 7-бит (0), 8-бит (4) или UCS-2 (8) для Unicode. Длинные сообщения конкатенируются либо байтами UDH в теле, либо необязательными параметрами SAR (sar_msg_ref_num, sar_total_segments, sar_segment_seqnum); выберите один способ и придерживайтесь его, поскольку маршруты различаются в том, какой из них принимают.
Окно, throttling и keepalive
SMPP использует окно передачи: ограничение на число PDU submit_sm, отправленных до получения ответов на них. Превышение окна или установленного TPS вызывает ESME_RTHROTTLED (0x58). Правильная реакция — снизить темп с задержкой jitter, а не зацикливаться на повторных попытках.
Чтобы обнаружить наполовину открытое TCP-соединение, каждая сторона отправляет enquire_link по таймеру простоя (обычно каждые 30–60 секунд) и ожидает enquire_link_resp. Отсутствие ответа означает, что сессия мертва, и её следует пересоздать (re-bind) с экспоненциальной задержкой.
Штатное завершение работы использует unbind / unbind_resp. Неожиданные разрывы соединения должны вызывать переподключение с задержкой и идемпотентными повторами, чтобы потерянное окно не приводило к двойной отправке и двойному выставлению счёта.
Отчёты о доставке через SMPP
Отчёты о доставке приходят в виде PDU deliver_sm. Текст отчёта в поле short_message содержит id, sub, dlvrd, дату отправки, дату завершения, конечный статус (stat: DELIVRD, UNDELIV, EXPIRED, REJECTD) и код ошибки (err).
Сопоставляйте DLR с исходной отправкой по message_id провайдера, а не только по тексту отчёта — message_id может возвращаться в шестнадцатеричном виде в submit_resp, но в десятичном — в DLR, поэтому нормализуйте оба формата.
Всегда отвечайте deliver_sm_resp. Неподтверждённый DLR будет повторно отправлен SMSC и может остановить окно приёма, поэтому подтверждайте его незамедлительно, даже если ваша дальнейшая обработка асинхронна.
- SMPP — это постоянная бинарная сессия для высокообъёмного A2P; v3.4 — распространённый базовый вариант, v5.0 обратно совместима.
- Bind выполняется как transmitter, receiver или transceiver; transceiver вдвое сокращает число соединений и упрощает сопоставление DLR.
- TON/NPI определяют отображение sender ID, а data_coding — кодировку; в обоих легко ошибиться.
- Соблюдайте окно и TPS, снижайте темп при ESME_RTHROTTLED и поддерживайте сессию активной с помощью enquire_link.