C++ ActiveMQ实现通讯

C++ ActiveMQ实现通讯完整版

简介

该博客收到一些反应,说教程不够明细操作的时候怎么都不行,特今日(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 <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 <activemq/transport/DefaultTransportListener.h>
#include <cms/ExceptionListener.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 <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:
	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 <windows.h>


//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 <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 
{
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<ActiveMQConnection*>( 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;
}
.这些地方是需要注意的

171909_GlF5_867520.png

apr因为消费者需要,单独在C/C++ --->常规中的附加包含目录 引入,另外还有activemq-cpp的源码也是

D:\project\projectpc\work\activemq-cpp-library-3.4.0\src\main (换成你自己的目录放到附加包含目录)

下图是那些编译好的lib dll附加库目录 属性配置

171951_bKR1_867520.png

这是将那些编译好的lib要加入到链接器 -> 输入->附加依赖项 中

172030_ecub_867520.png

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的时候才能调用到那些内库,如下图

172945_8xpg_867520.png

最最后要说明的当然是在运行的时候要运行activemq服务,先前就有同学说,他都配置好了,也能正常编译就是发不了消息也收不到消息,然后总找不到原因,希望同学细心点啊。

最后贴上demo运行示例图,收工!

173419_okMA_867520.png

转载于:https://my.oschina.net/Thinkeryjgfn/blog/704618

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值