activeMq-CPP应用程序demo

author: 陈训

一、avtiveMq服务端的安装

1、从官网获取软件包:

网址:​​http://activemq.apache.org/activemq-590-release.html​

activeMq-CPP的使用_mq

2、解压运行activeMq

wget     ​​http://archive.apache.org/dist/activemq/apache-activemq/5.9.0/apache-activemq-5.9.0-bin.tar.gz​

解压:tar  zxvf  apache-activemq-5.9.0-bin.tar.gz

进入到解压的文件中去:运行activeMq

activeMq-CPP的使用_kafka_02

用ps -elf|grep active查看一下是否在后台运行

activeMq-CPP的使用_消息队列_03

3、监控

ActiveMQ默认启动时,启动了内置的jetty服务器,提供一个用于监控ActiveMQ的admin应用。 

访问链接形式:​​http://127.0.0.1:8161/admin/​

在浏览器中访问上面的链接(注意:ip修改成activeMq服务端的ip地址),出现登录界面,输入用户名和密码会进入activeMq管理网页页面(用户和密码都是admin)

在稍后的运行demo后可以从这个网页监控端查看队列名称、生产的消息数目以及消费情况以及是否有消费者正在等待消息的到来

activeMq-CPP的使用_activemq_04

二、activeMq cpp的编译安装

1、介绍:AvtiveMqcpp是activeMq的c++接口,从官网提供地址下载即可

wget     ​​http://apache.fayea.com/activemq/activemq-cpp/3.9.3/activemq-cpp-library-3.9.3-src.tar.gz​

tar   -zxvf  activemq-cpp-library-3.9.3-src.tar.gz

先完成下面的步骤再来编译安装

2、安装编译activeMqcpp需要安装其他的依赖包:

2.1、安装依赖包CppUnit

获取源码包:wget    ​​https://sourceforge.net/projects/cppunit/files/cppunit/1.12.1/cppunit-1.12.1.tar.gz​

解压:tar -zxvfcppunit-1.12.1.tar.gz

进入到解压的文件中,然后三步安装法

./configure  --prefix=/usr/local/cppunit/

make

makeinstall

2.2、安装依赖包apr、apr-util和apr-iconv(如果你没有安装openssl的话需要安装openssl)

从​​http://apache.fayea.com/apr/​​镜像网站下载

Openssl网址:​​http://www.openssl.org/source/openssl-1.0.0a.tar.gz​

同2.1步骤中一样先解压再进入到各自的解压的文件中去再执行下面的安装步骤(三个依次上面的额顺序安装)

./configure  --prefix=/usr/local/apr/

make

makeinstall

 

./configure  --prefix=/usr/local/aprutil  --with-apr=/usr/local/apr/

make

makeinstall

 

./configure  --prefix=/usr/local/apr-iconv/  --with-apr=/usr/local/apr/

make

makeinstall

 

./config --prefix=/usr/local/openssl/

make

makeinstall


2.3、再来编译activeMq cpp源码,执行下面的步骤即可

./configure  --prefix=/usr/local/ActiveMQ-CPP --with-apr=/usr/local/apr/  --with-apr-util=/usr/local/aprutil/  --with-cppunit=/usr/local/cppunit  --with-openssl=/usr/local/openssl

make

make install

注:完成上面所有的步子就可以用cpp来编写activeMq应用接口了(producer和consumer)

注意:

出现这个或者fatal error: openssl/名单.h: No such file or directory。都是没有安装libssl-dev~

libssl-dev包含libraries, header files and manpages,他是openssl的一部分,而openssl对ssl进行了实现~


yum  install libssl-dev

yum  install openssl*

然后重新编译即可

三、运行demo

g++ producer.cpp -o send  -I/usr/local/ActiveMQ-CPP/   -I/usr/local/apr/include/apr-1  -L/usr/local/ActiveMQ-CPP/lib  -lactivemq-cpp

g++ consumer.cpp -o consumer  -I/usr/local/ActiveMQ-CPP/   -I/usr/local/apr/include/apr-1  -L/usr/local/ActiveMQ-CPP/lib  -lactivemq-cpp


activeMq-CPP的使用_activeM_05


1、send消息



activeMq-CPP的使用_activemq_06



2、消费消息



activeMq-CPP的使用_消息队列_07



3、查看网页监控端的情况



activeMq-CPP的使用_mq_08




代码如下:producer.cpp和consumer.cpp



