java - 用于接收/处理/回复的 TCP 套接字服务器设置

标签 java spring-boot spring-integration tcpsocket

这是继this之后的一个新问题较旧的问题和答案(特别是“不要评论旧答案,提出新问题”的评论),以及 these GitHub 中的示例。

我知道答案和示例是最小的工作“琐碎示例”,但我对“Spring 中的事物如何工作”(或应该工作)了解不够,无法理解如何将这些通用的、琐碎的示例分解为单独的服务器以及适合我的目的的客户。我目前有一个正在运行的 Spring-Boot 守护程序应用程序,它是通过 TCP 套接字连接对旧守护程序应用程序进行客户端/调用(没有任何“spring 集成”)的客户端。一切正常,正在生产中运行。

但现在我的任务是将遗留守护进程迁移到 Spring Boot。所以我只需要在服务器端配置和设置一个缓存/池化的 TCP 连接“套接字监听器”。然而,现有(自包含)示例的“客户端部分”让我感到困惑。就我而言,“客户端”(现有的 Spring Boot 守护进程)不会改变,并且是单独服务器上的单独应用程序,我只需要设置/配置套接字连接的“服务器端”( “遗留守护进程刚刚迁移到 Spring Boot”守护进程)。

我已复制 this example配置(准确地)到我的遗留迁移项目中

@EnableIntegration 
@IntegrationComponentScan 
@Configuration
public static class Config {

@Value(${some.port})
private int port;

@MessagingGateway(defaultRequestChannel="toTcp") 
public interface Gateway {

    String viaTcp(String in);

}

@Bean
@ServiceActivator(inputChannel="toTcp") 
public MessageHandler tcpOutGate(AbstractClientConnectionFactory connectionFactory) {
    TcpOutboundGateway gate = new TcpOutboundGateway();
    gate.setConnectionFactory(connectionFactory);
    gate.setOutputChannelName("resultToString");
    return gate;
}

@Bean 
public TcpInboundGateway tcpInGate(AbstractServerConnectionFactory connectionFactory)  {
    TcpInboundGateway inGate = new TcpInboundGateway();
    inGate.setConnectionFactory(connectionFactory);
    inGate.setRequestChannel(fromTcp());
    return inGate;
}

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

@MessageEndpoint
public static class Echo { 

    @Transformer(inputChannel="fromTcp", outputChannel="toEcho")
    public String convert(byte[] bytes) {
        return new String(bytes);
    }

    @ServiceActivator(inputChannel="toEcho")
    public String upCase(String in) {
        return in.toUpperCase();
    }

    @Transformer(inputChannel="resultToString")
    public String convertResult(byte[] bytes) {
        return new String(bytes);
    }

}

@Bean
public AbstractClientConnectionFactory clientCF() { 
    return new TcpNetClientConnectionFactory("localhost", this.port);
}

@Bean
public AbstractServerConnectionFactory serverCF() { 
    return new TcpNetServerConnectionFactory(this.port);
}

}

...项目将在“localhost”上启动并在端口 10000 上“监听”。但是,当我从另一个本地应用程序连接到套接字并发送一些测试文本时,没有任何返回,直到我关闭套接字监听应用程序。只有在套接字监听应用程序开始关闭后,响应(正确的“大写”结果)才会返回到发送应用程序。

如何让“监听者”正常返回响应给“发送者”,而不需要先关闭监听者的服务器?

或者有人可以提供一个仅显示服务器端(希望基于注释)设置的示例吗? (或者编辑示例,使服务器和客户端明显解耦?)

最佳答案

示例通常包含客户端和服务器,因为这样更容易。但将客户端和服务器端分开并没有什么特别的。下面是一个使用 Java DSL 的示例:

@SpringBootApplication
public class So60443538Application {

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

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

}
@SpringBootApplication
public class So604435381Application {

    private static final Logger LOG = LoggerFactory.getLogger(So604435381Application.class);

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

    @Bean
    public IntegrationFlow client() {
        return IntegrationFlows.from(Gate.class)
                .handle(Tcp.outboundGateway(Tcp.netClient("localhost", 1234)))
                .transform(Transformers.objectToString())
                .get();
    }

    @Bean
    @DependsOn("client")
    public ApplicationRunner runner(Gate gateway) {
        return args -> LOG.info(gateway.exchange("foo"));
    }

}

interface Gate {

    String exchange(String in);

}

2020-02-28 09:14:04.158 INFO 35974 --- [ main] com.example.demo.So604435381Application : FOO

关于java - 用于接收/处理/回复的 TCP 套接字服务器设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60443538/

相关文章:

java - Hibernate JCache 5.4.3.Final 不适用于 JCache 5.4.2.Final 配置

java - Spring security 在并发环境中得到错误的主体

java - AggregatingMessageHandler 的手动 ACK

java - Spring Integration Aggregator - 丢失消息

java - 检查字节数组列表是否包含新的字节数组

java - 如何使用单选按钮在警报对话框中添加“确定”和“取消”按钮

java - 没有 UI 的 Android 后台服务没有应答

java - 允许 Javascript 和 CSS 但不允许 XSS

java - 无法在自定义 Spring Boot 启动器中使用 WebSecurityConfigurerAdapter

java - spring-integration-aws java配置