Hot questions for Using Transmission Control Protocol in tcpserver

Question:

I have already created a simple tcp server with spring integration which keeps a connection alive and responses to each request during the connection.

In that requestMethod, I'm also able to read the MessageHeder to get the connectionId.

Now I want to send messages from the server to the client.

As far as i understood the documentation i need to put the connectionid in the MessageHeader and then send the message. But I can't figure out how to do the latter one. I have the Message ready but how do i send/push it out?

Here is my xml-configuration:

<bean id="lfSerializer" class="org.springframework.integration.ip.tcp.serializer.ByteArrayLfSerializer"/>

<int-ip:tcp-connection-factory
    id="socketserver"
    type="server"
    port="30124"
    using-nio="true"
    deserializer="lfSerializer"
    serializer="lfSerializer"
    single-use="false"/>

<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:interceptors>
        <int:wire-tap channel="logger"/>
    </int:interceptors>
</int:channel>

<int:channel id="outputChannel">
    <int:interceptors>
        <int:wire-tap channel="logger"/>
    </int:interceptors>
</int:channel>

<int:logging-channel-adapter id="logger" level="DEBUG" log-full-message="true"/>

<int:service-activator input-channel="inputChannel"
                   output-channel="outputChannel"
                   ref="echoService"
                   method="test"/>

<bean id="echoService"
    class="com.examples.EchoService" />

I also tried to create a bean and another serviceactivator for output, then autowired that bean and called it's "send" method, but I don't know what to implement in that send-method to send out a message.


Answer:

If it's a simple request/response scenario use an inbound gateway instead of channel adapters and the framework will take care of the correlation for you. This is used in the sample app. Simply have your POJO method return the reply payload.

If you want to send arbitrary messages to the client (i.e. NOT request/reply but, say, in, out, out, in, out, out, out etc) then, yes, you need to build the messages yourself, inserting the ip_connectionId header.

To send them, there are several options:

Inject outputChannel into your code

@Autowired
private MessageChannel outputChannel;

Use a MessagingTemplate to send to the channel (or simply call its send(Message<?> message) method directly).

Or

Use a MessagingGateway with a void return method and inject the gateway into your code.

EDIT:

Note, that if you want to start sending messages before receiving anything, you can obtain the connection id via the connection opened event.

Question:

I have a TCP server application in Java. When client connects, it tries to read packet from the connection. However, it does read even if the client didn't send anything. What I get is aray of bytes initialized by 0. I expected the socket to wait, and eventually timeout, until some data comes. However, instead it acts strange like this. What's wrong with this and how I can fix it? Here's how I read from the socket:

byte bytes[] = new byte[25];
socket.getInputStream().read(commandBytes);

Answer:

.read returns the number of bytes read. You need to check it before using the buffer. In your case, it is, probably, -1, meaning, that the client has not sent any data