TCP-клиент Spring Boot

Ищу пример подключения TCP через загрузку sping без xml (Spring-integration).

Я получил следующий фрагмент из URL-адреса Как создать соединение TCP при весенней загрузке для приема соединений?.

в этом примере достаточно только основного метода для подключения tcp. почему здесь заявлены другие бобы и преобразователь?

Это неправильно? Вместо того, чтобы использовать простой клиент сокета Java для принятия ответа, я хотел бы интегрироваться со Spring. Но подходящих примеров с использованием Java DSL нет.

Не могли бы вы помочь?

package com.example;

import java.net.Socket;

import javax.net.SocketFactory;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.annotation.Transformer;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.ip.tcp.TcpReceivingChannelAdapter;
import org.springframework.integration.ip.tcp.connection.AbstractServerConnectionFactory;
import org.springframework.integration.ip.tcp.connection.TcpNetServerConnectionFactory;
import org.springframework.integration.transformer.ObjectToStringTransformer;
import org.springframework.messaging.MessageChannel;

@SpringBootApplication
public class So39290834Application {

    public static void main(String[] args) throws Exception {
        ConfigurableApplicationContext context = SpringApplication.run(So39290834Application.class, args);
        Socket socket = SocketFactory.getDefault().createSocket("localhost", 9999);
        socket.getOutputStream().write("foo\r\n".getBytes());
        socket.close();
        Thread.sleep(1000);
        context.close();
    }

    @Bean
    public TcpNetServerConnectionFactory cf() {
        return new TcpNetServerConnectionFactory(9999);
    }

    @Bean
    public TcpReceivingChannelAdapter inbound(AbstractServerConnectionFactory cf) {
        TcpReceivingChannelAdapter adapter = new TcpReceivingChannelAdapter();
        adapter.setConnectionFactory(cf);
        adapter.setOutputChannel(tcpIn());
        return adapter;
    }

    @Bean
    public MessageChannel tcpIn() {
        return new DirectChannel();
    }

    @Transformer(inputChannel = "tcpIn", outputChannel = "serviceChannel")
    @Bean
    public ObjectToStringTransformer transformer() {
        return new ObjectToStringTransformer();
    }

    @ServiceActivator(inputChannel = "serviceChannel")
    public void service(String in) {
        System.out.println(in);
    }

}
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
0
7 511
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это приложение является одновременно клиентом и сервером.

Этот вопрос был конкретно о том, как написать на стороне сервера (принять соединение), используя Spring Integration.

Метод main() - это просто тест, который подключается к стороне сервера. Он использует стандартные API-интерфейсы сокетов Java; он также мог быть написан для использования компонентов Spring Integration на стороне клиента.

Кстати, вам не нужно использовать XML для написания приложения Spring Integration, вы можете настроить его с помощью аннотаций или использовать Java DSL. Прочтите документацию.

РЕДАКТИРОВАТЬ

Пример клиент / сервер с использованием Java DSL

@SpringBootApplication
public class So54057281Application {

    public static void main(String[] args) {
        SpringApplication.run(So54057281Application.class, args);
    }

    @Bean
    public IntegrationFlow server() {
        return IntegrationFlows.from(Tcp.inboundGateway(
                    Tcp.netServer(1234)
                        .serializer(codec()) // default is CRLF
                        .deserializer(codec()))) // default is CRLF
                .transform(Transformers.objectToString()) // byte[] -> String
                .<String, String>transform(p -> p.toUpperCase())
                .get();
    }

    @Bean
    public IntegrationFlow client() {
        return IntegrationFlows.from(MyGateway.class)
                .handle(Tcp.outboundGateway(
                    Tcp.netClient("localhost", 1234)
                        .serializer(codec()) // default is CRLF
                        .deserializer(codec()))) // default is CRLF
                .transform(Transformers.objectToString()) // byte[] -> String
                .get();
    }

    @Bean
    public AbstractByteArraySerializer codec() {
        return TcpCodecs.lf();
    }

    @Bean
    @DependsOn("client")
    ApplicationRunner runner(MyGateway gateway) {
        return args -> {
            System.out.println(gateway.exchange("foo"));
            System.out.println(gateway.exchange("bar"));
        };
    }

    public interface MyGateway {

        String exchange(String out);

    }

}

результат

FOO
BAR

Не могли бы вы поделиться фрагментом сервера и клиента отдельно для TCP, используя весеннюю интеграцию? Также предложите мне, что лучше всего использовать службу TCP? Достаточно ли Socket или лучше выполнить весеннюю итерацию? У меня нет большого опыта весенней интеграции.

Shakthi 06.01.2019 10:19

Это твой выбор; вы можете самостоятельно выполнить кодирование низкоуровневых сокетов или использовать что-то вроде Spring Integration для обеспечения абстракции более высокого уровня. Это действительно зависит от того, какое именно общение вам нужно. Я добавил пример клиент / сервер Spring Integration с использованием Java DSL.

Gary Russell 06.01.2019 17:37

Рассел, приведенный выше фрагмент работает хорошо. Если я вызываю MyGateway из другой службы, например, @Autowired MyGateway gateway; переместив интерфейс в другой пакет, он не работает. Там написано Consider defining a bean of type MyGateway. Пожалуйста, предложите.

Shakthi 10.01.2019 21:53

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

Gary Russell 10.01.2019 22:00

приведенный выше код работает, только если я прокомментирую строки .serializer(codec()) и .deserializer(codec()). И это тоже: для одного API я получаю ответ, а для другого API я получаю ошибку, такую ​​как org.springframework.messaging.MessagingException: Exception while awaiting reply; nested exception is java.io.IOException: CRLF not found before max message length: 2048, это исключение. Что я должен делать?

Shakthi 11.01.2019 16:54

Я добавил codec(), чтобы показать, как изменить значение по умолчанию; если ваш сервер ожидает (и возвращает CRLF), используйте ByteArrayCrLfSerializer (по умолчанию). Вы можете увеличить максимальную длину сообщения с помощью setMaxMessageSize(...); размер должен быть достаточно большим для самого большого ожидаемого сообщения, при этом не тратя впустую память; по умолчанию - 2048 байт.

Gary Russell 11.01.2019 17:02

Он отлично работает, как только я увеличил setMaxMessageSize(...). Спасибо :)

Shakthi 11.01.2019 19:38

Другие вопросы по теме