Используем вебсокеты в своем iOS приложении

Добрый день, уважаемые читатели Хабрахабра!

Сегодня я хочу рассказать вам о том, как просто и быстро подключить вебсокеты в свое iOS приложение на примере чата известной биржи криптовалют. Реализуем мы это при помощи удобного открытого решения SocketRocket.

Этот подход может пригодиться для:

  • Реализации чата в мобильном клиенте под iOS
  • Использовании информации чата для обучения нейронных сетей

Заинтересовавшихся прошу под кат!

Добавляем SocketRocket в проект

На гитхабе описано несколько вариантов установки, я опишу тот, которым пользуюсь сам.

  1. Добавляем в наш проект все файлы из группы «SocketRocket»
  2. Добавляем следующие фреймворки в проект:
    • libicucore.dylib
    • CFNetwork.framework
    • Security.framework
    • Foundation.framework
  3. Добавляем в проект расшифровщик HTML символов от Google (позже поймете, зачем)

Ничего сложного! Все готово для использования всей мощи вебсокетов.

Инициализируем сокеты

Методами информационного поиска, дедукции и с помощью отзывчивых разработчиков биржы, я наткнулся на открытый источник, откуда вырвал нужный URL для сокетов чата:

NSURL *url = [NSURL URLWithString:@"wss://ws.pusherapp.com/app/4e0ebd7a8b66fa3554a4?protocol=6&client=js&version=2.0.0&flash=false"];

Создаем сам объект сокета с нужным запросом, открываем его и делаем себя делегатом:

NSURLRequest *request = [NSURLRequest requestWithURL:url];
SRWebSocket *rusSocket = [[SRWebSocket alloc] initWithURLRequest:request];
rusSocket.delegate = self;
[rusSocket open];

