В прошлом году я покинул Mail.Ru, где проработал почти 7 лет. Я присоединился к Avito в конце лета - крупнейшей в России рубрике, где я сейчас работаю над внутренней платформой для обмена сообщениями. Если вы читали некоторые из моих предыдущих постов, то знаете, что обмен сообщениями, особенно обмен сообщениями в реальном времени, - это то, что меня больше всего волнует.

На новой работе познакомился с новыми интересными технологиями, с которыми никогда раньше не работал - Kubernetes, RabbitMQ, MongoDB. Изменения в жизни, новый опыт и новая команда вдохновили меня на продолжение работы над проектом Центрифуго, и теперь я рад сообщить о некоторых интересных вещах.

Во-первых, я его сломал. Последние несколько месяцев я работал над Centrifugo 2, который обратно несовместим с 1.x. И этот факт меня действительно пугает. Последние несколько лет я старался изо всех сил, разрабатывая экосистему Centrifugo для разных языков - API и клиентские библиотеки для Android, iOS, Python, NodeJS, Ruby, PHP, Go. Некоторые из этих библиотек я написал сам, некоторые - при большой помощи сообщества разработчиков ПО с открытым исходным кодом. Теперь, похоже, мне нужно начинать с нуля. И это будет тяжело.

Позвольте мне объяснить, почему я принял это решение и сделал версию 2 обратно несовместимой. Внутренний протокол клиент-сервер Centrifugo родился много лет назад, когда Centrifugo писали на Python. Конечно, протокол немного изменился за время своего жизненного цикла, но по своей сути оставался довольно стабильным. Одной из самых важных функций Centrifugo 2 будет поддержка двоичных веб-сокетов. И поскольку Centrifugo имеет собственное формирование JSON поверх соединения Websocket / SockJS для различных сообщений (подключение и аутентификация, подписка на канал, сообщения разных типов, полученные из канала и т. Д.), Мне нужен дополнительный уровень кодирования поверх двоичных кадров Websocket и выбор был довольно очевиден - Протобуф. Но я быстро понял, что то, что возможно с JSON, не подходит для Protobuf. Внутренние сообщения должны быть действительно хорошо организованы - и на самом деле хорошо, что Protobuf обеспечивает это - поэтому мне пришлось внести некоторые обратно несовместимые изменения в протокол Centrifugo. На самом деле, без значительного рефакторинга было бы почти невозможно реализовать некоторые вещи, о которых я расскажу ниже.

Но! Сервер Centrifugo будет решать ту же задачу, что и раньше, и будет иметь те же концепции, что и раньше. Это автономный сервер, который работает рядом с серверной частью вашего приложения, помогает поддерживать постоянные соединения и имеет API для доставки сообщений в реальном времени подключенным клиентам. Работа над версией 2 на данный момент сосредоточена в ветке c2.

Здесь я хочу вкратце выделить некоторые функции v2, не вдаваясь в подробности. На самом деле их гораздо больше, чем я пишу здесь, но давайте поговорим о наиболее важных частях.

Как я уже указывал выше, внутренний протокол теперь полностью описывается схемой Protobuf. Centrifugo 2 может поддерживать не только JSON для связи клиент-сервер, но и двоичные фреймы Websocket. Заставить его работать с двумя форматами кодирования было довольно сложно, но похоже, что это уже работает в ветке разработки Centrifugo v2.

Следующее, что следует упомянуть, это то, что Centrifugo теперь поддерживает двунаправленную потоковую передачу GRPC для связи клиент-сервер. На данный момент это довольно экспериментально, но я думаю, что это отличная функция - например, иметь возможность работать через Websocket с клиентами браузера и через GRPC с клиентами мобильных приложений.

Я всегда был уверен, что в Centrifugo есть полезный код, который можно использовать повторно, даже если сам сервер не соответствует чьим-то потребностям или ожиданиям. Некоторые люди спрашивали меня, можно ли использовать Centrifugo в качестве библиотеки из кода Go. Ответ был такой:

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

Одной из моих целей при разработке Centrifugo 2 было выделить ядро ​​Centrifugo, работающее в реальном времени, в отдельную библиотеку. Пока я еще не закончил работу, вы можете найти репозиторий незавершенной работы с этой библиотекой по адресу https://github.com/centrifugal/centrifuge. Centrifugo 2 будет использовать эту библиотеку для внутренних целей. И теперь программисты Go могут использовать его для создания приложений Go в реальном времени.

Давайте посмотрим на простой пример использования библиотеки Centrifuge в приложении Go:

А на стороне клиента, например в браузере:

В этом примере показано, как использовать библиотеку Centrifuge для простых вещей, таких как ведение журнала, когда клиенты подключаются к серверу и отключаются от него, а также для ответа на запросы RPC от клиентов. В этом примере все работает через Websocket. Но также можно запустить обработчик SockJS или запустить сервер GRPC, чтобы сделать то же самое с альтернативными транспортами. И вы можете запустить множество узлов Centrifuge и подключить их через Redis PUB / SUB и с поддержкой сегментирования. Имейте присутствие, историю, события присоединения / выхода и функции восстановления сообщений из коробки - то есть все, что было на сервере Centrifugo, будет в библиотеке. Поскольку библиотека поддерживает двоичные веб-сокеты, с ее помощью можно даже создавать многопользовательские игры в реальном времени.

Также можно обернуть обработчик Websocket любым промежуточным программным обеспечением и аутентифицировать / авторизовать соединения и действия, которые они хотят выполнять, используя любой механизм, который вы обычно используете в приложении Go.

Плохая новость в том, что у нас пока нет клиентов (даже браузер, хотя минимальный рабочий прототип находится в centrifuge-js ветка c2) - поэтому все, что я описал выше, в настоящее время в основном на бумаге, хотя серверная часть в основном закончена. . Надеюсь, что ситуация с клиентами со временем изменится, и я скоро смогу показать больше.

Итак ... В данный момент эта работа продолжается, и многие вещи еще предстоит сделать в дорожной карте. Я делюсь этим постом, чтобы попросить помощи и отзывов сообщества разработчиков ПО с открытым исходным кодом. Вы лично заинтересованы в подобной библиотеке? Можете ли вы помочь с дизайном API библиотеки или обзором кода? Не могли бы вы попробовать создать с его помощью приложение реального времени и оставить отзыв? Может быть вам интересно написать клиента? Любая помощь приветствуется.

Если вы хотите каким-то образом помочь с проектом, вы можете отправить мне сообщение в Centrifugo Чат Gitter или по электронной почте - см. Мой профиль Github.