java - Spring Boot TCP 客户端

标签 java spring-boot tcp spring-integration

我正在寻找一个通过 spring boot 连接 TCP 的示例,无需 xml(spring-integration)。

我从 How to create a Tcp Connection in spring boot to accept connections? 得到了以下代码片段网址。

在这个例子中,仅仅需要main方法就足以连接tcp。为什么其他bean和变压器在这里声明?

有错吗?我不想使用简单的 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);
    }

}

最佳答案

该应用程序既是客户端又是服务器。

这个问题具体是关于如何使用 Spring Integration 编写服务器端(接受连接)。

main()方法只是一个连接到服务器端的测试。它使用标准 Java 套接字 API;它也可以被编写为在客户端使用 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

关于java - Spring Boot TCP 客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54057281/

相关文章:

tcp - 套接字未在 lsof 中列出但在 netstat 中列出

linux - RELP 是否存在于 RSYSLOG 协议(protocol)之外?

java - 混淆 CSV

java - 问 : Updating a ProgressBar with real results (includes code)

java - ViewPager、FragmentStatePagerAdapter、ListFragment单独列出每个Fragment的数据

java - Spring Boot 将事务(和数据库连接)传播到 @Async 方法

spring-boot - SAML SSO keystore 证书的重要性

java - 避免在JDK升级后实现新的接口(interface)方法

java - 运行 jar 时无法确定数据库类型 NONE 的嵌入式数据库驱动程序类

c - 监听 TCP 端口时没有任何反应