#include <decaf/lang/Thread.h>
#include <decaf/lang/Runnable.h>
#include <decaf/util/concurrent/CountDownLatch.h>
#include <decaf/lang/Long.h>
#include <decaf/util/Date.h>
#include <activemq/core/ActiveMQConnectionFactory.h>
#include <activemq/util/Config.h>
#include <activemq/library/ActiveMQCPP.h>
#include <cms/Connection.h>
#include <cms/Session.h>
#include <cms/TextMessage.h>
#include <cms/BytesMessage.h>
#include <cms/MapMessage.h>
#include <cms/ExceptionListener.h>
#include <cms/MessageListener.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <memory>

using namespace activemq;
using namespace activemq::core;
using namespace decaf;
using namespace decaf::lang;
using namespace decaf::util;
using namespace decaf::util::concurrent;
using namespace cms;
using namespace std;


class SimpleProducer : public Runnable {
private:

Connection* connection;
Session* session;
Destination* destination;
MessageProducer* producer;
bool useTopic;
bool clientAck;
unsigned int numMessages;
std::string brokerURI;
std::string destURI;

private:

SimpleProducer( const SimpleProducer& );
SimpleProducer& operator= ( const SimpleProducer& );

public:

SimpleProducer( const std::string& brokerURI, unsigned int numMessages,
const std::string& destURI, bool useTopic = false, bool clientAck = false ) :
connection(NULL),
session(NULL),
destination(NULL),
producer(NULL),
useTopic(useTopic),
clientAck(clientAck),
numMessages(numMessages),
brokerURI(brokerURI),
destURI(destURI) {
}

virtual ~SimpleProducer(){
cleanup();
}

void close() {
this->cleanup();
}

virtual void run() {
try {
auto_ptr<ActiveMQConnectionFactory> connectionFactory(new ActiveMQConnectionFactory( brokerURI ) );

try{
connection = connectionFactory->createConnection();
connection->start();
} catch( CMSException& e ) {
e.printStackTrace();
throw e;
}

if( clientAck )
{
session = connection->createSession( Session::CLIENT_ACKNOWLEDGE );
} else
{
session = connection->createSession( Session::AUTO_ACKNOWLEDGE );
}

if( useTopic )
{
destination = session->createTopic( destURI );
} else
{
destination = session->createQueue( destURI );
}

producer = session->createProducer( destination );
producer->setDeliveryMode( DeliveryMode::NON_PERSISTENT );

string threadIdStr = Long::toString( Thread::currentThread()->getId() );
string text = (string)"Hello world! from thread " + threadIdStr;

for( unsigned int ix=0; ix<numMessages; ++ix )
{
TextMessage* message = session->createTextMessage( text );
message->setIntProperty( "Integer", ix );
printf( "Sent message #%d from thread %s\n", ix+1, threadIdStr.c_str() );
producer->send( message );
delete message;
}

}catch ( CMSException& e ) {
e.printStackTrace();
}
}

private:

void cleanup(){
try{
if( destination != NULL ) delete destination;
}catch ( CMSException& e ) { e.printStackTrace(); }
destination = NULL;

try
{
if( producer != NULL ) delete producer;
}catch ( CMSException& e ) { e.printStackTrace(); }
producer = NULL;

try{
if( session != NULL ) session->close();
if( connection != NULL ) connection->close();
}catch ( CMSException& e ) { e.printStackTrace(); }

try{
if( session != NULL ) delete session;
}catch ( CMSException& e ) { e.printStackTrace(); }
session = NULL;

try{
if( connection != NULL ) delete connection;
}catch ( CMSException& e ) { e.printStackTrace(); }
connection = NULL;
}
};

int main(int argc , char* argv[])
{

activemq::library::ActiveMQCPP::initializeLibrary();
std::cout << "=====================================================\n";
std::cout << "Starting produce message:" << std::endl;
std::cout << "-----------------------------------------------------\n";

std::string brokerURI ="failover://(tcp://127.0.0.1:61616)";
unsigned int numMessages = 2000;
std::string destURI = "test.chen";

bool useTopics = false;
SimpleProducer producer( brokerURI, numMessages, destURI, useTopics );
producer.run();
producer.close();

std::cout << "-----------------------------------------------------\n";
std::cout << "Finished test" << std::endl;
std::cout << "=====================================================\n";

activemq::library::ActiveMQCPP::shutdownLibrary();
}


consumer.cpp


#include <decaf/lang/Thread.h>
#include <decaf/lang/Runnable.h>
#include <decaf/util/concurrent/CountDownLatch.h>
#include <activemq/core/ActiveMQConnectionFactory.h>
#include <activemq/core/ActiveMQConnection.h>
#include <activemq/transport/DefaultTransportListener.h>
#include <activemq/library/ActiveMQCPP.h>
#include <decaf/lang/Integer.h>
#include <activemq/util/Config.h>
#include <decaf/util/Date.h>
#include <cms/Connection.h>
#include <cms/Session.h>
#include <cms/TextMessage.h>
#include <cms/BytesMessage.h>
#include <cms/MapMessage.h>
#include <cms/ExceptionListener.h>
#include <cms/MessageListener.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>

