2012-05-02 47 views
1

SimpleMessageListenerContainer选项外,不会为临时队列创建使用者。 我不会为一些问题用SimpleMessageListenerContainer面临here.为什么消费者不是为ActiveMQ Temp Queue创建的?

下面的代码是不工作...(是不是即使在创建临时队列)

     using (IConnection connection = connectionFactory.CreateConnection()) 
        using (ISession session = connection.CreateSession()) 
        { 
         IDestination destination = SessionUtil.GetDestination(session, aQueueName); 
         var replyDestination = session.CreateTemporaryQueue(); 

         // Create a consumer and producer 
         using (IMessageProducer producer = session.CreateProducer(destination)) 
         { 
          // Start the connection so that messages will be processed. 
          connection.Start(); 

          IBytesMessage request = session.CreateBytesMessage(aMsg); 
          request.NMSReplyTo = replyDestination; 

          IMessageConsumer consumer = session.CreateConsumer(replyDestination); 
          consumer.Listener += new MessageListener(this.OnAckRecieved); 

          // Send a message 
          producer.Send(request); 
          ack = this.autoEvent.WaitOne(this.msgConsumeTimeOut, true); 

          consumer.Close(); 
          consumer.Dispose(); 
          ConnectionFactoryUtils.GetTargetSession(session).DeleteDestination(replyDestination); 
         } 
         connection.Close(); 
         session.Close(); 

Flollowing代码工作: - 但是队列似乎是永久队列不一个临时队列

     using (IConnection connection = connectionFactory.CreateConnection()) 
        using (ISession session = connection.CreateSession()) 
        { 
         IDestination destination = SessionUtil.GetDestination(session, aQueueName); 
         var replyDestination = session.CreateTemporaryQueue(); 

         // Create a consumer and producer 
         using (IMessageProducer producer = session.CreateProducer(destination)) 
         { 
          // Start the connection so that messages will be processed. 
          connection.Start(); 

          IBytesMessage request = session.CreateBytesMessage(aMsg); 
          request.NMSReplyTo = replyDestination; 

          IDestination tempDestination = this.destinationResolver.ResolveDestinationName(session, request.NMSReplyTo.ToString()); 
          IMessageConsumer consumer = session.CreateConsumer(tempDestination); 
          consumer.Listener += new MessageListener(this.OnAckRecieved); 

          // Send a message 
          producer.Send(request); 
          ack = this.autoEvent.WaitOne(this.msgConsumeTimeOut, true); 

          consumer.Close(); 
          consumer.Dispose(); 
          ConnectionFactoryUtils.GetTargetSession(session).DeleteDestination(tempDestination); 
         } 
         connection.Close(); 
         session.Close(); 

与上面的代码(使用NmsDestinationAccessor的)它是working.but它创建一个永久队列。因此,当我直接使用临时队列答复目标时,它不起作用。

+0

你的意思是什么“未创建”,CreateConsumer()抛出任何异常或只是返回null? –

+0

根本没有错误。当我在webconsole上看到时,即使不为第二个代码创建临时队列。对于第三个代码,只有消费者未被创建。 –

+0

在NMS项目中增加了一个示例NUnit测试,以显示它的实际应用。 –

回答

0
  1. 与其使用C#,不如使用java编写代码,因为它是ActiveMQ的最佳套件。 阅读here for examples using temp queue in java.
  2. 然后把它编译成一个JAR文件,你可以在你的C#代码通过IKVM.NET导入为描述here
  3. 希望将这项工作。

注意:您必须知道您不能在不同的会话中使用temperory队列。

0

直接从NMSReplyTo.ToString方法直接创建对象ActiveMQTempQueue可能会引起您的问题,因为ToString方法无法保证返回可创建匹配目标的值。既然你不知道发送者是否指定了一个临时目标,或者它是否是正常的,那么它的编码也是错误的。正确的做法是简单地使用会话的创建使用者方法使用NSMReplyTo目的地原样创建新的使用者。

以下是NMS项目中的一个简单的请求响应测试用例,它与Apache.NMS.Stomp和Apache.NMS.ActiveMQ一起工作。

namespace Apache.NMS.Test 
{ 
[TestFixture] 
public class RequestResponseTest : NMSTestSupport 
{ 
    protected static string DESTINATION_NAME = "RequestDestination"; 

    [Test] 
    [Category("RequestResponse")]  
    public void TestRequestResponseMessaging() 
    { 
     using(IConnection connection = CreateConnection()) 
     { 
      connection.Start(); 
      using(ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge)) 
      { 
       IDestination destination = SessionUtil.GetDestination(session, DESTINATION_NAME); 
       ITemporaryQueue replyTo = session.CreateTemporaryQueue(); 

       using(IMessageConsumer consumer = session.CreateConsumer(destination)) 
       using(IMessageProducer producer = session.CreateProducer(destination)) 
       { 
        IMessage request = session.CreateMessage(); 

        request.NMSReplyTo = replyTo; 

        producer.Send(request); 

        request = consumer.Receive(TimeSpan.FromMilliseconds(3000)); 
        Assert.IsNotNull(request); 
        Assert.IsNotNull(request.NMSReplyTo); 

        using(IMessageProducer responder = session.CreateProducer(request.NMSReplyTo)) 
        { 
         IMessage response = session.CreateTextMessage("RESPONSE");       
         responder.Send(response); 
        }      
       } 

       using(IMessageConsumer consumer = session.CreateConsumer(replyTo)) 
       { 
        ITextMessage response = consumer.Receive(TimeSpan.FromMilliseconds(3000)) as ITextMessage; 
        Assert.IsNotNull(response); 
        Assert.AreEqual("RESPONSE", response.Text); 
       } 
      } 
     } 
    } 
} 
+0

如果没有完整的代码,肯定无法说第三个代码会创建一个消费者,然后立即在使用块之后消费者将被处置,从而将其从经纪人中取消订阅。 –

+0

与我的差异:1)connection.Start()放在创建consumer之前。2)connection.createSession放在connection.Start()之前。这可能是原因吗? –

+0

唯一的连接。开始做的是将消息调度给消费者。如果事情不适合你,那么最好的办法是创建一个NUnit测试用例,并将它附加到apache的新Jira问题上。 –

0

临时队列仅在创建它的连接存在时才存在。在开始连接之前,您正在创建示例代码,所以我认为它只是默默地出错,因为没有活动的连接。

+0

它在启动之前创建它们是合法的,这就是启动方法的意图。在调用开始之前,您通常会创建所有目的地,生产者和消费者。 –

+0

好吧,我没有使用临时队列,他说临时队列没有被创建,所以我只是猜测这可能是问题。在你的测试用例中,它们是在连接存在后创建的,所以认为这可能是关键区别。 – Thymine

相关问题