该博客收到一些反应,说教程不够明细操作的时候怎么都不行,特今日(2017年8月29日17点)进行博客修改,并将新demo一起附上,建议看看博客下面的“需要注意的地方”后在来编译demo!
所需的关联lib,dll,还有新实例demo都在下面这个附件里面,我的demo是用的vs2008编辑器。
新附件下载地址(如失效请联系):http://pan.baidu.com/s/1eS1pzkm
也可以直接参考下面的代码
编译的是时候需要导入activemq-cpp源码,可以去官网下载
http://activemq.apache.org/cms/download.html
activemq-cpp.lib activemq-cpp.dll也是需要编译的,嫌编译麻烦,可以直接使用附件里面编译好的
apr依赖下载地址:http://apr.apache.org/download.cgi
apr-1.6.2-win32-src.zip,apr-iconv-1.2.1-win32-src-r2.zip, apr-util-1.6.0-win32-src.zip
一共是三个,下载后需要编译出lib,dll ,嫌编译麻烦,可以直接使用附件里面编译好的
#include "stdafx.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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:
SimpleProducer(){}
virtual ~SimpleProducer();
void start( const std::string& brokerURI, unsigned int numMessages, const std::string& destURI, bool useTopic , bool clientAck);
void send(const char* bytesMessage,int nSize);
void sendTxtMsg(const std::string& textMsg);
void close();
virtual void onException( const CMSException& ex AMQCPP_UNUSED );
virtual void transportInterrupted();
virtual void transportResumed();
private:
void cleanup();
virtual void initialize();
virtual string UnicodeToUTF8( const wstring& str );
virtual wstring ANSIToUnicode( const std::string& str );
private:
Connection* connection;
Session* session;
Destination* destination;
MessageProducer* producer;
bool useTopic;
bool clientAck;
unsigned int numMessages;
std::string brokerURI;
std::string destURI;
BytesMessage* bytesMessage;
TextMessage* textMessage;
};
#include "stdafx.h"
#include "SimpleProducer.h"
#include
//liuwei
//QQ:851668663
SimpleProducer::~SimpleProducer()
{
delete bytesMessage;
delete textMessage;
cleanup();
}
void SimpleProducer::start( const std::string& brokerURI, unsigned int numMessages, const std::string& destURI, bool useTopic = false, bool clientAck = false )
{
this->connection = NULL;
this->session = NULL;
this->destination = NULL;
this->producer = NULL;
this->numMessages = numMessages;
this->useTopic = useTopic;
this->brokerURI = brokerURI;
this->destURI = destURI;
this->clientAck = clientAck;
initialize();
}
void SimpleProducer::initialize()
{
try {
// Create a ConnectionFactory
ActiveMQConnectionFactory* connectionFactory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616?transport.useAsyncSend=true&maxReconnectDelay=10000");
//connection = connectionFactory->createConnection("userName","pwd");
connection = connectionFactory->createConnection();
connection->start();
// Create a Session
if( clientAck ) {
session = connection->createSession( Session::CLIENT_ACKNOWLEDGE );
} else {
session = connection->createSession( Session::AUTO_ACKNOWLEDGE );
}
// Create the destination (Topic or Queue)
if( useTopic ) {
destination = session->createTopic( destURI );
} else {
destination = session->createQueue( destURI );
}
// Create a MessageProducer from the Session to the Topic or Queue
producer = session->createProducer( destination );
producer->setDeliveryMode( DeliveryMode::NON_PERSISTENT );
}catch ( CMSException& e ) {
printf("createConnection faill!");
e.printStackTrace();
}
}
void SimpleProducer::send(const char* Message,int nSize)
{
// 创建一个byte类型的消息
bytesMessage = session->createBytesMessage((unsigned char*)Message,nSize);
// 发送消息
producer->send(bytesMessage );
delete bytesMessage;
//cleanup();
}
void SimpleProducer::sendTxtMsg(const std::string& textMsg)
{
// 消息内容
// 创建一个文本类型的消息
TextMessage* message = session->createTextMessage();
message->setStringProperty("language","c++");
message->setText(UnicodeToUTF8(ANSIToUnicode(textMsg)));
producer->send(message);
delete message;
//cleanup();
}
void SimpleProducer::onException( const CMSException& ex AMQCPP_UNUSED )
{
//printf("CMS Exception occurred. Shutting down client.\n");
//exit(1);
}
void SimpleProducer::transportInterrupted()
{
//std::cout << "The Connection's Transport has been Interrupted." << std::endl;
printf("The Connection's Transport has been Interrupted.");
}
void SimpleProducer::transportResumed()
{
// std::cout << "The Connection's Transport has been Restored." << std::endl;
printf("The Connection's Transport has been Restored.");
}
wstring SimpleProducer::ANSIToUnicode( const std::string& str )
{
int len = 0;
len = str.length();
int unicodeLen = ::MultiByteToWideChar( CP_ACP,0,str.c_str(),-1,NULL,0 );
wchar_t * pUnicode;
pUnicode = new wchar_t[unicodeLen+1];
memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t));
::MultiByteToWideChar( CP_ACP,0,str.c_str(),-1,(LPWSTR)pUnicode,unicodeLen );
wstring rt;
rt = ( wchar_t* )pUnicode;
delete pUnicode;
return rt;
}
string SimpleProducer::UnicodeToUTF8( const wstring& str )
{
char* pElementText;
int iTextLen;
// wide char to multi char
iTextLen = WideCharToMultiByte( CP_UTF8,0,str.c_str(),-1,NULL,0,NULL,NULL );
pElementText = new char[iTextLen + 1];
memset( ( void* )pElementText, 0, sizeof( char ) * ( iTextLen + 1 ) );
::WideCharToMultiByte( CP_UTF8,0,str.c_str(),-1,pElementText,iTextLen,NULL,NULL );
string strText;
strText = pElementText;
delete[] pElementText;
return strText;
}
string UnicodeToANSI( const wstring& str )
{
char* pElementText;
int iTextLen;
// wide char to multi char
iTextLen = WideCharToMultiByte( CP_ACP,0,str.c_str(),-1,NULL,0,NULL,NULL );
pElementText = new char[iTextLen + 1];
memset( ( void* )pElementText, 0, sizeof( char ) * ( iTextLen + 1 ) );
::WideCharToMultiByte( CP_ACP,0,str.c_str(),-1,pElementText,iTextLen,NULL,NULL );
string strText;
strText = pElementText;
delete[] pElementText;
return strText;
}
void close(){
}
void SimpleProducer::cleanup()
{
// Destroy resources.
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;
// Close open resources.
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;
}
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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
{
public:
SimpleAsyncConsumer(){}
virtual ~SimpleAsyncConsumer();
void start(const std::string& brokerURI, const std::string& destURI, bool useTopic, bool clientAck );
void close();
void runConsumer();
virtual void onMessage( const Message* message );
virtual void onException( const CMSException& ex AMQCPP_UNUSED );
virtual void transportInterrupted();
virtual void transportResumed();
private:
void cleanup();
private:
Connection* connection;
Session* session;
Destination* destination;
MessageConsumer* consumer;
bool useTopic;
bool clientAck;
std::string brokerURI;
std::string destURI;
//CSharesCompute* csHaresCompute;
};
// 4、SimpleAsyncConsumer.cpp
#include "stdafx.h"
#include "SimpleAsyncConsumer.h"
SimpleAsyncConsumer::~SimpleAsyncConsumer()
{
cleanup();
}
void SimpleAsyncConsumer::close()
{
cleanup();
}
void SimpleAsyncConsumer::start(const std::string& brokerURI, const std::string& destURI, bool useTopic, bool clientAck )
{
this->connection = NULL;
this->session = NULL;
this->destination = NULL;
this->consumer = NULL;
this->useTopic = useTopic;
this->brokerURI = brokerURI;
this->destURI = destURI;
this->clientAck = clientAck;
runConsumer();
}
void SimpleAsyncConsumer::runConsumer()
{
try {
// Create a ConnectionFactory
//ActiveMQConnectionFactory* connectionFactory = new ActiveMQConnectionFactory( brokerURI );
ActiveMQConnectionFactory* connectionFactory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616?transport.useAsyncSend=true&maxReconnectDelay=10000");
//connection = connectionFactory->createConnection("userName","pwd");
connection = connectionFactory->createConnection();
//delete connectionFactory;
ActiveMQConnection* amqConnection = dynamic_cast( connection );
if( amqConnection != NULL ) {
amqConnection->addTransportListener( this );
}
connection->start();
connection->setExceptionListener(this);
// Create a Session
if( clientAck ) {
session = connection->createSession( Session::CLIENT_ACKNOWLEDGE );
} else {
session = connection->createSession( Session::AUTO_ACKNOWLEDGE );
}
// Create the destination (Topic or Queue)
if( useTopic ) {
destination = session->createTopic( destURI );
} else {
destination = session->createQueue( destURI );
}
// Create a MessageConsumer from the Session to the Topic or Queue
consumer = session->createConsumer( destination );
consumer->setMessageListener( this );
} catch (CMSException& e) {
printf("SimpleAsyncConsumer createConnection faill!");
e.printStackTrace();
}
}
// Called from the consumer since this class is a registered MessageListener.
void SimpleAsyncConsumer::onMessage( const Message* message )
{
static int count = 0;
try{
count++;
const TextMessage* txtMessage =
dynamic_cast< const TextMessage* >( message );
string text;
if( txtMessage != NULL ) {
text = txtMessage->getText();
} else {
text = "NOT A BYTE SMESSAGE!";
}
if( clientAck ) {
message->acknowledge();
}
printf( "收到字符串MSG: %s\n", text.c_str() );
} catch (CMSException& e) {
printf("SimpleAsyncConsumer 接受消息失败!");
e.printStackTrace();
}
}
void SimpleAsyncConsumer::onException( const CMSException& ex AMQCPP_UNUSED )
{
printf("CMS Exception occurred. Shutting down client.\n");
exit(1);
}
void SimpleAsyncConsumer::transportInterrupted()
{
std::cout << "The Connection's Transport has been Interrupted." << std::endl;
}
void SimpleAsyncConsumer::transportResumed()
{
std::cout << "The Connection's Transport has been Restored." << std::endl;
}
void SimpleAsyncConsumer::cleanup(){
//*************************************************
// Always close destination, consumers and producers before
// you destroy their sessions and connection.
//*************************************************
// Destroy resources.
try{
if( destination != NULL ) delete destination;
}catch (CMSException& e) {
}
destination = NULL;
try{
if( consumer != NULL ) delete consumer;
}catch (CMSException& e) {
}
consumer = NULL;
// Close open resources.
try{
if( session != NULL ) session->close();
if( connection != NULL ) connection->close();
}catch (CMSException& e) {
}
// Now Destroy them
try{
if( session != NULL ) delete session;
}catch (CMSException& e) {
}
session = NULL;
try{
if( connection != NULL ) delete connection;
}catch (CMSException& e) {
}
connection = NULL;
}
// ActiveMQDemo.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "SimpleProducer.h"
#include "SimpleAsyncConsumer.h"
SimpleProducer g_SimpleProducer;
SimpleAsyncConsumer g_SimpleAsyncConsumer;
int _tmain(int argc, _TCHAR* argv[])
{
activemq::library::ActiveMQCPP::initializeLibrary();
std::string brokerURI;
std::string destURI;
bool useTopics;
bool clientAck;
//brokerURI ="tcp://127.0.0.1:61616?transport.useAsyncSend=true&maxReconnectDelay=10000";
brokerURI ="failover:(tcp://localhost:61616)";
useTopics = false;
unsigned int numMessages = 99999999;
clientAck = false;
//destURI = "Queue.HQ.Local";
//destURI = "Queue.HQ";
//g_SimpleProducer.start( brokerURI, numMessages, destURI, useTopics ,clientAck);
destURI = "Queue.test";
g_SimpleProducer.start( brokerURI, numMessages, destURI, useTopics ,clientAck);
g_SimpleProducer.sendTxtMsg("test");
std::string brokerURIs;
std::string destURIs;
bool useTopicss;
bool clientAcks;
brokerURIs = "failover:(tcp://127.0.0.1:61616)";
useTopicss = false;
unsigned int numMessagess = 2000;
destURIs = "Queue.test";
clientAcks = false;
g_SimpleAsyncConsumer.start(brokerURIs, destURIs, useTopicss, clientAcks);
g_SimpleAsyncConsumer.runConsumer();
printf("发送字符串数据ok");
getchar();
activemq::library::ActiveMQCPP::shutdownLibrary();
return 0;
}
apr因为消费者需要,单独在C/C++ --->常规中的附加包含目录 引入,另外还有activemq-cpp的源码也是
D:\project\projectpc\work\activemq-cpp-library-3.4.0\src\main (换成你自己的目录放到附加包含目录)
下图是那些编译好的lib dll附加库目录 属性配置
这是将那些编译好的lib要加入到链接器 -> 输入->附加依赖项 中
activemq-cpp.lib apr-1.lib
apriconv-1.lib
aprutil-1.lib
cppunit.lib
libapr-1.lib
libapriconv-1.lib
libaprutil-1.lib
xml.lib
最后需要特别注意的是,需要把编译生成的各种dll放到exe执行目录下,这样执行exe的时候才能调用到那些内库,如下图
最最后要说明的当然是在运行的时候要运行activemq服务,先前就有同学说,他都配置好了,也能正常编译就是发不了消息也收不到消息,然后总找不到原因,希望同学细心点啊。
最后贴上demo运行示例图,收工!