Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Java注释设置Spring集成协作通道适配器?_Java_Spring Boot_Tcp_Spring Integration_Multiplexing - Fatal编程技术网

如何使用Java注释设置Spring集成协作通道适配器?

如何使用Java注释设置Spring集成协作通道适配器?,java,spring-boot,tcp,spring-integration,multiplexing,Java,Spring Boot,Tcp,Spring Integration,Multiplexing,我看过其他与我的问题相关的帖子,但没有一个答案能帮助我解决问题 我在这里试着效仿这个例子: 我有一个接受请求的SpringRESTAPI,这些请求被转换成XML,然后我将它们发送给另一个接受TCP请求的应用程序 使用TcpOutboundGateway和TcpInboundGateway工作得很好,但速度很慢,所以我想通过协作通道适配器和多路复用来加快速度 根据我的理解,这个想法是通过网关发送一个请求,该请求被桥接到聚合器,该请求也被TcpSendingMessageHandler发送到另一个应

我看过其他与我的问题相关的帖子,但没有一个答案能帮助我解决问题

我在这里试着效仿这个例子:

我有一个接受请求的SpringRESTAPI,这些请求被转换成XML,然后我将它们发送给另一个接受TCP请求的应用程序

使用TcpOutboundGateway和TcpInboundGateway工作得很好,但速度很慢,所以我想通过协作通道适配器和多路复用来加快速度

根据我的理解,这个想法是通过网关发送一个请求,该请求被桥接到聚合器,该请求也被TcpSendingMessageHandler发送到另一个应用程序的tcp服务器。然后TCPrevivingChannelAdapter侦听响应,这些响应被发送到聚合器,在聚合器中它们与其请求(CORRELATION_ID头的bc)关联,然后发送到转换通道,转换通道将字节转换为字符串

显然,我的理解是错误的,因为我看不到响应是如何返回到网关的,而且它不起作用

