[英]Spring integration on reconnect TCP send handshake
我正在嘗試使用 TcpSendingMessageHandler 上的 ClientMode 來自動重新連接連接。 此連接需要保持打開狀態,因此實現重新連接 function 很重要。
private MessageChannel createNewSubflow(Message<?> message) {
String host = (String) message.getHeaders().get("host");
Integer port = (Integer) message.getHeaders().get("port");
Assert.state(host != null && port != null, "host and/or port header missing");
String hostPort = host + port;
TcpNetClientConnectionFactory cf = new TcpNetClientConnectionFactory(host, port);
TcpReceivingChannelAdapter messageHandler = new TcpReceivingChannelAdapter();
cf.setLeaveOpen(true);
TcpConnectionInterceptorFactoryChain fc = new TcpConnectionInterceptorFactoryChain();
HelloWorldInterceptorFactory factory = new HelloWorldInterceptorFactory();
fc.setInterceptors(new TcpConnectionInterceptorFactory[] { factory} );
cf.setInterceptorFactoryChain(fc);
cf.setDeserializer(new CustomSerializerDeserializer());
messageHandler.setErrorChannel(errorChannel);
messageHandler.setConnectionFactory(cf);
messageHandler.setOutputChannel(outputChannel);
TcpSendingMessageHandler handler = new TcpSendingMessageHandler();
handler.setConnectionFactory(cf);
handler.setClientMode(true);
handler.setRetryInterval(5000);
IntegrationFlow flow = f -> f.handle(handler);
IntegrationFlowContext.IntegrationFlowRegistration flowRegistration =
this.flowContext
.registration(flow)
.addBean(cf)
.id(hostPort + ".flow")
.register();
MessageChannel inputChannel = flowRegistration.getInputChannel();
this.subFlows.put(hostPort, inputChannel);
return inputChannel;
}
不幸的是,我需要在打開連接套接字后發送握手。
我試圖添加這篇文章中描述的消息攔截器( 攔截器)但是當連接套接字恢復時它不會進入攔截器。
恢復套接字時收到此警告:
HelloWorldInterceptor : No publisher available to publish TcpConnectionOpenEvent [source=HelloWorldInterceptor
警告來自攔截器,因為工廠未正確初始化。
您還需要為攔截器工廠添加.addBean()
。
編輯
正如評論中提到的,攔截器的替代方法就是使用事件監聽器。
我剛剛對此進行了測試,沒有發現任何問題:
@SpringBootApplication
public class So65899947Application {
public static void main(String[] args) {
SpringApplication.run(So65899947Application.class, args);
}
@Bean
public IntegrationFlow flow() {
return f -> f.handle(Tcp.outboundAdapter(Tcp.netClient("localhost", 1234))
.clientMode(true)
.retryInterval(5000));
}
}
@Component
class InitialSender {
private final IntegrationFlow flow;
InitialSender(IntegrationFlow flow) {
this.flow = flow;
}
@EventListener
public void opened(TcpConnectionOpenEvent event) {
this.flow.getInputChannel().send(new GenericMessage<>("Hello there",
Collections.singletonMap(IpHeaders.CONNECTION_ID, event.getConnectionId())));
}
}
$ nc -l 1234
Hello there
^C
$ nc -l 1234
Hello there
^C
$ nc -l 1234
Hello there
^C
$ nc -l 1234
Hello there
^C
$ nc -l 1234
Hello there
^C
編輯2
當我將其更改為使用網關時,我的結果相同......
@SpringBootApplication
@IntegrationComponentScan
public class So65899947Application {
public static void main(String[] args) {
SpringApplication.run(So65899947Application.class, args);
}
@Bean
public IntegrationFlow flow() {
return f -> f.handle(Tcp.outboundAdapter(Tcp.netClient("localhost", 1234))
.clientMode(true)
.retryInterval(5000));
}
}
@MessagingGateway(defaultRequestChannel = "flow.input")
interface Gate {
void handShake(@Payload String message, @Header(IpHeaders.CONNECTION_ID) String conn);
}
@Component
class InitialSender {
private final Gate gate;
InitialSender(Gate gate) {
this.gate = gate;
}
@EventListener
public void opened(TcpConnectionOpenEvent event) {
this.gate.handShake("Hello there", event.getConnectionId());
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.