Spring Integration tcp client multiple connections

假如想象 提交于 2019-11-29 11:54:14

It depends on what constitutes a "session" - if all the requests from a session on the client side all run on a single thread, you could write a simple wrapper for the connection factory that stores the connection in a ThreadLocal. You would need some mechanism to call the factory wrapper after the last request to close the connection and remove it from the ThreadLocal.

If the requests for a session can occur on multiple threads, it would be a bit more complicated but you could still do it with a ThreadLocal that maps to a connection instance.

EDIT

Here's an example...

@SpringBootApplication
public class So40507731Application {

    public static void main(String[] args) throws Exception {
        ConfigurableApplicationContext context = SpringApplication.run(So40507731Application.class, args);
        MessageChannel channel = context.getBean("clientFlow.input", MessageChannel.class);
        MessagingTemplate template = new MessagingTemplate(channel);
        ThreadAffinityClientConnectionFactory affinityCF = context.getBean(ThreadAffinityClientConnectionFactory.class);
        ExecutorService exec = Executors.newCachedThreadPool();
        CountDownLatch latch = new CountDownLatch(2);
        exec.execute(() -> {
            String result = new String(template.convertSendAndReceive("foo", byte[].class));
            System.out.println(Thread.currentThread().getName() + " " + result);
            result = new String(template.convertSendAndReceive("foo", byte[].class));
            System.out.println(Thread.currentThread().getName() + " " + result);
            affinityCF.release();
            latch.countDown();
        });
        exec.execute(() -> {
            String result = new String(template.convertSendAndReceive("foo", byte[].class));
            System.out.println(Thread.currentThread().getName() + " " + result);
            result = new String(template.convertSendAndReceive("foo", byte[].class));
            System.out.println(Thread.currentThread().getName() + " " + result);
            affinityCF.release();
            latch.countDown();
        });
        latch.await(10, TimeUnit.SECONDS);
        context.close();
        exec.shutdownNow();
    }

    @Bean
    public TcpNetClientConnectionFactory delegateCF() {
        TcpNetClientConnectionFactory clientCF = new TcpNetClientConnectionFactory("localhost", 1234);
        clientCF.setSingleUse(true); // so each thread gets his own connection
        return clientCF;
    }

    @Bean
    public ThreadAffinityClientConnectionFactory affinityCF() {
        return new ThreadAffinityClientConnectionFactory(delegateCF());
    }

    @Bean
    public TcpOutboundGateway outGate() {
        TcpOutboundGateway outGate = new TcpOutboundGateway();
        outGate.setConnectionFactory(affinityCF());
        return outGate;
    }

    @Bean
    public IntegrationFlow clientFlow() {
        return f -> f.handle(outGate());
    }

    @Bean
    public TcpNetServerConnectionFactory serverCF() {
        return new TcpNetServerConnectionFactory(1234);
    }

    @Bean
    public TcpInboundGateway inGate() {
        TcpInboundGateway inGate = new TcpInboundGateway();
        inGate.setConnectionFactory(serverCF());
        return inGate;
    }

    @Bean
    public IntegrationFlow serverFlow() {
        return IntegrationFlows.from(inGate())
                .transform(Transformers.objectToString())
                .transform("headers['ip_connectionId'] + ' ' + payload")
                .get();
    }

    public static class ThreadAffinityClientConnectionFactory extends AbstractClientConnectionFactory
            implements TcpListener {

        private final AbstractClientConnectionFactory delegate;

        private final ThreadLocal<TcpConnectionSupport> connection = new ThreadLocal<>();

        public ThreadAffinityClientConnectionFactory(AbstractClientConnectionFactory delegate) {
            super("", 0);
            delegate.registerListener(this);
            this.delegate = delegate;
        }

        @Override
        protected TcpConnectionSupport obtainConnection() throws Exception {
            TcpConnectionSupport tcpConnection = this.connection.get();
            if (tcpConnection == null || !tcpConnection.isOpen()) {
                tcpConnection = this.delegate.getConnection();
                this.connection.set(tcpConnection);
            }
            return tcpConnection;
        }

        public void release() {
            TcpConnectionSupport connection = this.connection.get();
            if (connection != null) {
                connection.close();
                this.connection.remove();
            }
        }

        @Override
        public void start() {
            this.delegate.start();
            setActive(true);
            super.start();
        }

        @Override
        public void stop() {
            this.delegate.stop();
            setActive(false);
            super.stop();
        }

        @Override
        public boolean onMessage(Message<?> message) {
            return getListener().onMessage(message);
        }

    }

}

Result:

pool-2-thread-2 localhost:64559:1234:3d898822-ea91-421d-97f2-5f9620b9d369 foo
pool-2-thread-1 localhost:64560:1234:227f8a9f-1461-41bf-943c-68a56f708b0c foo
pool-2-thread-2 localhost:64559:1234:3d898822-ea91-421d-97f2-5f9620b9d369 foo
pool-2-thread-1 localhost:64560:1234:227f8a9f-1461-41bf-943c-68a56f708b0c foo
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!