2012-05-02 5 views
1

За исключением SimpleMessageListenerContainer вариант, потребитель не создан для очереди temp. Я не буду использовать SimpleMessageListenerContainer для некоторых вопросов перед here.Почему потребитель не создан для очереди ActiveMQ Temp?

Следующий код не работает ... (даже очередь температуры не создается)

     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

Добавлен пример теста NUnit из проекта NMS, чтобы показать его в действии. –

ответ

0
  1. Вместо того, чтобы использовать C#, напишите код в java, поскольку это лучший набор для ActiveMQ. Читать here for examples using temp queue in java.
  2. а затем компилировать его в файл JAR, и вы можете импортировать его в C# код через ikvm.net, как описано here
  3. Надеюсь, что он будет работать с этим.

Примечание: вы должны знать, что вы не можете использовать темперированную очередь в разных сеансах.

0

Создание ActiveMQTempQueue объекта непосредственно из метода NMSReplyTo.ToString, вероятно, вызывающий проблемы здесь, как метод 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) соединение .Start() помещается перед созданием потребителя.2) connection.createSession помещается перед соединением. Start(). это может быть причиной? –

+0

единственное подключение. Старт - это тиграция отправки сообщений потребителям. Если что-то не работает для вас, лучше всего создать тестовый пример NUnit и прикрепить его к новой проблеме Jira в apache. –

0

Временная очередь существует только в том случае, когда созданное соединение существует. В вашем образце кода вы создаете его перед запуском соединения, поэтому я думаю, что его просто ошибка из-за отсутствия активного соединения.

+0

Его право создавать их перед вызовом start, это намерение метода start. Вы обычно создавали бы все пункты назначения, производителей и потребителей до начала запуска. –

+0

Хорошо, я не использовал временные очереди, и он сказал, что временные очереди не создаются, поэтому я просто догадался, что это может быть проблемой. В вашем тестовом примере они создаются после того, как соединение существует, поэтому считается, что это может быть ключевым отличием. – Thymine

Смежные вопросы