Полный код метода setupSockets
- (void)setupSockets
{
    NSURL *url = [NSURL URLWithString:@"wss://ws.pusherapp.com/app/4e0ebd7a8b66fa3554a4?protocol=6&client=js&version=2.0.0&flash=false"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    SRWebSocket *rusSocket = [[SRWebSocket alloc] initWithURLRequest:request];
    rusSocket.delegate = self;
    [rusSocket open];
}


Методы SRWebSocketDelegate

В каждом уважающем себя фреймворке под Objective-C обязательно должны быть делегаты — а в вебсокетах и подавно. Мы реализуем два метода делегата — первый, который вызывается после установки соединения и открытия сокета, и второй, вызываемый по получению сообщения.

- (void)webSocketDidOpen:(SRWebSocket *)webSocket
{
    NSString *helloMsg = @"{\"event\":\"pusher:subscribe\",\"data\":{\"channel\":\"chat_ru\"}}";
    [webSocket send:helloMsg];
}

Здесь все предельно просто: как только сокеты открываются, мы подписываемся на оповещения из русского чата. По аналогии, можно прописать и «chat_en».

Дальше мы описываем метод получения сообщения от вебсокета:

- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message
{
    message = [[message stringByReplacingOccurrencesOfString:@"///" withString:@""] stringByReplacingOccurrencesOfString:@"\\\\\\" withString:@""];
    message = [message gtm_stringByUnescapingFromHTML];
}

Опять же, все просто. В первой строке метода мы избавляемся от мусора, во второй мы используем категорию от Google для того, чтобы преобразовать HTML символы в читаемые пользователем. Message и есть наше сообщение — дальше его можно парсить так, как душе угодно.

Пример сообщения
{«event»:«msg»,«data»:"\"{«uid»:«467754»,«login»:«BTCalexxx»,«msg»:«anyone in for a short ltc pump to 15?»,«msg_id»:12268748,«date»:«04.03.14 07:37:50»,«usr_clr»:"#8da0b9"}\"",«channel»:«chat_en»}

Закрываем соединение

Всегда закрывайте соединение, когда оно вам уже не нужно! Сделать это можно следующим методом:

[rusSocket close];

Заключение

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

В следующей статье могу описать, как создать свой WhatsApp при помощи открытых инструментов за 4-5 часов работы. Конечно, если вам, дорогие читатели, будет интересно.
Метки:
Поделиться публикацией
Похожие публикации
Комментарии 24
  • +7
    Чудесно. Если принимаете заявки, то, пожалуйста, опишите пример соккетов на карточный игре один-на-один. Диберц, кинг, очко, три палки, фараончик, волосинка, акулина, что угодно, на Ваш вкус.
    • 0
      Не знаю, за что вам минус поставили, но мне и самому эта тема очень интересна.

      К сожалению, я не работал с подобного рода использованием сокетов — поэтому, увы, не могу описать пример.
      • +1
        это же боты сработали на слова: очко, три палки и волосинка, но Человек вышел победителем (исправили ситуацию)
      • 0
        А чего там описывать то? один-на-один, это всего 2 клиента в рамках одного пула, один толкает сообщение серверу, что он делает, сервер шлёт сообщение второму клиенту.
      • 0
        Я конечно может что-то не понимаю, но пример реалзиации вебсокета есть прямо в на гитхабе в самой socketroket. И просто показать то, что может одна либа недостойно статьи на хабре. Есть еще куча реализаций этого протокола. Есть Socket-IO. Можно попытаться сделать energy-diagnostic, чтобы показать как классно юзать вебсокеты. А это по сути капитанская статья. То есть надо показать преимущества и недостатки данного подхода к организации работы с сетью. А это тупо пересказ того, что я и так могу найти в интеренете в два клика. Извините, накипело.
        • 0
          Простите, это моя первая статья на Хабре — впредь буду писать материалы потолще :)
      • +1
        Судя по найденному вами url, в чате используется Pusher.com, а значит можно использовать их библиотеку libpusher (кстати она также требует socketrocket).
        • 0
          Судя по всему, так оно и есть :)
        • +1
          «В следующей статье могу описать, как создать свой WhatsApp при помощи открытых инструментов за 4-5 часов работы. Конечно, если вам, дорогие читатели, будет интересно.»

          Не думаю что за 4-5 часов работы можно сделать что-то уникальное. Вы случаем на PubNub имеете ввиду под «открытыми инструментами»? Так там все достаточно просто, советую не портить карму.
          • +2
            Можно сделать, не уникальное, конечно — ведь WhatsApp уже существует :)

            Под «открытыми инструментами» имею ввиду сервис от C2Call. Мне пришлось сильно углубиться в него, чтобы реализовать кастомный чат для одного клиента — вот и хочу поделиться опытом.

            Если не проходить мой путь проб и ошибок из-за недостатка официальной документации, то вместо моей недели можно потратить всего 4-5 часов и получить готовый WhatsApp с чатом, пересылкой файлов, видеочатом, голосовыми звонками, звонками на оффлайн телефоны, историей чатов и т.д. и т.п. :)

            Да, там все совсем не так просто, как кажется на первый взгляд.
            • +1
              Ждём. Заранее спасибо.
          • 0
            Как создать соединение и закрыть его — можно прочитать и в доке либы. А вот как организовать работу вебсокета в фоновом режиме в IOS, я так и не разобрался. Если есть знающие люди, очень прошу подсказать, куда копать хотя бы. Т.к. через 10 минут работы сокет рвет соединение. А если поставить флаг voip, с которым все работает, то в сторе отказ получается, т.к. нет реализованного функционала voip.
            • 0
              Никак, «честный» бэкграунд простым чатам недоступен.
              Разве что в iOS 7 можно по пушам и/или периодически получать данные.
              • 0
                Спасибо за ответ. Этого я и боялся. В любом случае вебсокет слишком «дорогой» протокол для батареи. Будем думать, как это оптимизировать :)
                • 0
                  А нет ли какой-нибудь ссылки с тестами потребления батареи при использовании веб-сокетов? Было бы здорово почитать.
                  • 0
                    >> слишком «дорогой» протокол для батареи

                    вероятно этим и объясняются все ограничения яблока по поводу фонового режима.
                    • 0
                      Простите, а на чем основано ваше предположение, что вебсокет дорог для батареи? Насколько я знаю, то батарею ест не поддержка постоянного соединения, а количество данных передаваемых через сеть.
                      • 0
                        Все верно. Вебсокет подразумевает как раз постоянную передачу данных, т.к. этот протокол все же предусмотрен больше для реалтайм обмена данными. Именно поэтому я так и написал. Можно сократить объем передаваемых данных, а также частоту, но тогда зачем нужен вебсокет? Когда можно ограничиться пушами и т.д. :)
                        • 0
                          Я думаю что реалтайм и постоянная передача данных — разные вещи. В нашем приложении мы используем вебсокет, как раз для реалтайма. А передача данных происходит всего несколько раз в минуту. То есть по расходу батареи мы в этом случае выигрываем, так как не дергаем сервер каждые 5-10 секунд для синхронизации.
                          • 0
                            Если у вас данные передаются раз в N минут, то зачем дергать сервер каждые 5-10 секунд? И если данные идут только с сервера, почему бы не использовать пуш с нагрузкой, который в устройстве оптимизирован по потреблению (насколько я помню, телефон может получать пуши даже в случае спячки)?

                            В любом случае, в нашем приложении проблема в том, что данных бегает очень много и слишком часто. Это нужно оптимизировать, что мы и делаем :) Другое дело, что для поддержания вебсокета нужно использовать вейк локи, которые и сажают батарею, т.к. ни проц, ни wifi не могут уснуть.
                    • 0
                      это решается если приложение описано в манифесте как voip — но там придется много взаимодействовать с платформой, чтобы прошло…
                  • +2
                    Добавляем SocketRocket в проект


                    Используем CocoaPods и не парим себе и другим мозг.

                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.