CMS (C++ 消息服务)是一个面象apache activemq的消息中间层的C++接口。ActiveMQ-CPP是CMS的实现,不过当前只支持 openwire、amqp、TCP、ssl。 现在还支持主备切换功能。通过使用ActiveMQ-CPP提供的接口,我们可以使用多种协议来与消息中间件进行通信。下面的内容是在CentOS 7 x64(Linux)环境下搭建基本的ActiveMQ-CPP的开发环境,由于系统的基础环境的差异,该教程仅供参考。
一、基础环境
ActiveMQ-CPP开发环境需要如下依赖,但是由于操作系统环境的差异,实际上可能不全,需根据实际情况增加依赖。
TOOL | Recommended Version |
---|---|
autoconf | >= 2.61 |
automake | >= 1.10 |
libtool | >= 1.5.24 |
CPPUnit | 1.12.1 |
apr | 1.7.0 |
apr-iconv | 1.2.2 |
apr-util | 1.6.1 |
OpenSSL | 1.1.1d |
ActiveMQ-CPP | 3.9.5 |
对于autoconf、automake、libtool我们可以直接安装:
yum -y install autoconf
yum -y install automake
yum -y install libtool
CPPUnit
tar解压后,进入目录,编译三部曲,configure、make、make install(install需要root权限):
./configure --prefix=/usr/local/cppunit
make
make install
执行完后在/usr/local/cppunit/目录下可以看到头文件和库文件。
APR
同上,解压进入目录,三部曲:
./configure --prefix=/usr/local/apr
make
make install
apr-iconv
解压编译:
./configure --prefix=/usr/local/apriconv --with-apr=/usr/local/apr
make
make install
apr-util
解压编译:
./configure --prefix=/usr/local/aprutil --with-apr=/usr/local/apr
make
make install
openssl
解压编译:
./config --prefix=/usr/local/openssl
make
make install
ActiveMQ-CPP
解压编译:
./configure --prefix=/usr/local/activemq-cpp --with-apr=/usr/local/apr --with-apr-iconv=/usr/local/apriconv --with-apr-util=/usr/local/aprutil --with-cppunit=/usr/local/cppunit --with-openssl=/usr/local/openssl
make
make install
若在make时报错,提示找不到ssl库
/usr/bin/ld: cannot find -lssl
进入到 /usr/local/openssl目录,将lib64目录复制一份,复制的新目录名为lib,命令:cp -r lib64 lib,这是由于make时使用的 /usr/local/openssl/lib路径导致。
二、测试程序
到这里ActiveMQ-CPP的基本环境就搭建完成了,在/usr/local目录下生成了6个目录,分别为activemq-cpp、apr、apr-iconv、aprutil、cppunit、openssl。
下面编写一段测试代码(test.cpp),用于检测cms开发库是否可用。
#include <activemq/library/ActiveMQCPP.h>
#include <decaf/lang/Thread.h>
#include <decaf/lang/Runnable.h>
#include <decaf/util/concurrent/CountDownLatch.h>
#include <decaf/lang/Integer.h>
#include <decaf/lang/Long.h>
#include <decaf/lang/System.h>
#include <activemq/core/ActiveMQConnectionFactory.h>
#include <activemq/util/Config.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::core;
using namespace decaf::util::concurrent;
using namespace decaf::util;
using namespace decaf::lang;
using namespace cms;
using namespace std;
int main()
{
activemq::library::ActiveMQCPP::initializeLibrary();
Connection* conn;
Session* sess;
Destination* dest;
MessageProducer* producer;
std::string brokerurl("failover:(tcp://127.0.0.1:61616)");
try
{
auto_ptr<ConnectionFactory> connFactory(ConnectionFactory::createCMSConnectionFactory(brokerurl));
conn = connFactory->createConnection();
conn->start();
sess = conn->createSession(Session::AUTO_ACKNOWLEDGE);
dest = sess->createQueue("QueueFromLinuxTest");
producer = sess->createProducer(dest);
producer->setDeliveryMode(DeliveryMode::NON_PERSISTENT);
string text("Hello ActiveMQ from LinuxTest");
for (int i = 0; i < 3; ++i)
{
TextMessage* msg = sess->createTextMessage(text);
msg->setIntProperty("IntProp1", i);
producer->send(msg);
cout << "SEND-> " << text << endl;
delete msg;
}
}
catch (CMSException& e)
{
e.printStackTrace();
}
try {
delete dest;
dest = NULL;
delete producer;
producer = NULL;
if (NULL != sess)
sess->close();
if (NULL != conn)
conn->close();
delete sess;
sess = NULL;
delete conn;
conn = NULL;
}
catch (CMSException& e)
{
e.printStackTrace();
}
cout << "test end" << endl;
activemq::library::ActiveMQCPP::shutdownLibrary();
}
编译命令:运行时,需要将/usr/local/activemq-cpp/lib下的libactivemq-cpp.so、libactivemq-cpp.so.19、libactivemq-cpp.so.19.0.5这3个,以及/usr/local/openssl/lib下的libssl.so.1.1以及libcrypto.so.1.1复制到/usr/lib64目录下。
g++ test.cpp -I /usr/local/activemq-cpp/include/activemq-cpp-3.9.5 -I /usr/local/apr/include/apr-1 -L /usr/local/openssl/lib -l ssl -l crypto -L /usr/local/activemq-cpp/lib -l activemq-cpp
gcc/g++的编译参数,这里只介绍 -L 、-l、-include、-I。
-L :表示要链接的库所在的目录。-L. 表示要链接的库在当前目录, -L/usr/lib 表示要连接的库在/usr/lib下。目录在/usr/lib时,系统会自动搜索这个目录,可以不用指明。
-l (L的小写):表示需要链接库的名称,注意不是库文件名称,比如库文件为 libtest.so,那么库名称为test
-include :包含头文件,这个很少用,因为一般情况下在源码中,都有指定头文件。
-I (i 的大写):指定头文件的所在的目录,可以使用相对路径。