首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >spring-jms OutboundGateway不接收回复。

spring-jms OutboundGateway不接收回复。
EN

Stack Overflow用户
提问于 2013-04-11 10:16:43
回答 1查看 2.2K关注 0票数 0

也许这是个愚蠢的问题,我错过了一些非常简单的东西,但我真的被困住了。我使用的是ActiveMQ 5.5.1和SI 2.1.4

我的倾诉片段:

服务器

代码语言:javascript
复制
    <beans:bean id="connectionFactory"   class="org.apache.activemq.ActiveMQConnectionFactory">
    <beans:property name="brokerURL" value="tcp://localhost:61616" />
</beans:bean>


   <beans:bean id="listQueue" class="org.apache.activemq.command.ActiveMQQueue">
        <beans:constructor-arg name="name" value="LIST_QUEUE"/>
    </beans:bean>   

   <beans:bean id="replyListQueue" class="org.apache.activemq.command.ActiveMQQueue">
        <beans:constructor-arg name="name" value="REPLY_LIST_QUEUE"/>
    </beans:bean>             

    <channel id="replyListChannel"/> 
    <channel id="listIn" />
    <channel id="listDriver"/>
    <channel id="listStock"/>    


    <jms:inbound-channel-adapter id="listInJms"
        connection-factory="connectionFactory"
        destination="listQueue"
        channel="listIn"        
        auto-startup="true">
        <poller fixed-rate="3000"/>
    </jms:inbound-channel-adapter>  



    <header-value-router input-channel="listIn" header-name="List"
            default-output-channel="nullChannel">        
        <mapping value="Driver" channel="listDriver" />
        <mapping value="Stock" channel="listStock" />
    </header-value-router>

    <jms:outbound-channel-adapter connection-factory="connectionFactory"
        channel="replyListChannel"
        destination="replyListQueue"
        auto-startup="true">                 
    </jms:outbound-channel-adapter>

客户

代码语言:javascript
复制
<beans:bean id="connectionFactory"  class="org.apache.activemq.ActiveMQConnectionFactory">
    <beans:property name="brokerURL" value="tcp://localhost:61616" />
</beans:bean>      

<beans:bean id="requestListQueue" class="org.apache.activemq.command.ActiveMQQueue">
    <beans:constructor-arg value="LIST_QUEUE"/>
</beans:bean>         

<beans:bean id="replyListQueue" class="org.apache.activemq.command.ActiveMQQueue">
    <beans:constructor-arg value="REPLY_LIST_QUEUE"/>
</beans:bean> 


<channel id="requestListChannel">
    <queue capacity="20"/>
</channel>   

<channel id="listStockChannel">
    <queue capacity="20"/>
</channel>   

<channel id="listDriverChannel">
    <queue capacity="20"/>
</channel>       

<channel id="replyListChannel"/>                

<jms:outbound-gateway id="outListGW"
    connection-factory="connectionFactory"
    request-destination="requestListQueue"
    request-channel="requestListChannel"
    reply-destination="replyListQueue"
    reply-channel="replyListChannel" 
    reply-timeout="20000"
    receive-timeout="20000">
    <poller fixed-rate="5000" />
</jms:outbound-gateway>     


<header-value-router input-channel="replyListChannel" header-name="List"
        default-output-channel="nullChannel">        
    <mapping value="Driver" channel="listDriverChannel" />
    <mapping value="Stock" channel="listStockChannel" />
</header-value-router>

然后,在代码中的某个地方,我手动执行请求并侦听应答通道:

代码语言:javascript
复制
    public static DriverList requestDriverList() {

    Message<String> ldrm = MessageBuilder.withPayload("DriverList request").
            setHeader("List", "Driver").build();            
    try {
        ApplicationContext ctx = 
        new ClassPathXmlApplicationContext("classpath:dmclnt/config/integ-context.xml");
        MessageChannel requestListChannel = 
                ctx.getBean("requestListChannel", MessageChannel.class);
        QueueChannel listDriverChannel = 
                ctx.getBean("listDriverChannel", QueueChannel.class);


        logger.info("Request for DriverList is sent to channel");

        Message dlm = listDriverChannel.receive(20000);

        String xmlDL = (String)dlm.getPayload(); 

        JAXBContext jaxbctx = JAXBContext.newInstance(DriverList.class);
        DriverList dl = (DriverList)jaxbctx.createUnmarshaller().
        unmarshal(newStringReader(xmlDL));
        logger.info("DriverList objct unmarshalled: "+dl.toString());
        return dl;            
    } catch (JAXBException e) {
        logger.error("Error converting xmlDriverList to DriverList object",e);
        return null;
    } catch (RuntimeException e){
        logger.error(e); 
        return null;
    } 
}

但我收到

代码语言:javascript
复制
"MessageTimeoutException: failed to receive JMS response within timeout of: 20000ms"

一直。当我查看服务器日志时,我看到带有正确有效负载的回复成功地从服务器发送到客户端,而且,答复被放置到REPLY_LIST_QUEUE中,正如我在ActiveMQ管理控制台中所看到的那样。什么都不会发生!With_Correct_Payload中的REPLY_LIST_QUEUE消息处于此队列中的挂起状态和排队状态。没有消息被删除。尽管接收超时=“20000ms”延迟远远超过了获得回复的时间,但JmsOutboundGateway似乎不会从应答目的地队列中接收消息。我做错了什么?

EN

回答 1

Stack Overflow用户

发布于 2013-04-11 12:33:53

这是因为出站网关对消息相关性有一定的期望。对于您的配置,我认为网关希望服务器返回关联id中的入站消息id。它使用消息选择器来接收其答复。

如果您在服务器上使用入站网关,它将为您处理相关。

您选择在服务器上使用离散通道适配器而不是入站网关有什么特别的原因吗?

您可能需要考虑将其提升到2.2.3,其中对出站网关进行了一些改进(但它仍然需要服务器进行适当的关联)。

编辑:根据你下面的评论..。

如果您确实希望使用一对适配器,那么在使用当前配置时,必须使用<header-enricher/>将入站标头jms_messageid复制到jms_correlationId

或者,在客户端(出站网关)上,将correlation-key属性设置为JmsCorrelationId。这将导致网关在出站消息上填充该标头,并且服务器端不需要任何内容。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15946230

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档