Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UDP server with spring-integration

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"
/>
like image 947
user1703531 Avatar asked Nov 04 '22 15:11

user1703531


2 Answers

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?

like image 72
Rajesh Gheware Avatar answered Nov 14 '22 23:11

Rajesh Gheware


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

like image 34
Gary Russell Avatar answered Nov 15 '22 01:11

Gary Russell