在介紹ActiveMQ-CP以前,先介紹下CMS(C++ Messaging Service),CMS是C++程序與消息中間件進行通訊的一種標準接口,能夠經過CMS接口與相似ActiveMQ這樣的消息中間件進行通訊,它可以讓C++程序與消息中間件之間的交互更加優雅和便捷。html
ActiceMQ-CPP是CMS的一種實現,是一個可以與ActiveMQ進行通訊的C++客戶端庫,ActiveMQ-CPP的架構設計可以支持可插撥的傳輸協議和消息封裝格式,而且支持客戶端容量,可以與ActiveMQ高效和便捷地進行通訊,而且提供一系列跨平臺的類Java API的特性,如多線程處理、I/O、sockets等。linux
ActiveMQ-CPP的編譯依賴libuuid、apr、apr-util、apr-iconv、openssl幾個庫,若是須要跑CppUnit編寫的test,還依賴於cppunit,所以在安裝使用ActiveMQ-CPP以前,至少得安裝libuuid、apr、apr-util、apr-iconv、openssl幾個庫。apache
util-linux-ng在2.15.1版本之後,已經將libuuid做爲一部分包含進來,所以,只須要安裝util-linux-ng便可服務器
(1)查詢系統是否安裝util-linux-ng多線程
(2)若沒有安裝的話安裝正常流程:架構
下載異步
解壓socket
指定目錄安裝:./configure --without-ncurses --prefix=/usr/local/util-linux-ngui
編譯安裝:makespa
sudo make install
(1)下載apr:http://archive.apache.org/dist/apr/
(2)解壓
tar -xf apr-1.4.8.tar.gz
(3)配置apr源碼,並指定路徑
./configure --prefix=/usr/local/apr
(4)編譯安裝
make
sudo make install
(1)下載apr-iconv:http://archive.apache.org/dist/apr/
(2)解壓
tar -xf apr-iconv-1.2.1.tar.gz
(3)配置源碼,指定路徑/usr/local/apr-iconv,而且指定apr的安裝
./configure --prefix=/usr/local/apr-iconv --with-apr=/usr/local/apr
(4)編譯安裝
make
sudo make install
在安裝openssl的過程當中發現系統中已經安裝了openssl,查找安裝目錄:
lib的安裝目錄很重要,後面安裝ActiveMQ-CPP時須要
若系統中沒有安裝openssl,則按照正常流程安裝
(1)下載:openssl-1.0.1e.tar.gz
(2)解壓:tar -xf openssl-1.0.1e.tar.gz
(3)配置源碼,並指定路徑
./configure --prefix=/usr/local/openssl
(4)編譯安裝
make
sudo make install
(1)下載:http://activemq.apache.org/cms/activemq-cpp-381-release.html
(2)解壓
tar -xf activemq-cpp-library-3.8.1-src.tar.gz
(3)配置源碼,指定apr、openssl安裝路徑,以及ActiveMQ-CPP將要安裝的路徑
./configure --prefix=/usr/local/activemq-cpp --with-apr=/usr/local/apr/ --with-openssl=/usr/local/openssl
(4)編譯安裝
make
sudo make install
用戶用來建立到JMS提供者的鏈接的被管對象。JMS客戶經過可移植的接口訪問鏈接,這樣當下層的實現改變時,代碼不須要進行修改。 管理員
在JNDI名字空間中配置鏈接工廠,這樣,JMS客戶纔可以查找到它們。根據消息類型的不一樣,用戶將使用隊列鏈接工廠,或者主題鏈接工廠。
#ifndef _CMS_CONNECTIONFACTORY_H_ #define _CMS_CONNECTIONFACTORY_H_ #include <cms/Config.h> #include <cms/CMSException.h> #include <string> namespace cms { class Connection; class ExceptionListener; class MessageTransformer; class CMS_API ConnectionFactory { public: virtual ~ConnectionFactory(); virtual cms::Connection* createConnection() = 0; virtual cms::Connection* createConnection(const std::string& username, const std::string& password) = 0; virtual cms::Connection* createConnection(const std::string& username, const std::string& password, const std::string& clientId) = 0; virtual void setExceptionListener(cms::ExceptionListener* listener) = 0; virtual cms::ExceptionListener* getExceptionListener() const = 0; virtual void setMessageTransformer(cms::MessageTransformer* transformer) = 0; virtual cms::MessageTransformer* getMessageTransformer() const = 0; public: static cms::ConnectionFactory* createCMSConnectionFactory(const std::string& brokerURI); }; } #endif /*_CMS_CONNECTIONFACTORY_H_*/
鏈接表明了應用程序和消息服務器之間的通訊鏈路。在得到了鏈接工廠後,就能夠建立一個與JMS提供者的鏈接。根據不一樣的鏈接類型,鏈接容許用戶建立會話,以發送和接收隊列和主題到目標。
#ifndef _CMS_CONNECTION_H_ #define _CMS_CONNECTION_H_ #include <cms/Config.h> #include <cms/Startable.h> #include <cms/Stoppable.h> #include <cms/Closeable.h> #include <cms/Session.h> #include <cms/ConnectionMetaData.h> namespace cms { class ExceptionListener; class MessageTransformer; class CMS_API Connection : public Startable, public Stoppable, public Closeable { public: virtual ~Connection(); virtual void close() = 0; virtual const ConnectionMetaData* getMetaData() const = 0; virtual Session* createSession() = 0; virtual Session* createSession(Session::AcknowledgeMode ackMode) = 0; virtual std::string getClientID() const = 0; virtual void setClientID(const std::string& clientID) = 0; virtual ExceptionListener* getExceptionListener() const = 0; virtual void setExceptionListener(ExceptionListener* listener) = 0; virtual void setMessageTransformer(cms::MessageTransformer* transformer) = 0; virtual cms::MessageTransformer* getMessageTransformer() const = 0; }; } #endif /*_CMS_CONNECTION_H_*/
表示一個單線程的上下文,用於發送和接收消息。因爲會話是單線程的,因此消息是連續的,就是說消息是按照發送的順序一個一個接收的。會話的好處是它支持事務。若是用戶選擇了事務支持,會話上下文將保存一組消息,直到事務被提交才發送這些消息。在提交事務以前,用戶可使用回滾操做取消這些消息。一個會話容許用戶建立消息生產者來發送消息,建立消息消費者來接收消息。
namespace cms { class MessageTransformer; class CMS_API Session : public Closeable, public Startable, public Stoppable { public: enum AcknowledgeMode { AUTO_ACKNOWLEDGE, // 使用此確認模式,會話自動進行 DUPS_OK_ACKNOWLEDGE, CLIENT_ACKNOWLEDGE, SESSION_TRANSACTED, INDIVIDUAL_ACKNOWLEDGE }; public: virtual ~Session(); virtual void close() = 0; virtual void commit() = 0; virtual void rollback() = 0; virtual void recover() = 0; virtual MessageConsumer* createConsumer(const Destination* destination) = 0; virtual MessageConsumer* createConsumer(const Destination* destination, const std::string& selector) = 0; virtual MessageConsumer* createConsumer(const Destination* destination, const std::string& selector, bool noLocal) = 0; virtual MessageConsumer* createDurableConsumer(const Topic* destination, const std::string& name, const std::string& selector, bool noLocal = false) = 0; virtual MessageProducer* createProducer(const Destination* destination = NULL) = 0; virtual QueueBrowser* createBrowser(const cms::Queue* queue) = 0; virtual QueueBrowser* createBrowser(const cms::Queue* queue, const std::string& selector) = 0; virtual Queue* createQueue(const std::string& queueName) = 0; virtual Topic* createTopic(const std::string& topicName) = 0; virtual TemporaryQueue* createTemporaryQueue() = 0; virtual TemporaryTopic* createTemporaryTopic() = 0; virtual Message* createMessage() = 0; virtual BytesMessage* createBytesMessage() = 0; virtual BytesMessage* createBytesMessage(const unsigned char* bytes, int bytesSize) = 0; virtual StreamMessage* createStreamMessage() = 0; virtual TextMessage* createTextMessage() = 0; virtual TextMessage* createTextMessage(const std::string& text) = 0; virtual MapMessage* createMapMessage() = 0; virtual AcknowledgeMode getAcknowledgeMode() const = 0; virtual bool isTransacted() const = 0; virtual void unsubscribe(const std::string& name) = 0; virtual void setMessageTransformer(cms::MessageTransformer* transformer) = 0; virtual cms::MessageTransformer* getMessageTransformer() const = 0; }; } #endif /*_CMS_SESSION_H_*/
目標是一個包裝了消息目標標識符的被管對象,消息目標是指消息發佈和接收的地點,或者是隊列,或者是主題。JMS管理員建立這些對象,而後用戶經過JNDI發現它們。和鏈接工廠同樣,管理員能夠建立兩種類型的目標,點對點模型的隊列,以及發佈者/訂閱者模型的主題。
namespace cms { class CMS_API Destination { public: enum DestinationType { TOPIC, QUEUE, TEMPORARY_TOPIC, TEMPORARY_QUEUE }; public: virtual ~Destination(); virtual DestinationType getDestinationType() const = 0; virtual cms::Destination* clone() const = 0; virtual void copy(const cms::Destination& source) = 0; virtual bool equals(const cms::Destination& other) const = 0; virtual const CMSProperties& getCMSProperties() const = 0; }; }
由會話建立的對象,用於接收發送到目標的消息。消費者能夠同步地(阻塞模式),或異步(非阻塞)接收隊列和主題類型的消息。
namespace cms { class MessageTransformer; class CMS_API MessageConsumer : public Closeable, public Startable, public Stoppable { public: virtual ~MessageConsumer(); virtual Message* receive() = 0; virtual Message* receive(int millisecs) = 0; virtual Message* receiveNoWait() = 0; virtual void setMessageListener(MessageListener* listener) = 0; virtual MessageListener* getMessageListener() const = 0; virtual std::string getMessageSelector() const = 0; virtual void setMessageTransformer(cms::MessageTransformer* transformer) = 0; virtual cms::MessageTransformer* getMessageTransformer() const = 0; virtual void setMessageAvailableListener(cms::MessageAvailableListener* listener) = 0; virtual cms::MessageAvailableListener* getMessageAvailableListener() const = 0; }; }
由會話建立的對象,用於發送消息到目標。用戶能夠建立某個目標的發送者,也能夠建立一個通用的發送者,在發送消息時指定目標。
namespace cms { class MessageTransformer; class CMS_API MessageProducer : public Closeable { public: virtual ~MessageProducer(); virtual void send(Message* message) = 0; virtual void send(Message* message, AsyncCallback* onComplete) = 0; virtual void send(Message* message, int deliveryMode, int priority, long long timeToLive) = 0; virtual void send(Message* message, int deliveryMode, int priority, long long timeToLive, AsyncCallback* onComplete) = 0; virtual void send(const Destination* destination, Message* message) = 0; virtual void send(const Destination* destination, Message* message, AsyncCallback* onComplete) = 0; virtual void send(const Destination* destination, Message* message, int deliveryMode, int priority, long long timeToLive) = 0; virtual void send(const Destination* destination, Message* message, int deliveryMode, int priority, long long timeToLive, AsyncCallback* onComplete) = 0; virtual void setDeliveryMode(int mode) = 0; virtual int getDeliveryMode() const = 0; virtual void setDisableMessageID(bool value) = 0; virtual bool getDisableMessageID() const = 0; virtual void setDisableMessageTimeStamp(bool value) = 0; virtual bool getDisableMessageTimeStamp() const = 0; virtual void setPriority(int priority) = 0; virtual int getPriority() const = 0; virtual void setTimeToLive(long long time) = 0; virtual long long getTimeToLive() const = 0; virtual void setMessageTransformer(cms::MessageTransformer* transformer) = 0; virtual cms::MessageTransformer* getMessageTransformer() const = 0; }; }
是在消費者和生產者之間傳送的對象,也就是說從一個應用程序創送到另外一個應用程序。一個消息有三個主要部分:消息頭(必須):包含用於識別和爲消息尋找路由的操做設置。一組消息屬性(可選):包含額外的屬性,支持其餘提供者和用戶的兼容。能夠建立定製的字段和過濾器(消息選擇器)。一個消息體(可選):容許用戶建立五種類型的消息(文本消息,映射消息,字節消息,流消息和對象消息)。消息接口很是靈活,並提供了許多方式來定製消息的內容。
namespace cms { class CMS_API Message { public: static const int DEFAULT_DELIVERY_MODE; static const int DEFAULT_MSG_PRIORITY; static const long long DEFAULT_TIME_TO_LIVE; enum ValueType { NULL_TYPE = 0, BOOLEAN_TYPE = 1, BYTE_TYPE = 2, CHAR_TYPE = 3, SHORT_TYPE = 4, INTEGER_TYPE = 5, LONG_TYPE = 6, DOUBLE_TYPE = 7, FLOAT_TYPE = 8, STRING_TYPE = 9, BYTE_ARRAY_TYPE = 10, UNKNOWN_TYPE = 11 }; public: virtual ~Message(); virtual Message* clone() const = 0; virtual void acknowledge() const = 0; virtual void clearBody() = 0; virtual void clearProperties() = 0; virtual std::vector<std::string> getPropertyNames() const = 0; virtual bool propertyExists(const std::string& name) const = 0; virtual ValueType getPropertyValueType(const std::string& name) const = 0; virtual bool getBooleanProperty(const std::string& name) const = 0; virtual unsigned char getByteProperty(const std::string& name) const = 0; virtual double getDoubleProperty(const std::string& name) const = 0; virtual float getFloatProperty(const std::string& name) const = 0; virtual int getIntProperty(const std::string& name) const = 0; virtual long long getLongProperty(const std::string& name) const = 0; virtual short getShortProperty(const std::string& name) const = 0; virtual std::string getStringProperty(const std::string& name) const = 0; virtual void setBooleanProperty(const std::string& name, bool value) = 0; virtual void setByteProperty(const std::string& name, unsigned char value) = 0; virtual void setDoubleProperty(const std::string& name, double value) = 0; virtual void setFloatProperty(const std::string& name, float value) = 0; virtual void setIntProperty(const std::string& name, int value) = 0; virtual void setLongProperty(const std::string& name, long long value) = 0; virtual void setShortProperty(const std::string& name, short value) = 0; virtual void setStringProperty(const std::string& name, const std::string& value) = 0; virtual std::string getCMSCorrelationID() const = 0; virtual void setCMSCorrelationID(const std::string& correlationId) = 0; virtual int getCMSDeliveryMode() const = 0; virtual void setCMSDeliveryMode(int mode) = 0; virtual const Destination* getCMSDestination() const = 0; virtual void setCMSDestination(const Destination* destination) = 0; virtual long long getCMSExpiration() const = 0; virtual void setCMSExpiration(long long expireTime) = 0; virtual std::string getCMSMessageID() const = 0; virtual void setCMSMessageID(const std::string& id) = 0; virtual int getCMSPriority() const = 0; virtual void setCMSPriority(int priority) = 0; virtual bool getCMSRedelivered() const = 0; virtual void setCMSRedelivered(bool redelivered) = 0; virtual const cms::Destination* getCMSReplyTo() const = 0; virtual void setCMSReplyTo(const cms::Destination* destination) = 0; virtual long long getCMSTimestamp() const = 0; virtual void setCMSTimestamp(long long timeStamp) = 0; virtual std::string getCMSType() const = 0; virtual void setCMSType(const std::string& type) = 0; }; }