Рубрики
Без рубрики

Начало Работы С Ракетой Часть 1

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

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

1. Вступление

Rocket – это двоичный протокол, который используется поверх TCP или WebSockets. Rocket – это протокол связи, который охватывает Реактивные принципы . Это означает, что Rocket использует асинхронную связь. Он также подходит для push-уведомлений. Например, при использовании HTTP возникнет необходимость в опросе, чтобы проверить, доступны ли новые сообщения. Это приводит к ненужной нагрузке на сеть. Сокет предоставляет решение для этого. Существует 4 коммуникационные модели, которые можно использовать:

  • Запрос-Ответ (поток из 1)
  • Выстрели и забудь (ответа нет)
  • Поток запросов (поток из многих)
  • Канал (двунаправленные потоки)

Сокет расположен на уровне OSI 5/6 и, следовательно, на Прикладном уровне модели TCP/IP.

В следующих разделах вы найдете примеры для каждой модели связи: на стороне сервера, на стороне клиента и модульного теста. Исходный код, используемый в этом посте, конечно же, доступен по адресу GitHub .

2. Справочная документация

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

Всю информацию о протоколе, спецификации, реализациях можно найти на официальном Веб-сайт ракеты .

Платформа Spring поддерживает протокол сокетов.

Справочный раздел Spring Boot для протокола сокета.

Бен Уилкок написал несколько потрясающих блогов о протоколе сокетов. Полный список можно найти по адресу GitHub .

3. Модель Запроса-Ответа

Модель запроса-ответа позволит вам отправить один запрос и получить один ответ в ответ. Первое, что нужно сделать, это настроить базовое приложение Spring Boot. Перейдите на веб-сайт Spring Initializr , добавьте зависимость Сокет и создайте проект, который вы можете открыть в своей любимой среде разработки. При проверке pom вы замечаете, что добавлены зависимости spring-boot-starter-rocket и зависимость реактор-тест . Первый из них позволит включить поддержку сокетов в вашем приложении Spring Boot, второй необходим для целей тестирования.


    org.springframework.boot
    spring-boot-starter-rsocket

...

    io.projectreactor
    reactor-test
    test

Исходный код на GitHub разделен на два модуля Maven, один для сервера и один для клиента .

Для обмена информацией между клиентом и сервером вы создаете класс данных Notification , который будет элементом для передачи через RSocket. Класс Уведомление содержит Источник ,/| Пункт назначения и немного свободного Текста . Реализация toString будет использоваться для целей ведения журнала.

public class Notification {
    private String source;
    private String destination;
    private String text;

    public Notification() {
        super();
    }

    public Notification(String source, String destination, String text) {
        this.source = source;
        this.destination = destination;
        this.text = text;
    }

    public String getSource() {
        return source;
    }

    public String getDestination() {
        return destination;
    }

    public String getText() {
        return text;
    }

    @Override
    public String toString() {
        return "Notification{" +
                "source='" + source + '\'' +
                ", destination='" + destination + '\'' +
                ", text='" + text + '\'' +
                '}';
    }
}

3.1 Серверная Часть

Вы создаете контроллер сервера сокетов R и аннотируете его с помощью @Controller . Чтобы создать свой первый пример запроса-ответа сокета, вы просто добавляете метод ответ на запрос который принимает Уведомление , регистрирует полученный Уведомление и возвращает новое Уведомление где вы меняете местами полученный источник и пункт назначения и добавляете к нему простой текст. Чтобы сделать это запросом сокета, вам нужно аннотировать метод с помощью @MessageMapping и дать ему имя, например мой запрос-ответ .

@Controller
public class RsocketServerController {

    Logger logger = LoggerFactory.getLogger(RsocketServerController.class);

    @MessageMapping("my-request-response")
    public Notification requestResponse(Notification notification) {
        logger.info("Received notification for my-request-response: " + notification);
        return new Notification(notification.getDestination(), notification.getSource(), "In response to: " + notification.getText());
    }
}

Чтобы убедиться, что сервер сокетов запущен, вам также необходимо добавить порт в файл application.properties :

spring.rsocket.server.port=7000

Запустите сервер:

$ mvn spring-boot:run

В журнале регистрации вы заметили, что веб-сервер Netty запущен. Netty – это реактивный аналог веб-сервера Jetty.

Netty RSocket started on port(s): 7000

3.2 Клиентская сторона

Клиентская сторона немного сложнее. Вы снова создадите приложение Spring Boot, которое отправит Уведомление сообщение на сервер. Отправка сообщения будет вызвана с помощью http-вызова. Поэтому вы добавляете зависимость spring-boot-starter-web flux в клиент pom . Имейте в виду, что вы не можете использовать spring-boot-starter-web , вам нужно использовать вариант реактивного webflux.


    org.springframework.boot
    spring-boot-starter-webflux

