ActiveMQ C++ tutorial

C++调用ActiveMQ C++客户端调用ActiveMQ动态库 阅读详情

说明[编辑]

 本文会结合一个例子简要的说明activemq的c++客户端的使用方法

Apache ActiveMQ简介[编辑]

 Apache ActiveMQ是一个开源的消息服务器,实现了JMS规范,支持多语言客户端和协议。

ActiveMQ-CPP[编辑]

 ActiveMQ-CPP是c++客户端,目前支持 OpenWire and Stomp协议,两者都可以通过TCP和SSL,目前支持failover

JMS简介[编辑]

 说明:本段内容主要摘自《ActiveMQ in Action》一书
什么是消息中间件(Message-Oriented Middleware, MOM)?[编辑]
 MOM是一组中间件,用来构建分布式系统,它的特性包括:异步,松耦合,可靠,安全和可扩展等等。发送者和接收者进行异步通讯,发送者只需要把消息发送到MOM,不需要知道谁是接收者,MOM保证消息的送达;同样的,接收者也不需要关心发送者。
什么是JMS[编辑]
 在JMS出现之前,出现了很多MOM,它们各自采用自己的协议通讯,这就导致客户端代码与特定的MOM绑定。如果要切换到其它的MOM,那么需要重写客户端代码。因此Sun联合了很多MOM的提供商制定了一套Java的API规范,所有与之兼容的实现都必须实现这个API。
 这样客户端代码不需要任何修改就可以从一个MOM移植到另外一个MOM(前提当然是只使用标准JMS的API,如果你使用了某个MOM特殊的feature,那么就没法保证移植)。最早的版本是1998年完成的1.0,之后2002年修订出了1.1,这个版本是目前最流行的版本。
 2013年发布了最新的2.0版,不过目前ActiveMQ还未支持。
JMS基本概念[编辑]
Producer[编辑]
 消息发送者
Consumer[编辑]
 消息接收者
JMS Provider[编辑]
 JMS的实现者,比如ActiveMQ
Message[编辑]

消息包括消息头(Header)和内容 1. 头部包括JMS标准定义的header和用户自定义的属性(Property)

  有些头部是客户端代码的send方法自动设置的,比如:
  1.1 JMSDestination
       消息发送的地方,比如一个队列。
  1.2 JMSDeliveryMode
       Persistent -- 这样的消息会持久化到磁盘,即使ActiveMQ挂掉也不会丢失消息。
       Nonpersistent 非持久化,性能更快,但是有丢消息的风险。
  1.3 JMSExpiration
       可以通过MessageProducer.setTimeToLive() 来设置消息的TTL,如果消息超过TTL还没被消费,那么就会被丢弃。
  1.4 JMSMessageID 
       唯一ID
  1.5 JMSPriority
       消息优先级,0-4是普通优先级,5-9是高优先级。JMS规范并没有强制JMS Provider实现优先级,但大部分Provider都实现了。参考ActiveMQ的优先级
  有些头部是可选的:
  1.6 JMSCorrelationID 
       这个头部经常用来把响应消息和请求消息关联起来,比如请求者发送一个消息(比如有一个唯一的JMSMessageID=req001),响应者处理完这个消息后生成一条响应消息,把JMSCorrelationID设置成req001,那么请求者就可以从响应队列中筛选出
       自己的响应。
  1.7 JMSReplyTo 
       这个头部一般也用于请求响应,并且提示响应者把响应发送到指定的JMSDestination。注意,这只是一个提示,响应者完全可以不理会,而把响应发到其它的地方。
       【注:为什么需要JMSReplyTo?对于有些请求响应任务,比如P2P的,我们可以在请求者和响应者之间约定,比如请求者把请求发送到名称为”request“的队列,响应者把响应发送的”response“的队列,然后双方通过JSMCorrelationID唯一标识
            一对请求/响应。但有的情况,比如请求者不一定自己接受消息,它可能让别人接收消息,那么它可以知道JMSReplyTo】
  1.8 JMSType
       消息的类型,指定消息是什么类型的,比如是个字符串,比如是个整数。注意:JMS规范没有规定JMSType一定和实际内容匹配,有可能JMSType和实际内容不符合。
  还有一下头部是非规范的,有些JMS Provider提供了,有些没有。
  1.9 JMSRedelivered
       告诉消费者,这个消息是一个重发的消息,比如某个消息发送给了一个消费者,但是在它确认之前这个消费者挂了,那么这个消息就可能发送给其它的消费者。这个头部提醒消费者如果操作不是幂等的,那么就要注意。比如消费者的操作是把某个全局计数器
       加1,如果这个消息先发给消费者1,它成功加1,然后还没确认就挂了,然后这个消息重发给消费者2,它又加1,那么就出现错误。
  
  消息头可以用来筛选消息,比如我需要JMSCorrelationID等于某个值的消息。但是没有办法根据消息内容来筛选消息。具体参考:此页面的Message Selectors部分

2. 消息内容(Body)就是实际的内容

  JMS定义了:
  2.1 Message 
       无任何内容,可以设置头部。一般用于事件通知。
  2.2 TextMessage 
       字符串
  2.3 MapMessage 
       Java Map,Key是String,value是java原始类型,比如int,float,也可以是字符串。
  2.4 BytesMessage 
       字节数组,具体意义需要双方约定。【对于不同语言的通讯,使用这个很合适,比如使用Protobuf,Java消息发送者把消息内容变成字节数组,c++消息接收者把字节数组反序列化成对象】
  2.5 StreamMessage
       Java.io.InputStream/OutputStream
  2.6 ObjectMessage
       负责的Java对象,需要实现java.io.serializable。由于Java的序列化很臃肿,所以效率不高,但是跨平台(双方都是java),对象直接有复杂的循环引用关系(对应c++的术语是Deep Copy)也能正确处理。
JMS客户端基本概念[编辑]
JMSConnection[编辑]
  代表一个客户端到JSM Provider的连接,一般包括一个TCP的socket,因此比较”重“,建议同一个进程的不同线程共用一个Connection(使用一个Connection创建出不同的session)。当然如果你觉得一个Socket不能发挥网络的性能,那么可以
  多使用一些Connection,比如每10个线程共用一个Connection
Session[编辑]
  一个”会话“,不是线程安全的,因此每个线程都必须有自己的Session,一般通过Connection创建出来
Destination[编辑]
  目的地,比如某个队列,一般通过session来创建或者获得
Producer[编辑]
  生产者,我们这里只介绍P2P的模式,所以可以等价为消息发送者(Sender)
Consumer[编辑]
  消费者,我们这里只关心P2P的模式,所以可以等价为消息接收者(Receiver)
CMS ActiveMQ的c++客户端[编辑]

具体请阅读文档 我这里只是介绍一下安装编译和运行一个简单的例子

Build[编辑]

具体参考文档,我这里只是介绍我的环境(Ubuntu)的安装,其它*nix应该是类似,依赖可以使用包管理器安装,比如debian和yum/rpm,如果没有可以从源代码按照。其他系统比如Windows请参考文档。 1. 下载并解压源代码

   请在这里下载最新版本,我这里使用的是3.8.2
   我的源代码解压到/home/lili/soft/activemq-cpp-library-3.8.2/,以后用环境变量$ACTIVEMQ-CPP表示

2. 依赖

   2.1 libuuid
      直接 apt-get install
   2.2 CppUnit
      直接 apt-get install
   2.3 APR
      我下载1.5.0的源代码并且使用了默认的安装流程:./configure && make && sudo make install【由于默认的会把lib放到/usr/lib下所以需要root权限】,如果你没有root权限,./configure --prefix=/some/path

3. 编译

   3.1 生产configure脚本
      ./autogen.sh
   3.2 ./configure
   3.3 make 如果cpu较多,可以用make -j4加速
   3.4 make install
简单的Sender的例子[编辑]

1. 头文件

  需要引用 $ACTIVEMQ-CPP/src/main,比如在gcc下是 -I/home/lili/soft/activemq-cpp-library-3.8.2/src/main

2. 链接

  需要链接activemq-cpp库,比如在gcc下是 -lactivemq-cpp,如果so不在标准搜索路径下,可能要-L指定动态库的所在目录。

3. 运行

  如果找不到动态库,可能需要增加环境变量 LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/lib,因为我的系统默认安装到/usr/local/lib下了,运行时却不会去这里找。

4. 源代码

  我这里使用的是linux35上的一个activemq,你也可以自己安装activemq
  核心的代码其实非常少,都在run函数里面
/*
 * 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.
 */

#include <decaf/lang/Thread.h>
#include <decaf/lang/Runnable.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 <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;
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 Runnable {
private:

    Connection* connection;
    Session* session;
    Destination* destination;
    MessageProducer* producer;
    bool useTopic;
    bool clientAck;
    unsigned int numMessages;
    std::string brokerURI;
    std::string destURI;

private:

    SimpleProducer( const SimpleProducer& );
    SimpleProducer& operator= ( const SimpleProducer& );

public:

    SimpleProducer( const std::string& brokerURI, unsigned int numMessages,
                    const std::string& destURI, bool useTopic = false, bool clientAck = false ) :
        connection(NULL),
        session(NULL),
        destination(NULL),
        producer(NULL),
        useTopic(useTopic),
        clientAck(clientAck),
        numMessages(numMessages),
        brokerURI(brokerURI),
        destURI(destURI) {
    }

    virtual ~SimpleProducer(){
        cleanup();
    }

    void close() {
        this->cleanup();
    }

    virtual void run() {
        try {

            // Create a ConnectionFactory
            auto_ptr<ActiveMQConnectionFactory> connectionFactory(
                new ActiveMQConnectionFactory( brokerURI ) );

            // Create a Connection
            try{
                connection = connectionFactory->createConnection();
                connection->start();
            } catch( CMSException& e ) {
                e.printStackTrace();
                throw e;
            }

            // 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 );

            // Create the Thread Id String
            string threadIdStr = Long::toString( Thread::currentThread()->getId() );

            // Create a messages
            string text = (string)"Hello world! from thread " + threadIdStr;

            for( unsigned 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;
    }
};

////////////////////////////////////////////////////////////////////////////////
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 IPAddress 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 =
        "failover://(tcp://linux35:61616"
//        "?wireFormat=openwire"
//        "&connection.useAsyncSend=true"
//        "&transport.commandTracingEnabled=true"
//        "&transport.tcpTracingEnabled=true"
//        "&wireFormat.tightEncodingEnabled=true"
        ")";

    //============================================================
    // Total number of messages for this producer to send.
    //============================================================
    unsigned int numMessages = 2000;

    //============================================================
    // This is the Destination Name and URI options.  Use this to
    // customize where the Producer produces, to have the producer
    // use a topic or queue set the 'useTopics' flag.
    //============================================================
    std::string destURI = "TEST.FOO";

    //============================================================
    // set to true to use topics instead of queues
    // Note in the code above that this causes createTopic or
    // createQueue to be used in the producer.
    //============================================================
    bool useTopics = false;

    // Create the producer and run it.
    SimpleProducer producer( brokerURI, numMessages, destURI, useTopics );

    // Publish the given number of Messages
    producer.run();

    // Before exiting we ensure that all CMS resources are closed.
    producer.close();

    std::cout << "-----------------------------------------------------\n";
    std::cout << "Finished with the example." << std::endl;
    std::cout << "=====================================================\n";

    activemq::library::ActiveMQCPP::shutdownLibrary();
}
简单的Receiver的例子[编辑]

编译配置参考上面 本例使用的onMessage的回掉函数,也就是通过consumer->setMessageListener( this );告诉客户端lib,如果有消息就调用this.onMessage。 this(SimpleAsyncConsumer需要继承MessageListener。这种方式是异步的,当然也可以使用简单的同步方法。请参考$ACTIVEMQ-CPP/src/examples里的更多例子。

/*
 * 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.
 */

#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 {
private:

    Connection* connection;
    Session* session;
    Destination* destination;
    MessageConsumer* consumer;
    bool useTopic;
    std::string brokerURI;
    std::string destURI;
    bool clientAck;

private:

    SimpleAsyncConsumer( const SimpleAsyncConsumer& );
    SimpleAsyncConsumer& operator= ( const SimpleAsyncConsumer& );

public:

    SimpleAsyncConsumer( const std::string& brokerURI,
                         const std::string& destURI,
                         bool useTopic = false,
                         bool clientAck = false ) :
        connection(NULL),
        session(NULL),
        destination(NULL),
        consumer(NULL),
        useTopic(useTopic),
        brokerURI(brokerURI),
        destURI(destURI),
        clientAck(clientAck) {
    }

    virtual ~SimpleAsyncConsumer() {
        this->cleanup();
    }

    void close() {
        this->cleanup();
    }

    void runConsumer() {

        try {

            // Create a ConnectionFactory
            ActiveMQConnectionFactory* connectionFactory =
                new ActiveMQConnectionFactory( brokerURI );

            // Create a Connection
            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) {
            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!";
            }

            if( clientAck ) {
                message->acknowledge();
            }

            printf( "Message #%d Received: %s\n", count, text.c_str() );
        } catch (CMSException& e) {
            e.printStackTrace();
        }
    }

    // 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);
    }

    virtual void transportInterrupted() {
        std::cout << "The Connection's Transport has been Interrupted." << std::endl;
    }

    virtual void transportResumed() {
        std::cout << "The Connection's Transport has been Restored." << std::endl;
    }

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) {}
        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;
    }
};

////////////////////////////////////////////////////////////////////////////////
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 IPAddress 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 =
        "failover:(tcp://linux35:61616"
//        "?wireFormat=openwire"
//        "&connection.useAsyncSend=true"
//        "&transport.commandTracingEnabled=true"
//        "&transport.tcpTracingEnabled=true"
//        "&wireFormat.tightEncodingEnabled=true"
        ")";

    //============================================================
    // This is the Destination Name and URI options.  Use this to
    // customize where the consumer listens, to have the consumer
    // use a topic or queue set the 'useTopics' flag.
    //============================================================
    std::string destURI = "TEST.FOO?consumer.prefetchSize=1";

    //============================================================
    // set to true to use topics instead of queues
    // Note in the code above that this causes createTopic or
    // createQueue to be used in the consumer.
    //============================================================
    bool useTopics = false;

    //============================================================
    // set to true if you want the consumer to use client ack mode
    // instead of the default auto ack mode.
    //============================================================
    bool clientAck = false;

    // Create the consumer
    SimpleAsyncConsumer consumer( brokerURI, destURI, useTopics, clientAck );

    // Start it up and it will listen forever.
    consumer.runConsumer();

    // Wait to exit.
    std::cout << "Press 'q' to quit" << std::endl;
    while( std::cin.get() != 'q') {}

    // All CMS resources should be closed before the library is shutdown.
    consumer.close();

    std::cout << "-----------------------------------------------------\n";
    std::cout << "Finished with the example." << std::endl;
    std::cout << "=====================================================\n";

    activemq::library::ActiveMQCPP::shutdownLibrary();
}

参考文献[编辑]

  1. ActiveMQ首页
  2. ActiveMQ-CPP首页
  3. JMS 1.1
  4. JMS 2.0
  5. JMS 2.0新feature Part1
  6. JMS 2.0新feature Part2
Linux 下的 ActiveMQ C++ 客户端开发 本文主要针对 CentOS 7 x64(Linux)环境 ActiveMQ CPP 的编译及客户端开发 阅读详情

相关推荐

ActiveMQ-CPP安装与使用指南

