簡體   English   中英

用於接收/處理/回復的 TCP 套接字服務器設置

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

這是一個新問題,是對這個舊問題和答案(特別是“不要評論舊答案,提出新問題”的評論)以及 GitHub 中的這些示例的跟進。

我知道答案和示例是最少工作的“瑣碎示例”,但我對“事情在 Spring 中如何工作”(或應該如何工作)知之甚少,無法理解如何將這些通用的、瑣碎的示例分解為單獨的服務器和客戶端適合我的目的。 我目前有一個可用的 Spring-Boot 守護進程應用程序,它是客戶端通過 TCP 套接字連接/調用(沒有任何“spring 集成”)遺留守護進程應用程序。 一切正常,在生產中運行。

但是現在我的任務是將遺留守護程序也遷移到 Spring Boot。 所以我只需要在服務器端配置和設置一個緩存/池化的 TCP 連接“套接字偵聽器”。 但是,現有(自包含)示例的“客戶端部分”讓我感到困惑。 在我的情況下,“客戶端”(現有的 Spring Boot 守護進程)不會改變並且是單獨服務器上的單獨應用程序,我只需要設置/配置套接字連接的“服務器端”( “legacy-daemon 剛剛遷移到 Spring Boot”守護程序)。

我已將此示例配置(完全)復制到我的舊版遷移項目中

@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 --- [主要] com.example.demo.So604435381Application:FOO

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM