2013-04-11 51 views
0

也許這是一個愚蠢的問題,我錯過了一些非常簡單的事情,但我很困難。 我使用ActiveMQ的5.5.1和2.1.4 SIspring-jms OutboundGateway不接聽回覆

我CONFIGS片段:

--- SERVER ---

<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> 

--- CLIENT ---

<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> 

然後在代碼中的一些地方,我手動執行請求和監聽應答信道:

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; 
    } 
} 

但我收到

"MessageTimeoutException: failed to receive JMS response within timeout of: 20000ms" 

所有的時間。 當我查看服務器日誌時,我發現具有正確有效負載的答覆已成功從服務器發送到客戶端,而且, 答覆被置於REPLY_LIST_QUEUE中,正如我在ActiveMQ管理控制檯中看到的。 沒有更多的事情發生! REPLY_LIST_QUEUE中的消息With_Correct_Payload駐留在此隊列中的Pending和Enqueued狀態中。 沒有消息出隊。 看起來,儘管receive-timeout =「20000ms」的延遲遠遠足以得到答覆,但JmsOutboundGateway不會接收來自回覆目標隊列的消息。 我在做什麼錯?

回答

1

這是因爲出站網關對消息關聯有一些期望。我認爲,使用您的配置,網關希望服務器在關聯ID中返回入站消息ID。它使用消息選擇器來接收其答覆。

如果您在服務器上使用入站網關,它將爲您處理關聯。

是否有任何特殊原因選擇在服務器上使用離散通道適配器而不是入站網關?

您可能需要考慮升級到2.2.3,其中對出站網關進行了一些改進(但仍需要服務器進行適當的關聯)。

編輯:每低於您的評論...

如果你想使用一對適配器代替,與當前的配置,你將不得不使用一個<header-enricher/>jms_messageid複製入站頭jms_correlationId

或者,在客戶端(出站網關),將correlation-key屬性設置爲JmsCorrelationId。這將導致網關在出站消息中填充該標頭,並且在服務器端不需要任何東西。

+0

謝謝,加里,您的回覆 – user1676178 2013-04-23 13:27:03

+0

謝謝,加里,您的回覆,我很遺憾延遲評論 - 我一直在旅途中。事實上,事實證明,沒有什麼特別的不使用入站網關的原因。但我一直在想這是。:)。所以,對於出站和入站網關,一切工作都正常。但是,如果我真的有理由在服務器上創建兩個單獨的通道適配器(入站和出站)呢?我可能在服務器上建立什麼樣的關聯?使用setCorrelationId,例如?AFAIK,使用服務激活器(即使用SI消息,並且我必須使用服務激活器)我無法獲得JMS頭文件? – user1676178 2013-04-23 13:46:06

+0

我更新了我的答案。 – 2013-04-23 14:55:26