之前都是使用vi+make方式进行程序开发,可以说是一种传统+质朴的*nix开发方式。有一段时间用eclipse做Java的开发,突然想真正的在eclipse下用一把eclipse cdt结果不料却这样好使,在讨厌了微软.net开发工具之后,又发现了这样一个有效的东东。回想当时还曾用Visual studio开发然后向Linux移植的做法,想来也有些可笑,毕竟还有很多什么字符集,类库兼容性的一堆的问题等你处理。现在好了,utf8夸平台行,开发的方便性上去了,连makefile也不要你写了,整个就一visual studio 6的翻版。不得不谈一个子:“爽"!
言归正传谈谈eclipse下用ActiveMQ-cpp开发ActiveMQ。ActiveMQ-cpp如果不知道是啥,去google吧,不多讲。
1.下载 ActiveMQ-cpp 我用的3.0.1版本(时下比较新的稳定版本)
安装的时候可能会给你要APR/APRUitl,照着README做就可以了
./configre
./make
./make install
2.另外做一下ld.so.conf.d里边的配置文件
不然运行的时候找不到.so奥
3.操作系统里代了eclipse,足够了,下CDT部署一下,网上有好多了
对了你要做CDT开发,千万别告诉我你没装gcc
4.启动eclipse,创建一个managed c++ project
创建一个source file cpp的,main.cpp
将ActivemMQ-CPP的example文件写进去,不过我发现这代码没有用初始话,新版本还是变化比较大的,连进程模型数值转换都比着Java实现了一下,还用的智能指针,好阿:)
给贴段代码如下:
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// START SNIPPET: demo
#include <decaf/lang/Thread.h>
#include <decaf/lang/Runnable.h>
#include <decaf/util/concurrent/CountDownLatch.h>
#include <decaf/lang/Integer.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 <iostream>
#include <memory>
using namespace activemq::core;
using namespace decaf::util::concurrent;
using namespace decaf::util;
using namespace decaf::lang;
using namespace cms;
using namespace std;
class HelloWorldProducer : public Runnable {
private:
Connection* connection;
Session* session;
Destination* destination;
MessageProducer* producer;
int numMessages;
bool useTopic;
bool sessionTransacted;
std::string brokerURI;
public:
HelloWorldProducer( const std::string& brokerURI,
int numMessages,
bool useTopic = false,
bool sessionTransacted = false ){
this->connection = NULL;
this->session = NULL;
this->destination = NULL;
this->producer = NULL;
this->numMessages = numMessages;
this->useTopic = useTopic;
this->sessionTransacted = sessionTransacted;
this->brokerURI = brokerURI;
}
virtual ~HelloWorldProducer(){
cleanup();
}
virtual void run() {
try {
// Create a ConnectionFactory
auto_ptr<ConnectionFactory> connectionFactory(
ConnectionFactory::createCMSConnectionFactory( brokerURI ) );
// Create a Connection
connection = connectionFactory->createConnection();
connection->start();
// Create a Session
if( this->sessionTransacted ) {
session = connection->createSession( Session::SESSION_TRANSACTED );
} else {
session = connection->createSession( Session::AUTO_ACKNOWLEDGE );
}
// Create the destination (Topic or Queue)
if( useTopic ) {
destination = session->createTopic( "TEST.FOO" );
} else {
destination = session->createQueue( "TEST.FOO" );
}
// Create a MessageProducer from the Session to the Topic or Queue
producer = session->createProducer( destination );
producer->setDeliveryMode( DeliveryMode::NON_PERSISTENT );
// Create the Thread Id String
string threadIdStr = Integer::toString( Thread::getId() );
// Create a messages
string text = (string)"Hello world! from thread " + threadIdStr;
for( int ix=0; ix<numMessages; ++ix ){
TextMessage* message = session->createTextMessage( text );
message->setIntProperty( "Integer", ix );
// Tell the producer to send the message
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(){
// 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;
}
};
class HelloWorldConsumer : public ExceptionListener,
public MessageListener,
public Runnable {
private:
CountDownLatch latch;
CountDownLatch doneLatch;
Connection* connection;
Session* session;
Destination* destination;
MessageConsumer* consumer;
long waitMillis;
bool useTopic;
bool sessionTransacted;
std::string brokerURI;
public:
HelloWorldConsumer( const std::string& brokerURI,
long numMessages,
bool useTopic = false,
bool sessionTransacted = false,
long waitMillis = 30000 )
: latch(1), doneLatch(numMessages){
this->connection = NULL;
this->session = NULL;
this->destination = NULL;
this->consumer = NULL;
this->waitMillis = waitMillis;
this->useTopic = useTopic;
this->sessionTransacted = sessionTransacted;
this->brokerURI = brokerURI;
}
virtual ~HelloWorldConsumer(){
cleanup();
}
void waitUntilReady() {
latch.await();
}
virtual void run() {
try {
// Create a ConnectionFactory
auto_ptr<ConnectionFactory> connectionFactory(
ConnectionFactory::createCMSConnectionFactory( brokerURI ) );
// Create a Connection
connection = connectionFactory->createConnection();
connection->start();
connection->setExceptionListener(this);
// Create a Session
if( this->sessionTransacted == true ) {
session = connection->createSession( Session::SESSION_TRANSACTED );
} else {
session = connection->createSession( Session::AUTO_ACKNOWLEDGE );
}
// Create the destination (Topic or Queue)
if( useTopic ) {
destination = session->createTopic( "TEST.FOO" );
} else {
destination = session->createQueue( "TEST.FOO" );
}
// Create a MessageConsumer from the Session to the Topic or Queue
consumer = session->createConsumer( destination );
consumer->setMessageListener( this );
std::cout.flush();
std::cerr.flush();
// Indicate we are ready for messages.
latch.countDown();
// Wait while asynchronous messages come in.
doneLatch.await( waitMillis );
} catch( CMSException& e ) {
// Indicate we are ready for messages.
latch.countDown();
e.printStackTrace();
}
}
// Called from the consumer since this class is a registered MessageListener.
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!";
}
printf( "Message #%d Received: %s/n", count, text.c_str() );
} catch (CMSException& e) {
e.printStackTrace();
}
// Commit all messages.
if( this->sessionTransacted ) {
session->commit();
}
// No matter what, tag the count down latch until done.
doneLatch.countDown();
}
// If something bad happens you see it here as this class is also been
// registered as an ExceptionListener with the connection.
virtual void onException( const CMSException& ex AMQCPP_UNUSED) {
printf("CMS Exception occurred. Shutting down client./n");
exit(1);
}
private:
void 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) { e.printStackTrace(); }
destination = NULL;
try{
if( consumer != NULL ) delete consumer;
}catch (CMSException& e) { e.printStackTrace(); }
consumer = NULL;
// Close open resources.
try{
if( session != NULL ) session->close();
if( connection != NULL ) connection->close();
}catch (CMSException& e) { e.printStackTrace(); }
// Now Destroy them
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 AMQCPP_UNUSED, char* argv[] AMQCPP_UNUSED) {
activemq::library::ActiveMQCPP::initializeLibrary ();
std::cout << "=====================================================/n";
std::cout << "Starting the example:" << std::endl;
std::cout << "-----------------------------------------------------/n";
// Set the URI to point to the IP Address of your broker.
// add any optional params to the url to enable things like
// tightMarshalling or tcp logging etc. See the CMS web site for
// a full list of configuration options.
//
// http://activemq.apache.org/cms/
//
// Wire Format Options:
// =====================
// Use either stomp or openwire, the default ports are different for each
//
// Examples:
// tcp://127.0.0.1:61616 default to openwire
// tcp://127.0.0.1:61616?wireFormat=openwire same as above
// tcp://127.0.0.1:61613?wireFormat=stomp use stomp instead
//
std::string brokerURI =
"tcp://127.0.0.1:61616"
"?wireFormat=openwire"
// "&connection.alwaysSyncSend=true"
// "&connection.useAsyncSend=true"
// "&transport.commandTracingEnabled=true"
// "&transport.tcpTracingEnabled=true"
// "&wireFormat.tightEncodingEnabled=true"
;
//============================================================
// set to true to use topics instead of queues
// Note in the code above that this causes createTopic or
// createQueue to be used in both consumer an producer.
//============================================================
bool useTopics = true;
bool sessionTransacted = false;
int numMessages = 2000;
long long startTime = Date::getCurrentTimeMilliseconds();
HelloWorldProducer producer( brokerURI, numMessages, useTopics );
HelloWorldConsumer consumer( brokerURI, numMessages, useTopics, sessionTransacted );
// Start the consumer thread.
Thread consumerThread( &consumer );
consumerThread.start();
// Wait for the consumer to indicate that its ready to go.
consumer.waitUntilReady();
// Start the producer thread.
Thread producerThread( &producer );
producerThread.start();
// Wait for the threads to complete.
producerThread.join();
consumerThread.join();
long long endTime = Date::getCurrentTimeMilliseconds();
double totalTime = (endTime - startTime) / 1000.0;
std::cout << "Time to completion = " << totalTime << " seconds." << std::endl;
std::cout << "-----------------------------------------------------/n";
std::cout << "Finished with the example." << std::endl;
std::cout << "=====================================================/n";
}
// END SNIPPET: demo
篇幅有点多,当然了编译之前要配置几样东东,activemq include 在C++ comiler里边配置,在C++Linker里边配置类库,如果想再配个fopenmp之类的也在这两个地方添加就OK了。
5.检验一下效果
essage #463 Received: Hello world! from thread -1239528560
Message #464 Received: Hello world! from thread -1239528560
Message #465 Received: Hello world! from thread -1239528560
Message #466 Received: Hello world! from thread -1239528560
Message #467 Received: Hello world! from thread -1239528560
Message #468 Received: Hello world! from thread -1239528560
Message #469 Received: Hello world! from thread -1239528560
Message #470 Received: Hello world! from thread -1239528560
Message #471 Received: Hello world! from thread -1239528560
Message #472 Received: Hello world! from thread -1239528560
Message #473 Received: Hello world! from thread -1239528560
Message #474 Received: Hello world! from thread -1239528560
Message #475 Received: Hello world! from thread -1239528560
Message #476 Received: Hello world! from thread -1239528560
Message #477 Received: Hello world! from thread -1239528560
Message #478 Received: Hello world! from thread -1239528560
Message #479 Received: Hello world! from thread -1239528560
Message #480 Received: Hello world! from thread -1239528560
Message #481 Received: Hello world! from thread -1239528560
Message #482 Received: Hello world! from thread -1239528560
Message #483 Received: Hello world! from thread -1239528560
Message #484 Received: Hello world! from thread -1239528560
Message #485 Received: Hello world! from thread -1239528560
Message #486 Received: Hello world! from thread -1239528560
Message #487 Received: Hello world! from thread -1239528560
Message #488 Received: Hello world! from thread -1239528560
Message #489 Received: Hello world! from thread -1239528560
Message #490 Received: Hello world! from thread -1239528560
Message #491 Received: Hello world! from thread -1239528560
Message #492 Received: Hello world! from thread -1239528560
Message #493 Received: Hello world! from thread -1239528560
Message #494 Received: Hello world! from thread -1239528560
Message #495 Received: Hello world! from thread -1239528560
Message #496 Received: Hello world! from thread -1239528560
Message #497 Received: Hello world! from thread -1239528560
Message #498 Received: Hello world! from thread -1239528560
Message #499 Received: Hello world! from thread -1239528560
Message #500 Received: Hello world! from thread -1239528560
Message #501 Received: Hello world! from thread -1239528560
Message #502 Received: Hello world! from thread -1239528560
Message #503 Received: Hello world! from thread -1239528560
Message #504 Received: Hello world! from thread -1239528560
Message #505 Received: Hello world! from thread -1239528560
Message #506 Received: Hello world! from thread -1239528560
Message #507 Received: Hello world! from thread -1239528560
Message #508 Received: Hello world! from thread -1239528560
Message #509 Received: Hello world! from thread -1239528560
Message #510 Received: Hello world! from thread -1239528560
Message #511 Received: Hello world! from thread -1239528560
Message #512 Received: Hello world! from thread -1239528560
Message #513 Received: Hello world! from thread -1239528560
Message #514 Received: Hello world! from thread -1239528560
Message #515 Received: Hello world! from thread -1239528560
Message #516 Received: Hello world! from thread -1239528560
Message #517 Received: Hello world! from thread -1239528560
Message #518 Received: Hello world! from thread -1239528560
Message #519 Received: Hello world! from thread -1239528560
Message #520 Received: Hello world! from thread -1239528560
Message #521 Received: Hello world! from thread -1239528560
Message #522 Received: Hello world! from thread -1239528560
Message #523 Received: Hello world! from thread -1239528560
Message #524 Received: Hello world! from thread -1239528560
Message #525 Received: Hello world! from thread -1239528560
Message #526 Received: Hello world! from thread -1239528560
Message #527 Received: Hello world! from thread -1239528560
Message #528 Received: Hello world! from thread -1239528560
Message #529 Received: Hello world! from thread -1239528560
Message #530 Received: Hello world! from thread -1239528560
Message #531 Received: Hello world! from thread -1239528560
Message #532 Received: Hello world! from thread -1239528560
Message #533 Received: Hello world! from thread -1239528560
Message #534 Received: Hello world! from thread -1239528560
Message #535 Received: Hello world! from thread -1239528560
Message #536 Received: Hello world! from thread -1239528560
Message #537 Received: Hello world! from thread -1239528560
Message #538 Received: Hello world! from thread -1239528560
Message #539 Received: Hello world! from thread -1239528560
Message #540 Received: Hello world! from thread -1239528560
Message #541 Received: Hello world! from thread -1239528560
Message #542 Received: Hello world! from thread -1239528560