22

I have been through this and understood that I need to create a TcpReceivingChannelAdapter to accept connections. But I don't know how to proceed with that.

Could someone guide me over this?

Dmytro Chasovskyi
  • 3,209
  • 4
  • 40
  • 82
amitection
  • 2,696
  • 8
  • 25
  • 46

1 Answers1

18

See the tcp-client-server sample for some pointers using XML configuration.

For Java configuration; here's a simple Spring Boot app...

package com.example;

import java.net.Socket;

import javax.net.SocketFactory;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.annotation.Transformer;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.ip.tcp.TcpReceivingChannelAdapter;
import org.springframework.integration.ip.tcp.connection.AbstractServerConnectionFactory;
import org.springframework.integration.ip.tcp.connection.TcpNetServerConnectionFactory;
import org.springframework.integration.transformer.ObjectToStringTransformer;
import org.springframework.messaging.MessageChannel;

@SpringBootApplication
public class So39290834Application {

    public static void main(String[] args) throws Exception {
        ConfigurableApplicationContext context = SpringApplication.run(So39290834Application.class, args);
        Socket socket = SocketFactory.getDefault().createSocket("localhost", 9999);
        socket.getOutputStream().write("foo\r\n".getBytes());
        socket.close();
        Thread.sleep(1000);
        context.close();
    }

    @Bean
    public TcpNetServerConnectionFactory cf() {
        return new TcpNetServerConnectionFactory(9999);
    }

    @Bean
    public TcpReceivingChannelAdapter inbound(AbstractServerConnectionFactory cf) {
        TcpReceivingChannelAdapter adapter = new TcpReceivingChannelAdapter();
        adapter.setConnectionFactory(cf);
        adapter.setOutputChannel(tcpIn());
        return adapter;
    }

    @Bean
    public MessageChannel tcpIn() {
        return new DirectChannel();
    }

    @Transformer(inputChannel = "tcpIn", outputChannel = "serviceChannel")
    @Bean
    public ObjectToStringTransformer transformer() {
        return new ObjectToStringTransformer();
    }

    @ServiceActivator(inputChannel = "serviceChannel")
    public void service(String in) {
        System.out.println(in);
    }

}
Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • 1
    Perfect! Could you point me as to where I can find documentation on Java based configuration in Spring boot? – amitection Sep 05 '16 at 05:42
  • 2
    I am not sure what you mean. If you mean java configuration of Spring Integration components in boot, we have some examples in the reference manual, but not yet for all modules. We do have a [section](http://docs.spring.io/spring-integration/reference/html/overview.html#programming-tips) to guide you and point you where to find information about the underlying components for most elements. – Gary Russell Sep 05 '16 at 14:00
  • You can also use traditional Spring Integration XML configuration with Spring Boot - simply add `@ImportResource` to a configuration class. – Gary Russell Sep 07 '16 at 14:32
  • 2
    gradle dependencies :compile 'org.springframework.integration:spring-integration-core:4.3.11.RELEASE' compile 'org.springframework.integration:spring-integration-ip:4.3.11.RELEASE' – Kamil Nękanowicz Jul 31 '17 at 09:36
  • 1
    Your question is not clear. In any case you must not ask a new question in a comment; open a new question with much more detail, explaining exactly what you are having problems with. – Gary Russell Jul 31 '17 at 13:08
  • If you commented out other than main method also it will work. What is the point of creating those beans unnecessarily? – Shakthi Jan 05 '19 at 22:55
  • 1
    What are you talking about? Which beans? Define "will work". The connection factory allows the client to connect; the other beans are Spring Integration infrastructure, culminating in the service which simply prints a String. Don't comment on an old answer unless you have something meaningful to add. If there is something you don't understand, ask a new question with appropriate tags, and show **exactly** what you mean. – Gary Russell Jan 05 '19 at 23:42
  • 1
    This question was about the server side using Spring Integration; the `main` method is a simple client to test the server. – Gary Russell Jan 06 '19 at 01:02
  • I commented out the context.close() method and try testing with `nc localhost 9999 Hello Server`, I don't see the console logs on the Spring side. – blee908 Mar 06 '20 at 00:27
  • Don't ask a new question in a comment on a year+ old answer; ask a new question showing your code and configuration. – Gary Russell Mar 06 '20 at 00:54
  • It's literally the same tcp server code. Why do we need to ask a new question on the exact same server code? – blee908 Mar 08 '20 at 05:38
  • If it was the same question would be the same answer; your question is about using Spring Integration with `nc`. The admins here don't like long commentary; this answer already has a lot of comments. `nc localhost 9999 Hello` does nothing. `nc localhost 9999` will open a connection; entering `Hello Server` on the next line will send it; but followed by a linefeed. The default server factory looks for CRLF to delimit messages; use `telnet` for the client instead, or configure the factory to expect just a linefeed `factory.setDeserializer(new ByteArrayLfSerializer())`. – Gary Russell Mar 08 '20 at 14:49