简体   繁体   English

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

[英]TCP Socket Server setup for receive/process/reply

This is a new question following up on this older question and answer (specifically the comment that says "don't comment on old answers, ask a new question"), as well as these examples in GitHub.这是一个新问题,是对这个旧问题和答案(特别是“不要评论旧答案,提出新问题”的评论)以及 GitHub 中的这些示例的跟进。

I know the answer and examples are minimal working "trivial examples", but I don't know enough about how "things work in Spring" (or should work) to understand how to decompose those generic, trivial examples into separate servers and clients that suit my purpose.我知道答案和示例是最少工作的“琐碎示例”,但我对“事情在 Spring 中如何工作”(或应该如何工作)知之甚少,无法理解如何将这些通用的、琐碎的示例分解为单独的服务器和客户端适合我的目的。 I currently have a working Spring-Boot daemon application that is client to / calls on (without any "spring integration") a legacy daemon application over a TCP Socket connection.我目前有一个可用的 Spring-Boot 守护进程应用程序,它是客户端通过 TCP 套接字连接/调用(没有任何“spring 集成”)遗留守护进程应用程序。 It's all working, running in production.一切正常,在生产中运行。

But now I am tasked with migrating the legacy daemon to Spring Boot too.但是现在我的任务是将遗留守护程序也迁移到 Spring Boot。 So I only need to configure and set up a cached/pooled TCP connection "socket listener" on the server-side.所以我只需要在服务器端配置和设置一个缓存/池化的 TCP 连接“套接字侦听器”。 However, the "client parts" of the existing (self contained) examples confuse me.但是,现有(自包含)示例的“客户端部分”让我感到困惑。 In my case the "client side" (the existing Spring Boot daemon) is not going to change and is a separate app on a separate server, I only need to set up / configure the "server-side" of the socket connection (the "legacy-daemon freshly migrated to Spring Boot" daemon).在我的情况下,“客户端”(现有的 Spring Boot 守护进程)不会改变并且是单独服务器上的单独应用程序,我只需要设置/配置套接字连接的“服务器端”( “legacy-daemon 刚刚迁移到 Spring Boot”守护程序)。

I've copied this example configuration (exactly) into my legacy-migration project我已将此示例配置(完全)复制到我的旧版迁移项目中

@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);
}

}

...and the project will start on 'localhost' and "listen" on port 10000. But, when I connect to the socket from another local app and send some test text, nothing returns until I shut down the socket listening app. ...并且项目将在“localhost”上启动并在端口 10000 上“监听”。但是,当我从另一个本地应用程序连接到套接字并发送一些测试文本时,在我关闭套接字监听应用程序之前没有任何返回。 Only after the socket listening app starts shutting down does a response (the correct 'uppercased' result) go back to the sending app.只有在套接字侦听应用程序开始关闭后,响应(正确的“大写”结果)才会返回到发送应用程序。

How do I get the "listener" to return a response to the "sender" normally, without shutting down the listener's server first?如何让“侦听器”正常向“发件人”返回响应,而无需先关闭侦听器的服务器?

Or can someone please provide an example that ONLY shows the server-side (hopefully annotation based) setup?或者有人可以提供一个仅显示服务器端(希望基于注释)设置的示例吗? (Or edit the example so the server and client are clearly decoupled?) (或者编辑示例以便服务器和客户端明显分离?)

Samples usually contain both the client and server because it's easier that way.示例通常包含客户端和服务器,因为这样更容易。 But there is nothing special about breaking apart the client and server sides.但是将客户端和服务器端分开并没有什么特别之处。 Here's an example using the Java DSL:下面是一个使用 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 2020-02-28 09:14:04.158 INFO 35974 --- [主要] com.example.demo.So604435381Application:FOO

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM