Протокол SMPP: устранение неполадок и тестирование отправки SMS

от автора

Люди практически перестали использовать SMS для общения, но с точки зрения бизнеса это по-прежнему важный инструмент — для оповещений, авторизации, информирования о статусе заказов и во множестве других ситуаций. Сегодня рассмотрим протокол SMPP и его связь с SMS, а затем настроим свой сервер и интегрируемся с SMS API, чтобы отправить сообщение.

Взаимодействие мобильной сети с интернетом через SMPP

Протокол SMPP нужен для обмена сообщениями между веб-приложениями и мобильными абонентами по сети TCP/IP. Он не доставляет сообщения оператору связи самостоятельно, а служит лишь каналом передачи данных.

Основные элементы системы передачи SMS

  • SMS (Short Message Service) — стандарт телекоммуникаций для отправки коротких текстовых сообщений между мобильными телефонами и другими устройствами через сети мобильной связи.

  • SMSC (Short Message Service Center) — ключевой элемент инфраструктуры мобильной сети. Управляет маршрутизацией сообщения между сетями, отправкой, приёмом, хранением и доставкой SMS, включая уведомления о ней. Когда получатель временно недоступен, SMSC хранит сообщение и передаёт его в момент подключения устройства к сети.

Взаимосвязь SMS и SMPP

Источник

Хотя SMPP и SMS функционируют на разных уровнях, они тесно связаны. SMPP используется для передачи сообщений через серверы и сети к мобильным абонентам. И SMPP, и SMS зависят от SMSC, который управляет процессом передачи сообщений.

Применение SMPP

SMPP эффективен для обмена сообщениями между интернет-серверами и операторами мобильной связи. Для общения только между серверами чаще используют другие протоколы: HTTP, MQTT или AMQP, так как они предназначены для широкого спектра задач серверного взаимодействия и более оптимизированы для таких целей.

Проблемы при работе с SMPP

Работа с протоколом иногда вызывает проблемы, связанные с его техническими особенностями и инфраструктурными ограничениями.

  1. Проблемы с установлением и поддержанием соединения.

Соединение с SMSC прерывается или не устанавливается, особенно при нестабильном интернет-соединении или неверной конфигурации.

  1. Ошибки аутентификации.

При выполнении команды bind_transmitter, bind_receiver или bind_transceiver.

  1. Ограничения по скорости отправки сообщений (throttling).

Кодами ошибок, связанных с превышением лимитов скорости.

  1. Ошибки при обработке длинных сообщений.

SMS с длиной более 160 символов могут не доставляться или приходить по частям, которые не собираются в единое сообщение на устройстве получателя.

  1. Проблемы с кодировкой.

Сообщения приходят с неправильными символами или нечитаемым текстом.

  1. Проблемы с подтверждениями доставки (Delivery Receipts).

Приложение не получает подтверждения доставки сообщений или получает их с задержкой.

  1. Неправильная обработка сетевых ошибок.

Приложение зависает или теряет сообщения при возникновении проблем с сетью.

  1. Отсутствие управления потоками сообщений.

Приложение перегружается при одновременной отправке множества SMS.

  1. Проблемы с задержками доставки.

Сообщения доставляются с задержкой, или SMSC долго обрабатывает запросы на отправку.

  1. Несовместимость версий SMPP.

Ошибки взаимодействия с SMSC или другими системами.

  1. Таймауты при отправке сообщений.

Соединение с SMSC может «зависнуть», и сообщения не отправляются.

Но все эти проблемы можно диагностировать и исправить при разработке, а тестирование позволит выпустить стабильную версию.

Создание сервера express.js

Теперь создадим свою систему для отправки SMS через API-платформу МТС Exolve. Развернём базовый сервер на express. Все конфиденциальные данные для подключения будут храниться в файле .env: добавим в него пароль, логин, хост и порт. Сервер будет слушать 3000 порт, а по роуту http://localhost:3000/send-sms мы начнём отправлять запросы через Postman и посылать сообщения.

Также важно установить зависимости: dotenv, express, smpp.

В главный файл app.js добавляем код:

Сейчас у нас есть сервер на express, который можно запустить командой node app.js.

Подключение к SMPP

Далее создадим соединение с SMPP с помощью документации МТС Exolve. В файл smppConnection.js добавляем код:

