Java 接收/处理/回复的TCP套接字服务器设置

Java 接收/处理/回复的TCP套接字服务器设置,java,spring-boot,spring-integration,tcpsocket,Java,Spring Boot,Spring Integration,Tcpsocket,这是一个新问题,是对旧问题和答案(特别是“不要对旧答案发表评论,问一个新问题”)以及GitHub中的示例的后续问题 我知道答案,示例是最小的工作“平凡示例”,但我对“事物在春天如何工作”(或应该如何工作)了解不够,无法理解如何将这些通用的平凡示例分解为适合我的目的的单独服务器和客户机。我目前有一个工作的Spring引导守护程序应用程序,它是通过TCP套接字连接客户端到/调用遗留守护程序应用程序(没有任何“Spring集成”)。所有这些都在生产中运行 但现在我的任务是将遗留守护程序迁移到Sprin

这是一个新问题,是对旧问题和答案(特别是“不要对旧答案发表评论,问一个新问题”)以及GitHub中的示例的后续问题

我知道答案,示例是最小的工作“平凡示例”,但我对“事物在春天如何工作”(或应该如何工作)了解不够,无法理解如何将这些通用的平凡示例分解为适合我的目的的单独服务器和客户机。我目前有一个工作的Spring引导守护程序应用程序,它是通过TCP套接字连接客户端到/调用遗留守护程序应用程序(没有任何“Spring集成”)。所有这些都在生产中运行

但现在我的任务是将遗留守护程序迁移到Spring Boot。因此,我只需要在服务器端配置和设置缓存/池TCP连接“套接字侦听器”。然而,现有(自包含的)示例的“客户机部分”让我感到困惑。在我的情况下,“客户端”(现有的Spring引导守护程序)不会改变,并且是一个独立服务器上的独立应用程序,我只需要设置/配置套接字连接的“服务器端”(新迁移到Spring引导的旧守护程序)守护程序

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

@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的示例:

@springboot应用程序
公共类SO60443538应用程序{
公共静态void main(字符串[]args){
SpringApplication.run(So60443538Application.class,args);
}
@豆子
公共集成流服务器(){
返回IntegrationFlows.from(Tcp.inboundGateway(Tcp.netServer(1234)))
.transform(Transformers.objectToString())//字节[]->String
.transform(p->p.toUpperCase())
.get();
}
}
@springboot应用程序
公共类SO604435381应用程序{
私有静态最终记录器LOG=LoggerFactory.getLogger(SO604435381应用程序.class);
公共静态void main(字符串[]args){
SpringApplication.run(So604435381Application.class,args);
}
@豆子
公共集成流客户端(){
返回IntegrationFlows.from(Gate.class)
.handle(Tcp.outboundGateway(Tcp.netClient(“localhost”,1234)))
.transform(Transformers.objectToString())
.get();
}
@豆子
@德彭森(“客户”)
公共应用程序运行程序(网关){
返回args->LOG.info(gateway.exchange(“foo”);
}
}
接口门{
字符串交换(字符串输入);
}
2020-02-28 09:14:04.158信息35974---[main]com.example.demo.so604435381应用程序:FOO


有很多理由离题。没有代码,太宽泛,请求非现场资源,…关于你,直到你停止应用程序才得到回复;这意味着客户端和服务器之间存在某种阻抗不匹配;听起来客户端代码只在套接字关闭时才将回复视为“完成”。在默认配置下,“完成”由消息末尾的
\r\n
发出信号;为了让服务器在发送回复后关闭套接字,请将服务器工厂上的
singleUse
属性设置为
true
。感谢您的快速回答。我整天忙于研究生产问题和/或准备发布,所以我还没有回到这个问题上来。但我会的,我希望我能理解你的答案,并将其转化为我的需要。。。