I wonder if it is possible to create a UDP server with spring-integration framework that is able to accept requests and return responses.
For TCP there are TCP gateways which allow request/response processing but I don't see similar thing for UDP.
It is easy to setup UDP listener and receive packets but then I don't see how to return a response as I can only route it to a predefined output channel.
Also I don't see sender's IP and port as the transformer doesn't receive the DatagramPacket object but only the data.
Here is my configuration:
<int:channel id="ChannelIn" />
<ip:udp-inbound-channel-adapter id="ChannelReceiver"
channel="ChannelIn"
port="5555"
multicast="false"
check-length="false"
pool-size="10"
/>
<int:transformer
ref="datagramToPacketTransformer"
input-channel="ChannelIn"
output-channel="ChannelSA"
method="toPacket"/>
<int:channel id="ChannelSA" />
<int:service-activator id="ChannelActivator"
input-channel="ChannelSA"
ref="PacketHandler"
method="process"
/>
I have found n way to deal with UDP. Below is my configuration
<int-ip:udp-inbound-channel-adapter id="ChannelReceiver"
channel="serverBytes2StringChannel"
port="9000"
multicast="false"
check-length="false"
pool-size="10"
lookup-host="false"
/>
<int:transformer id="serverBytes2String"
input-channel="serverBytes2StringChannel"
output-channel="udpSA"
expression="new String(payload)"
/>
<int:service-activator input-channel="udpSA"
ref="deviceService"
method="udpMessage"/>
And deviceService
bean has this code:
public Message udpMessage(Message message) {
String response = "KO";
try {
response = process(message);
} catch (Throwable th) {
//do something
}
Message msg = MessageBuilder.withPayload(response.getBytes()).copyHeaders(message.getHeaders()).build();
sendReply(msg);
return null;
}
private void sendReply(Message message) {
try {
int port = (Integer) message.getHeaders().get("ip_port");
String ip = (String) message.getHeaders().get("ip_address");
InetAddress IPAddress = InetAddress.getByName(ip);
byte[] sentence = (byte[]) message.getPayload();
byte[] sendData = new byte[sentence.length];
byte[] receiveData = new byte[1024];
sendData = sentence;
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
DatagramSocket clientSocket = new DatagramSocket();
clientSocket.send(sendPacket);
clientSocket.close();
} catch (Exception ex) {
throw new RuntimeException("KO");
}
}
And this is working perfectly on my personal computer however when I deploy this code on Amazon AWS it is not working. I found that even though program is listening on UDP 9000 port, but no communication received at server side. This could be an issue with AWS setup though I have allowed all UDP port for that AWS instance.
Any hints on how to make this work on Amazon AWS?
I opened a new feature JIRA nearly two years ago
https://jira.springsource.org/browse/INT-1809
but it received no votes, or watchers, so I closed it.
Feel free to add a comment to it and we can re-open it.
The sender's ip is in the message header, but not his port...
message = MessageBuilder.withPayload(payload)
.setHeader(IpHeaders.HOSTNAME, hostName)
.setHeader(IpHeaders.IP_ADDRESS, hostAddress)
.build();
If you want to open a new JIRA for that, it's a small enough change to get into the 2.2. release that will come out shortly (but the gateways will not make 2.2).
https://jira.springsource.org/browse/INT
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With