2013-07-19 2 views
0

VSM 2010과 함께 activemq-cpp 3.7.0을 사용하여 클라이언트를 빌드하면 서버는 ActiveMQ 5.8입니다. here과 같은 CMS 구성을 기반으로 다음과 비슷한 코드를 사용하여 메시지 소비자를 만들었습니다. ConnClassExceptionListenerMessageListener입니다. cms::Session::commit()에 전화하기 전에 단 하나의 메시지 만 사용하려고합니다.PrefetchPolicy가있는 ActiveMQ-cpp 브로커 URI가 적용되지 않음

void ConnClass::setup() 
{ 

    // Create a ConnectionFactory 
    std::tr1::shared_ptr<ConnectionFactory> connectionFactory(
     ConnectionFactory::createCMSConnectionFactory(
      "tcp://localhost:61616?cms.PrefetchPolicy.queuePrefetch=1"); 

    // Create a Connection 
    m_connection = std::tr1::shared_ptr<cms::Connection>(
     connectionFactory->createConnection()); 

    m_connection->start(); 
    m_connection->setExceptionListener(this); 

    // Create a Session 
    m_session = std::tr1::shared_ptr<cms::Session>(
     m_connection->createSession(Session::SESSION_TRANSACTED)); 


    // Create the destination (Queue) 
    m_destination = std::tr1::shared_ptr<cms::Destination>(
     m_session->createQueue("myqueue?consumer.prefetchSize=1")); 

    // Create a MessageConsumer from the Session to the Queue 
    m_consumer = std::tr1::shared_ptr<cms::MessageConsumer>(
     m_session->createConsumer(m_destination.get())); 

    m_consumer->setMessageListener(this); 

} 

void ConnClass::onMessage(const Message* message) 
{ 
    // read message code ... 
    // schedule a processing event for 
    // another thread that calls m_session->commit() when done 
} 

문제는 내가 m_session->commit()를 호출하기 전에 대신에 하나의 메시지의 여러 메시지를 수신하고합니다 - commit() 호출이 사용자 입력에 의해 트리거 때문에 나는 이것을 알고있다. commit()을 호출하기 전에 onMessage()을 한 번만 호출하려면 어떻게해야합니까?

답변

0

그런 식으로 작동하지 않습니다. 비동기 소비자를 사용할 때 메시지는 onMessage 메서드가 완료 될 때 최대한 빠르게 전달됩니다. 하나의 메시지 만 사용하려면 동기화 수신 통화를 사용하십시오.

비동기 사용자의 경우 프리 페치를 사용하면 브로커가 한 번에 하나씩 실행하는 대신 클라이언트에서 작업을 버퍼링 할 수 있으므로 일반적으로 비동기식 onMessage 호출이 완료되면 ack가 다음으로 전송되므로 더 나은 결과를 얻을 수 있습니다. 브로커가 다음 메시지를 클라이언트에 보냅니다.

+0

그러나 프리 페치 "크기"옵션으로 메시지 수를 제어 할 수없는 이유는 무엇입니까? 또는 프리 페치 옵션을 잘못 이해 했습니까? – devil

+0

옵션을 이해하지 못했습니다. 브로커에게 클라이언트 측에서 쌓아 놓고 유지해야 할 작업량을 표시합니다. 비동기 소비자의 비동기라는 단어는 단서이어야합니다. –

+0

async를 사용했기 때문에 sync를 명시 적으로 수행해야하는 추가 스레드를 관리 할 필요가 없습니다. 트랜잭션을 커밋하기 전에받은 메시지 수를 제한하려고합니다. async 메서드의 프리 페치 정책에서 size 매개 변수를 사용하여이 작업을 수행 할 수 없다는 말입니까? 단일 메시지 만 원한다면 커밋 할 때까지 메서드의 끝에서 차단하도록 onMessage를 강제해야한다는 의미입니까? 그건 그렇고, 내가 메시지를 ACKing 대신 커밋을 사용하므로 SESSION_TRANSACTED 모드를 사용하고 있습니다. – devil