![](https://habrastorage.org/getpro/geektimes/post_images/fd3/d6c/fca/fd3d6cfca5053dd6a071a02ce74c3bb5.jpg)
В этой статье я поделюсь опытом прямой интеграции с крупным российским сотовым оператором (обратите внимание: именно напрямую, а не через шлюзы), а также на вводном уровне порассуждаю об околоSMS-ных технологиях и протоколе SMPP — без скучных таблиц и спецификаций, в стиле короткой детективной истории.
Завязка сюжета
Однажды мы (Рутвит) обратились с предложением к крупнейшему оператору связи — компании МТС. Мы понимали: чтобы сделать цену твита неотличимой от цены обычного SMS, нужна прямая интеграция с ОПСОС-ом (кстати, это слово расшифровывается как «Оператор Сотовой Связи»). МТС — огромная компания, заточенная на сотрудничество с крупными партнерами, поэтому я полагал, что наше предложение рассмотрят нескоро, и не особенно рассчитывал на успех. Какова же была наша радость, когда МТС не только быстро ответила, но и в результате конструктивных переговоров приняла решение запустить совместный проект с Рутвитом.
Все мы знаем, что крупные компании зачастую медлительны и неповоротливы, однако это, похоже, не относится к МТС. Рабочая группа, с которой мы контактировали в процессе интеграции, быстро реагировала на наши вопросы, и мы продвигались вперед. Это было особенно ценно в той связи, что прямая интеграция с сотовым оператором оказалась на порядок сложнее, чем подключение какого-нибудь популярного SMS-шлюза: я еще расскажу о технических подробностях ближе к концу статьи.
И вот мы сначала запустили альфа-версию SMS-сервиса на Рутвите (читать совместный с МТС пресс-релиз на сайте ПРАЙМ-ТАСС), а сегодня заменяем в этом сервисе значок «альфа» на «бету», о чем и сообщаем в данной статье. Сервис, помимо прочего, позволяет отправлять твиты с помощью SMS по обычной стоимости (согласно тарифного плана абонента) не только в Рутвит, но и в большой Твиттер — через механизм экспорта.
Итак, отправлять твиты по SMS можно ровно за те же деньги, за которые вы отправляете любую другую SMS. Для этой же цели мы решили использовать не короткий номер, а более привычный, длинный: +7 916 140-0-140. Люди часто не доверяют коротким номерам, т.к. не уверены, сколько денег с них снимут за SMS: с длинным номером такой проблемы как будто бы нет.
Как начать писать твиты по SMS?
Чтобы начать писать твиты по SMS, введите номер своего телефона на сайте Рутвита:
![](https://habrastorage.org/getpro/geektimes/post_images/866/f06/1da/866f061da69914d5b34b8d077174acb7.png)
Затем отправьте слово «да» (регистр не важен) на номер Рутвита +7 916 140-0-140. Как только робот увидит это сообщение, он привяжет ваш номер к вашему аккаунту, и все последующие SMS на номер +7 916 140-0-140 будут восприниматься как твиты от вашего имени.
А еще можно писать SMS по себестоимости в Твиттер, FriendFeed, Facebook, LiveJournal, Buzz
Если вы поклонник Твиттера, настройте экспорт сообщений Рутвит -> Твиттер (или FriendFeed, Facebook, LiveJournal, Buzz) и пишите в Твиттер (FriendFeed, Facebook, LiveJournal, Buzz) SMS по себестоимости, используя Рутвит в качестве шлюза:
![](https://habrastorage.org/getpro/geektimes/post_images/e4b/1ea/fb0/e4b1eafb007630e87592b9206a30f2d6.png)
(Для справедливости стоит отметить, что в Twitter можно отправлять SMS и через зарубежные шлюзы, однако в России это получается сильно дороже: ведь SMS на британский номер +44xxxx, предоставляемый Твиттером, дороже SMS на российский номер Рутвита +7 916 140-0-140.)
Теперь ложка дегтя, присутствующая в бета-версии. Одна из наших целей — сделать так, чтобы пользователь мог не только отправлять SMS в Рутвит по цене обычного SMS, но также и бесплатно получать по SMS твиты на мобильный телефон. Некоторые сервисы микроблогов просто покупают GSM-модем (или смартфон с Linux) и принимают/отправляют SMS через него, однако этот способ работает только на небольших объемах трафика: он плохо масштабируется. Тем не менее, мы хотим избавить пользователей социальных сетей от дополнительных затрат при активации и пользовании данным сервисом. Но только техническая интеграция и заключение договора напрямую с оператором позволит этого добиться. А пока идут переговоры, в бета-версии не реализована возможность приема SMS на телефон: можно только отправлять твиты в систему. В этом вопросе мы делаем ставку на будущее.
Технические подробности прямой интеграции
Мы раньше никогда не работали с SMS и протоколом SMPP. И, когда мы подписали договор с МТС, мы столкнулись с выбором:
- либо сделать SMPP-клиента вручную (с использованием модулей для Perl, например);
- либо использовать готовый SMPP-сервер промышленного масштаба (самый популярный из них — Kannel).
Немного о SMPP, протоколе передачи SMS-сообщений
Протокол SMPP (расшифровывается как «Short Message Peer to Peer») сам по себе весьма сложен. Он очень низкоуровневый (спецификации занимают 170 страниц). Сложность обусловлена, главным образом, историческими причинами. Группа протоколов для передачи голоса разрабатывалась в 1975 г. В те времена никаких SMS еще не было (не было даже ЖК-дисплеев для сотовых телефонов, как и самих мобильников). И вот, в 1985 г. в стандартные пакеты протокола передачи голоса решили «упихать» поддержку текстовых сообщений. Но полезного места в этих пакетах было мало, поэтому сообщения получились короткими, всего 160 символов — Short Messages.
Полезный объем данных, который можно передать в SMPP-пакете, составляет 140 байт. Это не опечатка. Как же в них поместилось 160 символов? Вы, наверное, уже догадались: 1 символ ASCII можно закодировать 7 битами. Таким образом, получается 160 * 7 = 1120 бит, или 140 байт.
Если бы мы жили в США, где кодировки ASCII «должно быть достаточно каждому», то мы бы спокойно писали твиты размером 160 символов. Однако при передаче русских букв по SMS они упаковываются в кодировку UTF-16, т.е. 2 байта на 1 русскую букву. Поэтому в 1 сообщении может поместиться не более 140/2 = 70 символов русского алфавита. Если текст длиннее, он упаковывается в 2 и более SMS-сообщения, которые затем «склеиваются» при отображении на телефоне.
Но это еще не все. В 2 SMS-сообщениях можно доставить вовсе не 70 * 2 = 140 русских букв, а всего только 134. Дополнительное место требуется для кодирования служебной информации, в частности, информации о числе SMS в цепочке и номере текущей SMS в ней.
Kannel сотоварищи
Сервер Kannel, который мы использовали, на самом деле имеет более широкую область применимости. Он предназначен для контент-провайдинга, когда запрос представляет собой SMS, а ответ — некоторый SMS-контент: мелодии, картинки и т.д. Мы используем только ту часть, которая организует прием и трансляцию SMS: Kannel принимает SMPP-сообщение, распаковывает/расшифровывает его и передает нам HTTP-запросом номер телефона и текст. В ответ же мы не посылаем никакого контента.
Правда, не обошлось без сюрпризов. У МТС весьма скурпулезная схема тестирования: мы не только должны корректно принимать сообщения, но и укладываться во всевозможные тайм-ауты при постановке запросов в очередь, поддерживать throttling, вовремя отправлять сообщения-подтверждения доставки при взрывном росте нагрузки. На тестовом стенде мы столкнулись с проблемой, для решения которой нам пришлось немного пропатчить Kannel (он написан на Си). Вкратце ее можно описать так: предположим, на Kannel пришли 2 SMPP-пакета, а третий — уперся в ограничение пропускной скособности, заданной МТС, а поэтому — застрял в очереди. Если теперь ограничение снялось, но тут же пришло 4-е сообщение, то в стандартном варианте Kannel поставит это 4-е сообщение перед всеми ранее застрявшими. Поэтому 3-е сообщение опять окажется в конце очереди и будет отодвигаться все дальше и дальше по мере поступления новых SMS. Оказывается, для нагрузочных тестов МТС это поведение имеет значение — как и многие другие аспекты, которые пришлось учесть при прямой интеграции.
Мы не имели опыта работы с SMPP ранее, но Kannel позволил нам выкарабкаться. На наше счастье, Kannel даже в базовой конфигурации обрабатывает очень многое из того, что было нужно ОПСОС-у. Но, положа руку на сердце, сейчас, уже «съев собаку» на SMPP, мы бы стали все делать с использованием Perl и модулей с CPAN, а не Kannel. Но это было бы возможно только благодаря тому опыту, который мы получили с Kannel. Без этого опыта программирование прямой интеграции с ОПСОС-ом на Perl — все равно, что учить человека плавать, бросив его в воду с обрыва: может, и научится, а может, утонет. МТС особенно скурпулезен при тестировании обработки ошибок, выдерживания разнообразных тайм-аутов. Например, четко регламентируется время отправки подтверждений *_resp на SMPP-сообщения: задержки должны укладываться в заданные МТС временные интервалы. Если вы решите работать с SMPP напрямую, изучите вначале Kannel: я бы рекомендовал делать вам собственное решение, повторяя архитектуру Kannel-а, особенно — аспектов буферизации сообщений.