const smpp = require("smpp"); require("dotenv").config();   let session; let isBound = false; // Переменная для отслеживания статуса привязки let isBindingInProgress = false; // Флаг для отслеживания процесса привязки let bindTimeout; // Таймер для сообщения о проблемах с привязкой   const closeSession = (reason) => {   console.log(reason);   session.destroy(); // Принудительное закрытие сессии   isBound = false; // Обновляем статус сессии };   const connectSMPP = () => {   console.log("Попытка подключения к SMPP серверу...");   session = new smpp.Session({     host: process.env.SMPP_HOST,     port: process.env.SMPP_PORT,   });     session.on("connect", () => {     console.log("СMPP сервер подключен. Попытка привязки...");     isBindingInProgress = true; // Указываем, что процесс привязки начался     // Устанавливаем таймер на 5 секунд для закрытия сессии при задержке привязки     bindTimeout = setTimeout(() => {       if (isBindingInProgress) {         closeSession(           "Привязка занимает больше 5 секунд. Закрытие сессии. Возможно, неверные данные или проблемы с сервером."         );       }     }, 5000); // Тайм-аут на 5 секунд       session.bind_transceiver(       {         system_id: process.env.SMPP_SYSTEM_ID,         password: process.env.SMPP_PASSWORD,       },       (pdu) => {         clearTimeout(bindTimeout); // Очищаем таймер, если PDU получен         isBindingInProgress = false; // Привязка завершена           if (pdu.command_status === 0) {           isBound = true; // Успешная привязка           console.log("Успешное подключение к серверу SMPP");         }       }     );   });     session.on("close", () => {     if (isBindingInProgress) {       console.error(         "Соединение SMPP закрыто во время привязки. Вероятно, неверные данные аутентификации."       );     } else {       console.log("Соединение SMPP закрыто.");     }     isBound = false; // Соединение закрыто, сессия неактивна   });     session.on("error", (error) => {     clearTimeout(bindTimeout); // Очищаем таймер при ошибке     closeSession(`Ошибка соединения SMPP: ${error}`);   });     session.on("pdu", (pdu) => {     console.log("Получен PDU:", pdu);   }); }; const getSession = () => {   if (!isBound) {     console.error(       "Ошибка: SMPP сессия не привязана. Проверьте параметры аутентификации."     );   }   return session; };   module.exports = { connectSMPP, getSession };

Этот код устанавливает соединение с SMPP. Обратите внимание, что на каждом шаге производится вывод в консоль — для отслеживания ошибок.

Отправка SMS

Заключительная часть кода отправляет сообщения.

Добавляем код в новый файл smsService.js.

const { getSession } = require("./smppConnection");   const sendSMS = (phoneNumber, message, sender) => {   const session = getSession();     if (!session) {     console.error(       "Сессия SMPP не подключена или не активна. Сообщение не будет отправлено."     );     return;   }     console.log(     `Попытка отправить сообщение: "${message}" на номер: ${phoneNumber} от отправителя: ${sender}`   );     session.submit_sm(     {       source_addr: sender, // Номер отправителя       destination_addr: phoneNumber, // Номер получателя       short_message: message, // Текст сообщения       source_addr_ton: 1, // Тип номера отправителя (1 для международного номера)       source_addr_npi: 1, // План нумерации отправителя (1 для E.164)       dest_addr_ton: 1, // Тип номера получателя (1 для международного номера)       dest_addr_npi: 1, // План нумерации получателя (1 для E.164)       registered_delivery: 1, // Запрос уведомления о доставке       data_coding: 0x08, // Кодировка сообщения (0x08 для Unicode, 0x00 для GSM7)     },     (pdu) => {       console.log("Получен ответ PDU на отправку сообщения:", pdu);       if (pdu.command_status === 0) {         console.log("Сообщение отправлено успешно");       } else {         console.error("Не удалось отправить сообщение", pdu.command_status);       }     }   ); };   module.exports = { sendSMS };

Тестирование подключения

Запустим приложение командой node app.js.

При корректно введённых данных программа выведет сообщение: «Успешное подключение к серверу SMPP». Попробуем ввести заведомо ложный host или port.

Если port неправильный, увидим предупреждение: «Ошибка соединения SMPP: Error: getaddrinfo ENOTFOUND smpp.exolve.ru123213».

Соединение SMPP закрыто.

Если ошибка в указании port, то:
Попытка подключения к SMPP серверу…

node:internal/errors:541       throw error;       ^  RangeError [ERR_SOCKET_BAD_PORT]: Port should be >= 0 and < 65536. Received type string ('277511').     at lookupAndConnect (node:net:1298:5)     at Socket.connect (node:net:1255:5)     at Object.connect (node:net:238:17)     at new Session (C:\work\SMPP\node_modules\smpp\lib\smpp.js:67:33)     at connectSMPP (C:\work\SMPP\smppConnection.js:17:13)     at Object.<anonymous> (C:\work\SMPP\app.js:8:1)     at Module._compile (node:internal/modules/cjs/loader:1469:14)     at Module._extensions..js (node:internal/modules/cjs/loader:1548:10)     at Module.load (node:internal/modules/cjs/loader:1288:32)     at Module._load (node:internal/modules/cjs/loader:1104:12) {   code: 'ERR_SOCKET_BAD_PORT' }

Если мы неправильно ввели system_id или password, то соединение не будет установлено, и через 5 секунд отобразится ошибка:

Попытка привязки…

Привязка занимает больше 5 секунд. Закрытие сессии. Возможно, неверные данные или проблемы с сервером.

Соединение SMPP закрыто во время привязки. Вероятно, неверные данные аутентификации.

Тестирование отправки SMS

Удобнее всего тестировать через Postman. Отправим POST-запрос по API http://localhost:3000/send-sms. Тело запроса: 

{   "phoneNumber": "Ваш номер телефона",   "message": "Ваше сообщение",   "sender": "Номер телефона Exolve" }

Если введём неправильные номера, консоль сразу предупредит об этом. Если ошибок нет, то мы получим сообщение на указанный номер.

Получаем сообщение

Получаем сообщение

Обращайте внимание на PDU при отлавливании ошибок.

В этих отчётах есть вся нужная информация.

Тщательное изучение и умение работать с консолью поможет выявить и решить даже самую низкоуровневую проблему при работе с SMPP. А такие сервисы, как МТС Exolve, позаботились о подробной документации для работы с этим протоколом.


ссылка на оригинал статьи https://habr.com/ru/articles/863278/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *