Всем привет. Недавно у моих проектов перестали приходить пуш уведомления на устройства iOS. После процесса "гуглирования" выяснилось, что пуш уведомления для "яблок" теперь должны быть отправлены по протоколу http/2.

HEADERS
  - END_STREAM
  + END_HEADERS
  :method = POST
  :scheme = https
  :path = /3/device/00fc13adff785122b4ad28809a3420982341241421348097878e577c991de8f0
  host = api.development.push.apple.com
  authorization = bearer eyAia2lkIjogIjhZTDNHM1JSWDciIH0.eyAiaXNzIjogIkM4Nk5WOUpYM0QiLCAiaWF0I
 jogIjE0NTkxNDM1ODA2NTAiIH0.MEYCIQDzqyahmH1rz1s-LFNkylXEa2lZ_aOCX4daxxTZkVEGzwIhALvkClnx5m5eAT6
 Lxw7LZtEQcH6JENhJTMArwLf3sXwi
  apns-id = eabeae54-14a8-11e5-b60b-1697f925ec7b
  apns-expiration = 0
  apns-priority = 10
  apns-topic = <MyAppTopic>
DATA
  + END_STREAM
    { "aps" : { "alert" : "Hello" } }
Listing 8-3 shows a sample request constructed for a certificate that contains multiple topics.

Вот пример запроса по протоколу http/2

Но проблема заключалась в другом. В основном я использую ASP.NET Framework на базе сервера IIS. Сервер у меня на базе Windows 2012R2. Проблема в том, что данная версия не знает что такое HTTP/2 вообще. Я потратил несколько дней на тщетные попытки что-то сделать. Переустанавливать сервер нет возможности. Так как на нем запущены множество проектов и останавливать их работу нельзя. В данном случае не уходили только пуш сообщения на "яблоки". С устройствами ANDROID проблем таких не возникает.

Решение проблемы

Совсем не так давно я интересовался новой технологией ASP.NET Core. Проекты ASP.NET Core можно публиковать на сервере с Linux. Linux дружит с HTTP/2.

Было принято решение написать облачный сервис на ASP.NET Core и отправлять туда пост запросом пуш сообщение и токен устройства для получения.

Я взял библиотеку для работы с ASP.NET Core. Немного модифицировал и скомпилировал проект

 public class dotAPNSService : IDisposable
    {
        public event EventHandler OnTokenExpiredHandler;
        private ApnsJwtOptions options = null;

        public dotAPNSService(string bundle)
        {
            options = new ApnsJwtOptions()
            {
                BundleId = bundle, // здесь нужно указать название проекта com.org.test
                CertContent = "Здесь необходимо указать сертификат полученный в кабинете разработчика",//https://developer.apple.com/account/resources/authkeys/list
                KeyId = "здесь ид ключа",//https://developer.apple.com/account/resources/authkeys/list
                TeamId = "здесь ид команды"//https://developer.apple.com/account/resources/authkeys/list
            };
        }

        public void SendNotifications(String[] deviceTokens, String title, String body)
        {
            if (deviceTokens == null || deviceTokens.Length <= 0)
            {
                return;
            }

            if (String.IsNullOrEmpty(title))
            {
                return;
            }

            if (String.IsNullOrEmpty(body))
            {
                return;
            }

            // once you've gathered all the information needed and created an options instance, it's time to call
            var apns = ApnsClient.CreateUsingJwt(new HttpClient( ), options);

            // start the process     
            foreach (String deviceToken in deviceTokens)
            {
                var push = new ApplePush(ApplePushType.Alert)
                    .AddAlert(title, body)
                    .AddToken(deviceToken);

                Send(apns, push, deviceToken);
            }
        }
}

ВНИМАНИЕ!!! Сохраните ключ в надежном месте. Насколько мне известно второй раз вы его не скачаете. Его можно скачать только один раз.

Запуск

Для запуска NET.Core на линукс я использовал Docker. Я использовал VPS сервер от компании REG.RU. В личном кабинете покупаем VPS.

Обратите внимание! У рег.ру только облачные серверы поддерживают нужную виртуализацию для докера. Также только облачные поддерживают смену ядра линукса. Это официальный ответ их службы поддержки.

Заходим и выбираем сервер с установленным докером

создаем пользователя на докере

публикуем приложение через Visual Studio

Вводим логин пароль от докера и приложение публикуется.

Далее просто подключается к нашему серверу через SSH. ключи доступа придут к Вам на эл почту.

Вводим команду на запуск вашего проекта из докера

docker run -d -p 80:80/tcp учетнаязапись/названиепроекта

после этой команды ваш проект будет доступен по адресу http://ипадрессервера/

Далее во всех проекта я просто отправляю пост запрос по этому адресу с массивом токенов получателей заголовком и сообщением. Все уходит и приходит просто супер быстро.

P.S. Вы можете привязать доменное имя в настройках рег.ру.

Итог

В данный момент все пуш сообщения уходят нормально. Проблем с такой связкой не обнаружено. Даже кажется что пуши уходят намного быстрее чем это работало раньше. Надеюсь моя статья поможет тем, кто столкнулся с аналогичной проблемой.