我可以看到套接字被打开,但它在消息发送后立即被关闭,因此反序列化程序返回EOF:null错误

  • 我是否设置了TCPrecevingChannelAdapter错误

  • 如何将响应返回到网关

  • 我应该使用Future作为网关响应吗

  • TCP配置:

    @EnableIntegration
    @IntegrationComponentScan
    @Configuration
    public class TcpMultiPlexConfig implements ApplicationListener<TcpConnectionEvent> {
    
        protected final static Logger LOGGER = LoggerFactory.getLogger(TcpMultiPlexConfig.class);
    
        @Value("${engine.port}")
        private int port;// = 55001;
        @Value("${engine.address}")
        private String ipAddress;// = "192.168.1.1";
        @Value("${engine.timeout}")
        private int timeout;
    
        @Override
        public void onApplicationEvent(TcpConnectionEvent tcpEvent) {
            TcpConnection source = (TcpConnection) tcpEvent.getSource();
            if (tcpEvent instanceof TcpConnectionOpenEvent) {
                LOGGER.info("********* Socket Opened " + source.getConnectionId());
            } else if (tcpEvent instanceof TcpConnectionCloseEvent) {
                LOGGER.info("*********** Socket Closed " + source.getConnectionId());
            }
        }
    
        @MessagingGateway(defaultRequestChannel="input")
        public interface MultiPlexGateway {
    
            String send(@Payload String in, @Header("CORRELATION_ID") String transactionId);
    
        }
        // TODO the request and response are being put together
        @Bean
        @ServiceActivator(inputChannel = "input")
        public BridgeHandler bridge() {
            BridgeHandler bridge = new BridgeHandler();
            bridge.setOutputChannelName("toAggregatorClient");
            bridge.setOrder(1);
            return bridge;
        }
    
        @Bean
        public PublishSubscribeChannel input() {
            return new PublishSubscribeChannel();
        }
    
        @Bean
        public DirectChannel toAggregatorClient() {
            return new DirectChannel();
        }
    
        @Bean
        public DirectChannel noResponseChannel() {
            return new DirectChannel();
        }
    
        @Bean
        public DirectChannel toTransformerClient() {
            return new DirectChannel();
        }
    
        @Bean
        public TcpReceivingChannelAdapter inAdapterClient() {
            TcpReceivingChannelAdapter receivingAdapter = new TcpReceivingChannelAdapter();
            receivingAdapter.setConnectionFactory(clientConnectionFactory());
            receivingAdapter.setOutputChannel(toAggregatorClient());
            receivingAdapter.setClientMode(true);
            return receivingAdapter;
        }
    
    
        @Bean
        @ServiceActivator(inputChannel = "input")
        public TcpSendingMessageHandler outAdapterClient() {
            TcpSendingMessageHandler outAdapter = new TcpSendingMessageHandler();
            outAdapter.setOrder(2);
            outAdapter.setConnectionFactory(clientConnectionFactory());
            outAdapter.setClientMode(true);
            return outAdapter;
        }
    
        @Bean(name ="clientCFMP")
        public AbstractClientConnectionFactory clientConnectionFactory() {
            TcpNetClientConnectionFactory tcp = new TcpNetClientConnectionFactory(this.ipAddress , this.port);
            tcp.setSerializer(new DefaultSerializer()); // out
    //      byte delimeter = "\n".getBytes()[0];
    //      ElasticByteArrayRawSingleTerminatorSerializer deserializer = new ElasticByteArrayRawSingleTerminatorSerializer(delimeter);
    //      DefaultDeserializer deserializer = new DefaultDeserializer();
            MyDefaultDeserializer deserializer = new MyDefaultDeserializer();
            tcp.setDeserializer(deserializer);
    
            tcp.setSoTimeout(timeout);
            tcp.setSingleUse(false);
            MapMessageConverter mc = new MapMessageConverter();
            mc.setHeaderNames("CORRELATION_ID");
            tcp.setMapper(new MessageConvertingTcpMessageMapper(mc));
    
            return tcp;
        }
    
    
        @MessageEndpoint
        public static class MyConverters {
    
            @Transformer(inputChannel="toTransformerClient", outputChannel = "resultToString")
            public byte[] getResponse(MessageGroup payload) {
    //          byte[] result = null;
                List<Message<?>>list = new ArrayList<>(payload.getMessages());
                byte[] result = (byte[]) list.get(1).getPayload();
    //          LOGGER.info(result);
                return result;
            }
    
            @Transformer(inputChannel="resultToString")
            public String convertResult(byte[] bytes) {
                String result = new String(bytes);
                LOGGER.info("*********** RESULT => " + result);
                return result;
            }
    
            @ServiceActivator(inputChannel = "noResponseChannel")
            public MessageTimeoutException  noResponse(String input) {
                throw new MessageTimeoutException("****** No response received for => " + input);
            }
    
        }
    
    
    
        @Bean
        @ServiceActivator(inputChannel = "toAggregatorClient", outputChannel = "toTransformerClient")
        public FactoryBean<MessageHandler>  aggregatorFactoryBean() {
            AggregatorFactoryBean  afb = new AggregatorFactoryBean ();
            afb.setExpireGroupsUponCompletion(true);
            afb.setExpireGroupsUponTimeout(true);
            afb.setGroupTimeoutExpression(new ValueExpression<>(this.timeout));
            afb.setCorrelationStrategy(new HeaderAttributeCorrelationStrategy("CORRELATION_ID"));
            afb.setReleaseStrategy(new MessageCountReleaseStrategy(2));
            afb.setProcessorBean(new DefaultAggregatingMessageGroupProcessor());
            afb.setSendPartialResultOnExpiry(false);
            afb.setMessageStore(new SimpleMessageStore());
            afb.setDiscardChannel(noResponseChannel());
            return afb;
        }
    
    @使能集成
    @集成组件扫描
    @配置
    公共类TcpMultiPlexConfig实现ApplicationListener{
    受保护的最终静态记录器Logger=LoggerFactory.getLogger(TcpMultiPlexConfig.class);
    @值(“${engine.port}”)
    专用int端口;//=55001;
    @值(“${engine.address}”)
    专用字符串ipAddress;//=“192.168.1.1”;
    @值(“${engine.timeout}”)
    私有int超时;
    @凌驾
    ApplicationEvent(TcpConnectionEvent tcpEvent)上的公共无效{
    TcpConnection源=(TcpConnection)tcpEvent.getSource();
    if(TcpConnectionOpenEvent的tcpEvent实例){
    LOGGER.info(“*******套接字已打开”+source.getConnectionId());
    }else if(TCP连接关闭事件的TCP事件实例){
    LOGGER.info(“*********套接字已关闭”+source.getConnectionId());
    }
    }
    @MessagingGateway(defaultRequestChannel=“输入”)
    公共接口多路网关{
    String send(@Payload String in,@Header(“CORRELATION_ID”)String transactionId);
    }
    //TODO正在将请求和响应放在一起
    @豆子
    @ServiceActivator(inputChannel=“输入”)
    公共BridgeHandler bridge(){
    BridgeHandler bridge=新的BridgeHandler();
    setOutputChannelName(“toAggregatorClient”);
    桥。设置顺序(1);
    返回桥;
    }
    @豆子
    公共出版物订阅频道输入(){
    返回新的PublishSubscribeChannel();
    }
    @豆子
    public DirectChannel toAggregatorClient(){
    返回新的DirectChannel();
    }
    @豆子
    公共直接频道noResponseChannel(){
    返回新的DirectChannel();
    }
    @豆子
    公共直接通道至变压器客户(){
    返回新的DirectChannel();
    }
    @豆子
    公共TcPrecevingChannelAdapter inAdapterClient(){
    TCPrecivingChannelAdapter receivingAdapter=新的TCPrecivingChannelAdapter();
    receivingAdapter.setConnectionFactory(clientConnectionFactory());
    setOutputChannel(toAggregatorClient());
    receivingAdapter.setClientMode(真);
    返回接收适配器;
    }
    @豆子
    @ServiceActivator(inputChannel=“输入”)
    公共TcpSendingMessageHandler outAdapterClient(){
    TcpSendingMessageHandler outAdapter=新的TcpSendingMessageHandler();
    outAdapter.setOrder(2);
    setConnectionFactory(clientConnectionFactory());
    outAdapter.setClientMode(true);
    返回输出适配器;
    }
    @Bean(name=“clientCFMP”)
    公共抽象clientConnectionFactory clientConnectionFactory(){
    TcpNetClientConnectionFactory tcp=新的TcpNetClientConnectionFactory(this.ipAddress,this.port);
    tcp.setSerializer(新的DefaultSerializer());//输出
    //byte delimeter=“\n”。getBytes()[0];
    //ElasticByteArrayRawSingleTerminatorSerializer反序列化器=新的ElasticByteArrayRawSingleTerminatorSerializer(delimeter);
    //DefaultDeserializer反序列化器=新的DefaultDeserializer();
    MyDefaultDeserializer反序列化程序=新的MyDefaultDeserializer();
    设置反序列化器(反序列化器);
    tcp.setSoTimeout(超时);
    tcp.setSingleUse(假);
    MapMessageConverter mc=新的MapMessageConverter();
    mc.setHeaderNames(“相关ID”);
    tcp.setMapper(newmessageconvertingcpmessageapper(mc));
    返回tcp;
    }
    @消息端点
    公共静态类myconverter{
    @变压器(inputChannel=“toTransformerClient”,outputChannel=“resultToString”)
    公共字节[]getResponse(消息组有效负载){
    //字节[]结果=空;
    
    List我没有详细查看您的代码;已经很晚了,而且是一个周末,但请参阅,以获得一种更简单的技术,使用入站/出站连接ID关联请求/回复

    @Service
    public class MultiPlexGatewayTransmission <T extends EngineData> extends AbstractMultiPlexEngineTransmission {
    
        public MultiPlexGatewayTransmission(MultiPlexGateway gateway) {
            super(gateway);
        }
    
        @Override
        public T request(EngineData request, Class<? extends EngineData> clazz) {
            String response = gateway.send(JaxbUtils.marshall(request), request.getApi().getMessageId());
            gateway.send(JaxbUtils.marshall(request), request.getApi().getMessageId());
            if(response == null || response.isEmpty()) {
                return null;
            }
    
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("MPGateway response ::: " + response.trim());
            }
    
            @SuppressWarnings("unchecked")
            T clientResponse = (T) JaxbUtils.unmarshall(response, clazz);
            if (LOGGER.isDebugEnabled()) {
    //          LOGGER.debug("*** Unmarshall response ::: " + clientResponse);
            }
            return clientResponse;
        }
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    @ActiveProfiles("test")
    public class ITGetClientsTest extends AbstractEngineTest {
    
        private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());
    
    //  @Autowired
    //  private GatewayTransmission<ClientsResponse> transmission;
    
        @Autowired
        private MultiPlexGatewayTransmission<ClientsResponse> transmission;
    
        @Test
        public void testGetClients() {
            LOGGER.info("Gateway test testGetClients... ");
    
            Api api = new Api();
            api.setIp("192.168.1.1");
            api.setMessageId(UUID.randomUUID().toString());
            api.setVersion("1.0");      
            api.setUserToken(token);
    
            ClientsRequest request = new ClientsRequest();
            request.setApi(api);
    
            ClientsResponse response = (ClientsResponse) transmission.request(request, ClientsResponse.class);
            Assert.assertTrue(response != null);
            Assert.assertTrue(!response.getClient().isEmpty());
    
            LOGGER.info(Arrays.deepToString(response.getClient().toArray()));
        }
    
    
    
    }