通过阅读ActiveMQ-CPP的官方文档,你可以进一步扩展和优化你的应用程序。首先,你需要从ActiveMQ官方网站(https://activemq.apache.org/activemq-cpp)下载ActiveMQ-CPP的最新版本。ActiveMQ-CPP是一个功能强大的C++消息队列库,它提供了与ActiveMQ消息代理交互的接口。以上示例代码创建了一个生产者和一个消费者,它们都连接到本地ActiveMQ代理,并在名为"myQueue"的队列中发送和接收消息。第三步:编译和运行示例代码。

cl6789的博客 266

Windows下实现C++ 连接ActiveMQ

文章目录1.什么是ActiveMQ?2.能用来做什么?3. 支持的消息类型4.本地安装ActiveMQ服务4.1 下载地址4.2 启动4.3 配置文件activemq.xml5.C++实现连接ActiveMQ5.1 下载相关接口5.2 编译5.2.1 编译activemq-cpp工程5.2.2 编译libapr工程生成libapr-1.lib和libapr-1.dll库5.2.3 编译activemq-cpp.example例子工程,运行例子 1.什么是ActiveMQ? ActiveMQ是Apache软件

lsl-做一个优秀的人 5862

ActiveMQ-CPP客户端库在VS2010中的编译和使用指南

Apache ActiveMQ是一个开源的消息代理服务器,实现了Java消息服务(JMS)规范,为不同应用程序之间提供可靠的异步通信。作为企业级消息服务的领先解决方案,它支持多种语言的客户端访问,并且可以在各种平台和操作系统上运行。版本3.9.4新增了多个功能,其中最受开发者关注的包括对SSL/TLS的支持、性能的提升、以及对多种网络协议的改进。SSL/TLS的支持使得ActiveMQ-CPP在安全性方面更上一层楼,能够保证客户端和服务器之间的通信安全。

weixin_35756624的博客 721

linux C++ 环境下的ActiveMQ学习

ActiveMQ 1.概述 ActiveMQ 是Apache出品,最流行的、功能强大的即时通讯和集成模式的开源服务器。ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现。提供客户端支持跨语言和协议,带有易于在充分支持JMS 1.1和1.4使用J2EE企业集成模式和许多先进的功能。 2.特点 2.⒈ 多种语言和协议编写客户端。语言: Java,...

更与何人说♫ 1379

ActiveMQ完整的C++源码

包括ActiveMQ、CPPUnit、APR、APR-iconv、APR-util四个编译ActiveMQ必须的包,省得一个一个去下载了。 开发具体例子参考下面的链接 http://blog.sina.com.cn/s/blog_a459dcf501017ooh.html 配置和简单的例子参考下面的链接 http://blog.youkuaiyun.com/lee353086/article/details/6777261 感谢kagula和邵明提供上面的链接例子

ActiveMQ-CPP在vs2017上测试通过

ActiveMQ-CPP在vs2017上测试通过,测试时间 2018年12月30日

C++连接activemq遇到的坑

近期和甲方对接,要求使用activemq, 只给了对接的IP、端口、队列、用户名、密码的信息。但是过程还是很曲折的。建议用比较干净的机器搭建, 一些加域的机器最好不要用,如何搭建MQ和如何安装JAVA环境,参考下面的两个连接。1、activmq 使用C++连接有两种方式, 第一种是stomp, 第二种是activemq的开源库。例子的代码都是封装继承了Therad, 需要利用线程运行,如何调用,线程都已经规划好。stomp默认的端口是61613, 开源库是61616. 而甲方提供的说61616,

问渠哪得清如许 404

ActiveMQ C++ Windows客户端 3.8.3例子代码(含头文件和编译出来的dll和lib)

activemq的最新的CMS客户端代码是3.8.3,由于在windows下编译比较麻烦,遍寻网络不获,所以自己仔细研究了一下,终于编译成功,分享给大家。附件中的例子工程在vs2010下编译通过。如果需要移植到自己的工程里,仅需要把include和lib两个目录复制到自己的工程下,然后进行相应配置即可。ps:需要在自己的工程里把那几个lib文件配置到链接——输入里(大概有六七个就行了,具体可参考网上其他朋友的文档)。对了,本例子只是制作了release版本,debug没做,所以,debug的不能run哦。如果有自己想改cms源码的话,我想,那些大拿自己编译出来是没有问题的,也就不需要参考偶的拙劣之作了 顺祝大家工作顺利!

c++ ActiveMQ

在C++中使用ActiveMQ,你可以使用库,这是一个ActiveMQ的C++客户端实现。下面是一个简单的步骤说明,用于在C++项目中设置和使用。

xie__jin__cheng的博客 604

MATLAB自动驾驶(1)——预构建场景库

MATLAB自动驾驶(1)——预构建场景库

Ucicorn Gundam的博客 3265

Arm CCA架构:硬件级机密计算与安全隔离技术解析

机密计算(Confidential Computing)通过硬件级隔离技术构建可信执行环境(TEE),是当前云安全和数据隐私保护的核心方案。Armv9-A引入的CCA架构采用物理地址空间隔离和Granule保护表(GPT)机制,实现4KB颗粒度的内存访问控制。该技术通过标准化的RMI/RSI接口规范,为虚拟化环境和安全敏感应用提供硬件级保护,特别适用于金融交易、医疗数据处理等需要严格隔离的场景。相比传统TEE方案,Arm CCA在隔离等级和动态权限管理方面具有显著优势,其Realm World设计为机密计算

weixin_30905133的博客 565

Mqtt开发笔记:Mqtt服务器搭建

使用到mqtt服务器(中间件)。

长沙红胖子 Qt・西安|省级科研团队从业背景,深耕双一流体系高精尖技术配套研发|剥离高精尖机理,沉淀高端特种行业领域 Qt 工程化落地经验|博文仅分享通用技术总结,输出公开普适工程思路。 6万+

YOLOv8知识蒸馏实战:用BCKD和LD在自制数据集上分别提点1.63%和1.69%的保姆级教程

本文详细介绍了在YOLOv8模型上应用知识蒸馏技术(BCKD和LD方法)的实战教程,通过自制数据集实现性能提升1.63%和1.69%。内容涵盖环境配置、模型选择、BCKD和LD的具体实现及调参技巧,适合目标检测领域的开发者和研究者。

weixin_29082143的博客 245

使用ActiveMQ进行C++与C#的通信1 - ActiveMQ入门

该系列文章介绍如何通过ActiveMQ在C++和C#控制台项目之间通信。 关于ActiveMQ的介绍可以参考《深入浅出ActiveMQ》,平台搭建可以参考《Activemq 平台搭建与C#示列》,两者之间有交叉内容,这里我以ActiveMQ之user-guide翻译为开篇,如有纰漏、错误敬请指正。

pigautumn的专栏 1858

Android Studio运行报错: failed to load include path ……\platforms\android-35\android.jar的最细解决方案

【代码】Android Studio运行报错: failed to load include path ……\platforms\android-35\android.jar的最细解决方案。

2401_86789230的博客 2万+

STM32F103C8T6 Bootloader开发实战:串口IAP固件升级与Keil工程配置详解

本文详细介绍了STM32F103C8T6 Bootloader开发实战,重点讲解串口IAP固件升级的实现方法与Keil uVision5工程配置。通过Flash分区管理、USART1通信协议设计及应用程序跳转机制等核心技术,帮助开发者掌握嵌入式系统固件升级方案,提升设备维护效率。

weixin_29165725的博客 436

activeMq-CPP的使用

activeMq-CPP应用程序demo author: 陈训 一、avtiveMq服务端的安装 1、从官网获取软件包: 网址:http://activemq.apache.org/activemq-590-release.html 2、解压运行activeMq wget   http://archive.apache.org/dist/activemq/apache-active

chen 1万+

VMware ubuntu虚拟机(或Centos7)与主机共享文件夹

系统环境 Windows 10 Vmware Workstation 15 Pro Ubuntu 20.04.1 LTS centos7 1.Ubuntu配置共享文件 1.1安装VMware-tools 更新最新VMware-tools组件 编辑->首选项->更新->立即下载所有组件 安装VMware-tools 虚拟机->安装VMware-tools 安装后ubuntu会加载一个虚拟光驱,解压文件,在解压的文件目录下执行以下命令进行安装 sudo vmware-instal

weixin_38924500的博客 2160

C++ ActiveMQ实现通讯

C++ ActiveMQ实现通讯完整版 简介 该博客收到一些反应,说教程不够明细操作的时候怎么都不行,特今日(2017年8月29日17点)进行博客修改,并将新demo一起附上,建议看看博客下面的“需要注意的地方”后在来编译demo! 所需的关联lib,dll,还有新实例demo都在下面这个附件里面,我的demo是用的vs2008编辑器。 新附件下载地址(如失效请联系):http://pan

lwcloud的博客 1万+

从Excel到Power Pivot:构建你的第一个商业智能分析模型

本文详细介绍了如何从Excel升级到Power Pivot,构建你的第一个商业智能分析模型。通过激活Power Pivot功能、导入数据、建立表关系、创建智能度量值以及打造交互式仪表盘,帮助用户高效处理百万行级别的数据,实现数据自动关联和动态分析,大幅提升商业决策效率。

weixin_30629653的博客 256

LeRobot 入门教程(二)强化学习训练及 SmolVLA 模型微调

本文介绍了LeRobot框架中基于人类在环的样本高效强化学习(HIL-SERL)工作流,包含真实机器人训练和模拟环境训练两大模块。在真实机器人部分,详细说明了从配置设置、工作空间边界确定、演示数据收集、奖励分类器训练到演员-学习者架构部署的全流程,并强调了人类干预的关键作用。同时介绍了适用于模拟训练的gym_hil环境及其配置使用方法。最后,文章提供了微调SmolVLA基础模型的指南,包括数据集收集、微调步骤和模型评估方法。该工作流实现了人机协作的高效强化学习,适用于各类机器人操作任务。

2506_90492529的博客 3896

Apache ActiveMQ C++ 库指南

Apache ActiveMQ C++ 库指南 1. 项目介绍 Apache ActiveMQ C++ 是一个消息库,它支持多种协议与消息中间件(如ActiveMQ)进行通信。这个库允许应用程序在分布式环境中发送和接收消息,实现解耦和异步处理。该项目遵循Apache软件基金会的Apache 2.0 许可证,并由广泛的社区贡献者维护。 2. 项目快速启动 环境准备 在Unix系统上构建和安装Acti...

gitblog_00928的博客 702

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

C++ ActiveMQ

点击打开链接搭建ActiveMq通讯步骤: 1:安装并运行activemq.bat批处理文件 首先下载apache-activemq-5.1.0-bin.zip压缩文件,官方下载地址:http://activemq.apache.org/download.html 在getting past releases中选择自己的版本 2:解压文件到本地目录下,找到bin目录下的active

u013474032的专栏 2938

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Active MQ C++实现通讯

Active MQ C++实现通讯 Kagula 2011-9-13 简介 在参考资料[2]的基础上介绍如何用C++调用Active MQ的客户端API。 环境:[1]Windows XP SP3 [2]Visual Studio 2008 SP1 阅读前提:[1]熟悉Microsoft Visual Studio下的C++编程 [2]熟悉《Active MQ使用》这篇文章中的...

webcenterol 531

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

c++ linux mq,Linux下activeMQ与c++客户端的部署与应用

activeMQ做为一个消息中间件,用于p2p或pub/sub模式的消息模型。此时业务上的客户端服务器都是客户端,而activeMQ做为服务器。1. 怎么使用?1. 以p2p模式为例,下载安装activeMQ,而后启动,而后运行。2. 编写客户端1做为消息生产者,发送消息到activeMQ。3. 编写客户端2做为消息消费者,从activeMQ接收消息。2. 安装activeMQ3. c++客户端开...

weixin_29214715的博客 359

C++ activemq CMS 学习笔记

很早前就仓促的接触过activemq,但当时太赶时间.后面发现activemq 需要了解的东西实在是太多了. 关于activemq 一直想起一遍文章.但也一直缺少自己的见解.或许是网上这些文章太多了.也可能是自己知识还不足够. 0,activemq-cpp 能解决什么问题. 实际应用就是让开发者能从多线程,多消息通信中解救出来.更多的关注应用逻辑...

weixin_34358365的博客 652
上一篇: ubuntu 11.10 upgrade to 12.04
fancyerII
博客等级 码龄23年 48粉丝 164原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值