using namespace activemq;
using namespace activemq::core;
using namespace activemq::transport;
using namespace decaf::lang;
using namespace decaf::util;
using namespace decaf::util::concurrent;
using namespace cms;
using namespace std;


class SimpleAsyncConsumer : public ExceptionListener,
public MessageListener,
public DefaultTransportListener {
private:

Connection* connection;
Session* session;
Destination* destination;
MessageConsumer* consumer;
bool useTopic;
std::string brokerURI;
std::string destURI;
bool clientAck;

private:

SimpleAsyncConsumer( const SimpleAsyncConsumer& );
SimpleAsyncConsumer& operator= ( const SimpleAsyncConsumer& );

public:

SimpleAsyncConsumer( const std::string& brokerURI,
const std::string& destURI,
bool useTopic = false,
bool clientAck = false ) :
connection(NULL),
session(NULL),
destination(NULL),
consumer(NULL),
useTopic(useTopic),
brokerURI(brokerURI),
destURI(destURI),
clientAck(clientAck) {
}

virtual ~SimpleAsyncConsumer() {
this->cleanup();
}

void close() {
this->cleanup();
}

void runConsumer() {

try {
ActiveMQConnectionFactory* connectionFactory = new ActiveMQConnectionFactory( brokerURI );
connection = connectionFactory->createConnection();
delete connectionFactory;

ActiveMQConnection* amqConnection = dynamic_cast<ActiveMQConnection*>( connection );
if( amqConnection != NULL )
{
amqConnection->addTransportListener( this );
}

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

if( clientAck ) {
session = connection->createSession( Session::CLIENT_ACKNOWLEDGE );
} else {
session = connection->createSession( Session::AUTO_ACKNOWLEDGE );
}

if( useTopic ) {
destination = session->createTopic( destURI );
} else {
destination = session->createQueue( destURI );
}

consumer = session->createConsumer( destination );
consumer->setMessageListener( this );

} catch (CMSException& e) {
e.printStackTrace();
}
}

virtual void onMessage( const Message* message ) {
static int count = 0;
try
{
count++;
const TextMessage* textMessage =
dynamic_cast< const TextMessage* >( message );
string text = "";

if( textMessage != NULL ) {
text = textMessage->getText();
} else {
text = "NOT A TEXTMESSAGE!";
}

if( clientAck ) {
message->acknowledge();
}

printf( "Message #%d Received: %s\n", count, text.c_str() );
} catch (CMSException& e) {
e.printStackTrace();
}
}

virtual void onException( const CMSException& ex AMQCPP_UNUSED ) {
printf("CMS Exception occurred. Shutting down client.\n");
exit(1);
}

virtual void transportInterrupted() {
std::cout << "The Connection's Transport has been Interrupted." << std::endl;
}

virtual void transportResumed() {
std::cout << "The Connection's Transport has been Restored." << std::endl;
}

private:

void cleanup(){
try{
if( destination != NULL ) delete destination;
}catch (CMSException& e) {}
destination = NULL;

try{
if( consumer != NULL ) delete consumer;
}catch (CMSException& e) {}
consumer = NULL;

try{
if( session != NULL ) session->close();
if( connection != NULL ) connection->close();
}catch (CMSException& e) {}

try{
if( session != NULL ) delete session;
}catch (CMSException& e) {}
session = NULL;

try{
if( connection != NULL ) delete connection;
}catch (CMSException& e) {}
connection = NULL;
}
};

int main(int argc, char* argv[]) {

activemq::library::ActiveMQCPP::initializeLibrary();

std::cout << "=====================================================\n";
std::cout << "Starting the example:" << std::endl;
std::cout << "-----------------------------------------------------\n";

std::string brokerURI = "failover:(tcp://127.0.0.1:61616)";

std::string destURI = "test.chen";
bool useTopics = false;
bool clientAck = false;
SimpleAsyncConsumer consumer( brokerURI, destURI, useTopics, clientAck );
consumer.runConsumer();
std::cout << "Press 'q' to quit" << std::endl;
while( std::cin.get() != 'q') {}
consumer.close();

std::cout << "-----------------------------------------------------\n";
std::cout << "Finished with the example." << std::endl;
std::cout << "=====================================================\n";

activemq::library::ActiveMQCPP::shutdownLibrary();
}