如何使用Java注释设置Spring集成协作通道适配器?
我看过其他与我的问题相关的帖子,但没有一个答案能帮助我解决问题 我在这里试着效仿这个例子: 我有一个接受请求的SpringRESTAPI,这些请求被转换成XML,然后我将它们发送给另一个接受TCP请求的应用程序 使用TcpOutboundGateway和TcpInboundGateway工作得很好,但速度很慢,所以我想通过协作通道适配器和多路复用来加快速度 根据我的理解,这个想法是通过网关发送一个请求,该请求被桥接到聚合器,该请求也被TcpSendingMessageHandler发送到另一个应用程序的tcp服务器。然后TCPrevivingChannelAdapter侦听响应,这些响应被发送到聚合器,在聚合器中它们与其请求(CORRELATION_ID头的bc)关联,然后发送到转换通道,转换通道将字节转换为字符串 显然,我的理解是错误的,因为我看不到响应是如何返回到网关的,而且它不起作用 我可以看到套接字被打开,但它在消息发送后立即被关闭,因此反序列化程序返回EOF:null错误如何使用Java注释设置Spring集成协作通道适配器?,java,spring-boot,tcp,spring-integration,multiplexing,Java,Spring Boot,Tcp,Spring Integration,Multiplexing,我看过其他与我的问题相关的帖子,但没有一个答案能帮助我解决问题 我在这里试着效仿这个例子: 我有一个接受请求的SpringRESTAPI,这些请求被转换成XML,然后我将它们发送给另一个接受TCP请求的应用程序 使用TcpOutboundGateway和TcpInboundGateway工作得很好,但速度很慢,所以我想通过协作通道适配器和多路复用来加快速度 根据我的理解,这个想法是通过网关发送一个请求,该请求被桥接到聚合器,该请求也被TcpSendingMessageHandler发送到另一个应
@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()));
}
}