Убедитесь, что вы не определяете порт в application.properties ,

2021-01-02 12:04:58.853 ERROR 19058 --- [           main] o.s.boot.SpringApplication               : Application run failed
org.springframework.context.ApplicationContextException: Failed to start bean 'rSocketServerBootstrap'; nested exception is reactor.netty.ChannelBindException: Failed to bind on [0.0.0.0:7000]
...
Caused by: reactor.netty.ChannelBindException: Failed to bind on [0.0.0.0:7000]
    Suppressed: java.lang.Exception: #block terminated with an error
...

Вы создаете контроллер R SocketClient и аннотируете его с помощью @RestController . Далее вам нужно создать R Запрашивающий сокет экземпляр для того, чтобы иметь возможность подключиться к серверу сокетов. В методе RequestResponse вы создаете сообщение Уведомление (для простоты использования просто скопируйте класс Уведомление из серверного модуля и убедитесь, что он также присутствует на стороне клиента) и с помощью rSocketRequester экземпляр, вы указываете маршрут, по которому вы хотите отправить сообщение (имя равно имени, указанному в аннотации @MessageMapping на стороне сервера), данные, которые вы хотите отправить, и, наконец, ожидаемый ответ. Ответ будет Моно , что означает, что вы ожидаете один ответ от сервера, и ответ должен быть Уведомлением сообщением. Само сообщение возвращается вызывающему абоненту.

@RestController
public class RsocketClientController {

    private static final String CLIENT = "Client";
    private static final String SERVER = "Server";

    private final RSocketRequester rSocketRequester;

    Logger logger = LoggerFactory.getLogger(RsocketClientController.class);

    public RsocketClientController(@Autowired RSocketRequester.Builder builder) {
        this.rSocketRequester = builder.tcp("localhost", 7000);
    }

    @GetMapping("/request-response")
    public Mono requestResponse() {
        Notification notification = new Notification(CLIENT, SERVER, "Test the Request-Response interaction model");
        logger.info("Send notification for my-request-response: " + notification);
        return rSocketRequester
                .route("my-request-response")
                .data(notification)
                .retrieveMono(Notification.class);
    }
}

Запустите как сервер, так и клиент и вызовите URL-адрес:

$ curl http://localhost:8080/request-response
{"source":"Server","destination":"Client","text":"In response to: Test the Request-Response interaction model"}

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

Клиент:

Send notification for my-request-response: Notification{source='Client', destination='Server', text='Test the Request-Response interaction model'}

Сервер:

Received notification for my-request-response: Notification{source='Client', destination='Server', text='Test the Request-Response interaction model'}

3.3 Тестовая сторона

Создание теста для кода сервера очень похоже на создание кода клиента. Для настройки соединения необходимо создать R-запрос сокета . Отправка сообщения идентична коду клиента, только на этот раз вы помещаете ответ в переменную результат типа Mono<Уведомление> . Вы можете использовать эту переменную результат в Пошаговом верификаторе для проверки полученного ответа. С помощью Пошагового верификатора вы можете проверить реактивные ответы в своем модульном тесте.

@SpringBootTest
class MyRsocketServerPlanetApplicationTests {

    private static final String CLIENT = "Client";
    private static final String SERVER = "Server";

    private static RSocketRequester rSocketRequester;

    @BeforeAll
    public static void setupOnce(@Autowired RSocketRequester.Builder builder, @Value("${spring.rsocket.server.port}") Integer port) {
        rSocketRequester = builder.tcp("localhost", port);
    }

    @Test
    void testRequestResponse() {
        // Send a request message
        Mono result = rSocketRequester
                .route("my-request-response")
                .data(new Notification(CLIENT, SERVER, "Test the Request-Response interaction model"))
                .retrieveMono(Notification.class);

        // Verify that the response message contains the expected data
        StepVerifier
                .create(result)
                .consumeNextWith(notification -> {
                    assertThat(notification.getSource()).isEqualTo(SERVER);
                    assertThat(notification.getDestination()).isEqualTo(CLIENT);
                    assertThat(notification.getText()).isEqualTo("In response to: Test the Request-Response interaction model");
                })
                .verifyComplete();
    }
}

4. Вывод

Вы изучили основы прикладного протокола сокетов и изучили, как создать сервер, клиент и модульный тест для модели взаимодействия Запрос-ответ. В блоге next вы узнаете, как создать сервер, клиент и модульный тест для оставшихся трех моделей связи.

Оригинал: “https://dev.to/mydeveloperplanet/getting-started-with-rsocket-part-1-442d”