RSocket — це прикладний протокол для мультиплексованого дуплексного зв'язку за протоколами TCP, WebSocket та іншими механізмами передачі байтових потоків, що використовує одну з таких моделей взаємодії:
-
Request-Response
— надсилання одного повідомлення та отримання одного у відповідь. -
Request-Stream
— надсилання одного повідомлення та отримання потоку повідомлень у відповідь. -
Channel
— надсилання потоків повідомлень в обох напрямках. -
Fire-and-Forget
— надсилання одностороннього повідомлення.
Після встановлення початкового з'єднання різниця між "клієнтом" і "сервером" втрачається, оскільки обидві сторони стають симетричними, і кожна сторона може ініціювати одну з перерахованих вище взаємодій. Саме тому в протоколі сторони, що беруть участь, називаються "реквестер (запитувач)" і "респондер (відповідач)", авказані вище взаємодії — "потоки запитів" або просто "запити".
Основні особливості та переваги протоколу RSocket:
-
Семантика Reactive Streams по межі мережі — для потокових запитів, таких як
Request-Stream
іChannel
, сигнали зворотної реакції проходять між реквестером і респондером, дозволяючи реквестеру уповільнити респондер у джерела, що знижує залежність від контролю навантажень на мережевому рівні, а також необхідність буферизації на мережевому рівні або на будь-якому іншому рівні. -
Регулювання (дроселювання запитів) — ця функція названа "Leasing (обмежене користування)" на ім'я кадру
LEASE
, який може бути відправлений з будь-якої сторони для обмеження загальної кількості запитів, дозволених іншою стороною за певний час. Періоди обмеженого використання періодично продовжуються. -
Відновлення сеансу — призначене для випадків втрати зв'язку та вимагає збереження певного стану. Управління станом для програм організовано прозоро і добре працює у поєднанні зі зворотною реакцією, яку може зупинити постачальник, коли це можливо, та зменшити величину необхідного стану.
-
Фрагментація та повторне складання великих повідомлень.
-
Keepalive (heartbeat-повідомлення).
У RSocket є реалізації кількома мовами. Бібліотека Java побудована на основі Project Reactor, а для передачі використовується Reactor Netty. Це означає, що сигнали від публікаторів Reactive Streams у твоєму додатку прозоро поширюватимуться через RSocket мережею.
Протокол
Однією з переваг RSocket є те, що він має чітко прописану логіку роботи "на льоту" і зрозумілу специфікацію, а також певні розширення протоколу. Тому доречно прочитати специфікацію, незалежно від реалізації мови та API фреймворків вищого рівня. Цей розділ містить короткий опис створення певного контексту.
Підключення
Спочатку клієнт підключається до сервера через низькорівневий потоковий засіб передачі, як-то протокол TCP або
WebSocket, і посилає серверу кадр SETUP
для встановлення параметрів з'єднання.
Сервер може відхилити кадр SETUP
, але зазвичай після його відправки (для клієнта) та отримання (для
сервера) обидві сторони можуть почати надсилати запити, якщо тільки SETUP
не вказує на використання
семантики обмеженого використання для обмеження кількості запитів, і в цьому випадку обидві сторони повинні
дочекатися кадру LEASE
з іншого боку, щоб дозволити робити запити.
Виконання запитів
Після встановлення з'єднання обидві сторони можуть ініціювати запит через один із кадрів
REQUEST_RESPONSE
, REQUEST_STREAM
, REQUEST_CHANNEL
або
REQUEST_FNF
. Кожен із цих кадрів несе одне повідомлення від реквестера до респондера.
Респондер може потім повернути кадри PAYLOAD
з повідомленнями у відповідь, а у разі REQUEST_CHANNEL
реквестер може також відпарвувати кадри PAYLOAD
з додатковими повідомленнями-запитами.
Якщо запит містить потік повідомлень, як-от Request-Stream
і Channel
, респондер
зобов'язаний слідувати сигналам запиту від реквестера. Запит виражається у кількості повідомлень. Початковий запит
вказується у кадрах REQUEST_STREAM
та REQUEST_CHANNEL
. Наступні запити сигналізуються за
допомогою кадрів REQUEST_N
.
Кожна сторона також може надсилати через кадр METADATA_PUSH
повідомлення про метадані, які стосуються не
окремого запиту, а з'єднання в цілому.
Формат повідомлення
Повідомлення RSocket містять дані та метадані. Метадані можуть бути використані для відправлення маршруту, токена
безпеки тощо. Дані та метадані можуть бути по-різному відформатовані. MIME-типи для кожного з них оголошуються у
кадрі SETUP
і застосовуються до всіх запитів для цього з'єднання.
Хоча всі повідомлення можуть містити метадані, зазвичай метадані, такі як маршрут, надаються щодо кожному запиту і,
отже, включаються тільки до першого повідомлення запиту, тобто до одного з кадрів REQUEST_RESPONSE
,
REQUEST_STREAM
, REQUEST_CHANNEL
або REQUEST_FNF
.
Розширення протоколу визначають загальні формати метаданих для використання у додатках:
-
Складені метадані — кілька незалежно відформатованих записів метаданих.
-
Маршрутизація — маршрут для запиту.
Реалізація Java
Java-реалізація для RSocket побудована на
основі Project Reactor. Механізми передачі для TCP та
WebSocket побудовані на базі Reactor Netty.
Будучи бібліотекою Reactive Streams, Reactor полегшує роботу з реалізації протоколу. У додатках цілком природним є
використання Flux
та Mono
з декларативними операторами та прозорою підтримкою зворотної
реакції.
API в RSocket для Java навмисно спрощено і є базовим. У ньому особливу увагу приділено особливостям протоколу та збереженню моделі прикладного програмування (наприклад, генератор коду для RPC порівняно з іншими) як незалежну функціональність вищого рівня.
Основний контракт io.rsocket.RSocket моделює чотири типи взаємодії запитів, водночас Mono
надає
проміс одного повідомлення, Flux
— потік повідомлень, а io.rsocket.Payload
— саме
повідомлення з доступом до даних та метаданих у вигляді байтових буферів. Контракт RSocket
використовується симетрично. У частині надсилання запитів програмі надається RSocket
для виконання
запитів. У частині надсилання відповідей програма реалізує RSocket
для обробки запитів.
Цей опис не є вичерпним вступом. Здебільшого додаткам Spring не доведеться безпосередньо використовувати його API. Однак може бути важливо побачити або поекспериментувати з RSocket окремо від Spring. Java-репозиторій для RSocket містить низку прикладів додатків, що демонструють API та можливості протоколу.
Засоби підтримки у Spring
Модуль spring-messaging
містить таке:
-
RSocketRequester — текучий API для виконання запитів через
io.rsocket.RSocket
з кодуванням/декодуванням даних та метаданих. -
Анотовані респондери — анотовані за допомогою
@MessageMapping
методи обробника для передачі відповіді.
Модуль spring-web
містить реалізації Encoder
та Decoder
, такі як Jackson
CBOR/JSON і Protobuf, які, швидше за все, знадобляться додаткам на RSocket. Він також містить PathPatternParser
,
який можна підключити для ефективного зіставлення маршруту.
Spring Boot 2.2 підтримує створення сервера RSocket через протоколи TCP або WebSocket, включно з можливістю
використання RSocket через WebSocket у сервері WebFlux. Також є підтримка клієнта та автоконфігурація для RSocketRequester.Builder
та RSocketStrategies
. Докладнішу інформацію див. у розділі, присвяченому RSocket у довіднику з Spring Boot.
Spring Security 5.2 передбачає підтримку RSocket.
Spring Integration 5.2 передбачає вхідні та вихідні шлюзи для взаємодії з клієнтами та серверами RSocket. Докладнішу інформацію див. у довідковому посібнику Spring Integration Reference Manual.
Spring Cloud Gateway підтримує з'єднання на основі RSocket.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