问题
Hello I am new on spring integration
I checked examples for Spring Integration dynamic routing. Finally ı found it in here
Dynamic TCP Client
In here there were lines
@Component
@MessagingGateway(defaultRequestChannel = "toTcp.input")
public interface TcpClientGateway {
byte[] send(String data, @Header("host") String host, @Header("port") int port);
}
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);
TcpSendingMessageHandler handler = new TcpSendingMessageHandler();
handler.setConnectionFactory(cf);
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;
}
but i changed it with
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);
cf.setLeaveOpen(true);
//cf.setSingleUse(true);
ByteArrayCrLfSerializer byteArrayCrLfSerializer =new ByteArrayCrLfSerializer();
byteArrayCrLfSerializer.setMaxMessageSize(1048576);
cf.setSerializer(byteArrayCrLfSerializer);
cf.setDeserializer(byteArrayCrLfSerializer);
TcpOutboundGateway tcpOutboundGateway = new TcpOutboundGateway();
tcpOutboundGateway.setConnectionFactory(cf);
IntegrationFlow flow = f -> f.handle(tcpOutboundGateway);
IntegrationFlowContext.IntegrationFlowRegistration flowRegistration =
this.flowContext.registration(flow)
.addBean(cf)
.id(hostPort + ".flow")
.register();
MessageChannel inputChannel = flowRegistration.getInputChannel();
this.subFlows.put(hostPort, inputChannel);
return inputChannel;
}
to work with request/response architecture. It really works fine because it provides dynamic routing with out creating tcp clients by hand.
At this point i need some help to improve my scenario. My scenario is like that;
Client sends a message to Server and receive that message's response from server but then server needs to send arbitrary messages to that client (it is like GPS location update information). When server starts to send these messages to client generates error messages like below
ERROR 54816 --- [pool-2-thread-1] o.s.i.ip.tcp.TcpOutboundGateway : Cannot correlate response - no pending reply for ::58628:62fd67b6-af2d-42f1-9c4d-d232fbe9c8ca
I checked spring integration document and noticed that Gateways is working only with request/response so i learned that i should use adapters but i do not know how should i use adapters with dynamic tcp client.
here ı found similar topics and some responses but could not reach my goal or found example to combine solutions.
Spring Integration TCP Spring integration TCP server push to client
回答1:
You just need to register two flows; one for input; one for output - the problem is correlating the response for the reply, and routing the arbitrary messages to some place other than the gateway.
I updated the sample for this use case on this branch.
You can see the changes in the last commit on that branch; most of the changes were to simulate your server side.
On the client side, we simply register two flows and use a @ServiceActivator
method to get the inbound messages; you can identify which server they come from via the connection id.
来源:https://stackoverflow.com/questions/62702192/spring-integration-gateway-vs-adapters