问题
I have read and followed the example in http://docs.spring.io/spring-integration/reference/html/ip.html#ip-correlation
I have a spring-integration server
<int-ip:tcp-connection-factory
id="socketserver"
type="server"
port="30124"
using-nio="true"
mapper="mapper"
deserializer="jsonSerializer"
serializer="jsonSerializer"
single-use="false"/>
with this mapper from above link:
<bean id="mapper"
class="org.springframework.integration.ip.tcp.connection.MessageConvertingTcpMessageMapper">
<constructor-arg name="messageConverter">
<bean class="org.springframework.integration.support.converter.MapMessageConverter">
<property name="headerNames">
<list>
<value>correlationId</value>
<value>sequenceNumber</value>
<value>sequenceSize</value>
</list>
</property>
</bean>
</constructor-arg>
with inbound and outbound adapter
<int-ip:tcp-inbound-channel-adapter id="inboundServer"
channel="inputChannel"
connection-factory="socketserver"/>
<int-ip:tcp-outbound-channel-adapter id="outboundServer"
channel="outputChannel"
connection-factory="socketserver"/>
<int:channel id="inputChannel"/>
<int:channel id="outputChannel"/>
<int:service-activator input-channel="inputChannel"
output-channel="outputChannel"
ref="echoService"
method="test"/>
<bean id="echoService" class="com.example.HelloReply" />
I'm sending Messages to a connected client with
Map<String, Object> headers = new HashMap<String, Object>();
Map msgMap = new HashMap();
msgMap.put("message", "test");
headers.put(IpHeaders.CONNECTION_ID, <the connection id>);
headers.put("correlationId", "boo");
headers.put("sequenceNumber", 100);
headers.put("sequenceSize", 5);
Message<Map> msg = new GenericMessage<Map>(msgMap, headers);
MessagingTemplate template = new MessagingTemplate();
Message reply = template.sendAndReceive(outputChannel, msg);
The last line blocks forever, because I can't figure out how to reply to that message properly from my legacy client (telnet).
The sent message is:
{"headers":{"sequenceNumber":101,"sequenceSize":5,"correlationId":"boo"},"payload":{"message":"test"}}
I thought that it would be the correlationId and the same sequenceNumber to match so I tried to response from client to the server with
{"headers":{"sequenceNumber":101,"sequenceSize":5,"correlationId":"boo"},"payload":{"result":"OK"}}
But it is interpreted as a new inbound message, not recognized as an answer for the initial send-message.
So what does sendAndReceive expect and is there some documentation/specification for that special usecase (sendAndReceive communication with non-spring clients).
回答1:
What do you mean by
channels "sendAndReceive"
?
Which APIs are you using? Unless you use a gateway, you are responsible for reply correlation.
The TCP Client-Server Multiplex Sample shows one technique (an aggregator) to correlate replies when not using a gateway.
Show your complete configuration (edit the question, don't add in a comment; it doesn't render well).
EDIT:
The framework can't do the correlation for you automatically (with template.sendAndReceive()
). It doesn't know anything about your custom headers and, in any case, there's no way to get a reference to the automatic reply queue in the template for this message.
You have to write your own code to do the correlation.
template.send(...);
// wait for incoming message with the same correlation id
For example, you could use, say, a Map<String, BlockingQueue>
, keyed by the correlation id and poll
for the response.
Invoke another method in the class via a <service-activator/>
and put
the reply into the BlockingQueue
for the correlation id. You could also use a map of QueueChannel
s.
This use case (block the thread waiting for some asynchronous event) has come up several times and we are considering adding a component to make things easier.
来源:https://stackoverflow.com/questions/30841348/how-should-a-message-look-like-to-be-a-response