rocketmq-client-cpp-2.2.0-大部分功能接口测试成功例子(官网Demo)

以下是 rocketmq-client-cpp 的主要功能及其对应的 C++ 示例代码。每个功能都附带详细的解释,帮助你快速理解如何在实际项目中使用该库。

源文件准备

  • 编译,安装rocket-client-cpp
  • 在main.cpp添加文件common.h,并将附录"附录 官网 example 中 common.h"内容添加到common.h中
  • 添加对接测试Demo,即可成功运行

1. 消息生产

1.1 同步消息发送 SyncProducer.cpp
/*
 * 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 <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <condition_variable>
#include <iomanip>
#include <iostream>
#include <mutex>
#include <thread>

#include "common.h"

using namespace rocketmq;

std::atomic<bool> g_quit;
std::mutex g_mtx;
std::condition_variable g_finished;
TpsReportService g_tps;

void SyncProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* producer) {
  while (!g_quit.load()) {
    if (g_msgCount.load() <= 0) {
      std::unique_lock<std::mutex> lck(g_mtx);
      g_finished.notify_one();
    }
    MQMessage msg(info->topic,  // topic
                  "*",          // tag
                  info->body);  // body
    try {
      auto start = std::chrono::system_clock::now();
      SendResult sendResult = producer->send(msg, info->SelectUnactiveBroker);
      g_tps.Increment();
      --g_msgCount;
      auto end = std::chrono::system_clock::now();
      auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
      if (duration.count() >= 500) {
        std::cout << "send RT more than: " << duration.count() << " ms with msgid: " << sendResult.getMsgId() << endl;
      }
    } catch (const MQException& e) {
      std::cout << "send failed: " << std::endl;
    }
  }
}

int main(int argc, char* argv[]) {
  RocketmqSendAndConsumerArgs info;

#if 0
  if (!ParseArgs(argc, argv, &info)) {
    exit(-1);
  }
#else
    info.namesrv = "192.168.8.138:9876;192.168.8.139:9876";
    info.namesrv_domain = "";
    info.groupname = "please_rename_unique_group_name";
    info.topic = "TopicTest";
    info.body = "msgbody for test";
#endif
  PrintRocketmqSendAndConsumerArgs(info);
  DefaultMQProducer producer("please_rename_unique_group_name");
  producer.setNamesrvAddr(info.namesrv);
  producer.setNamesrvDomain(info.namesrv_domain);
  producer.setGroupName(info.groupname);
  producer.setInstanceName(info.groupname);
  producer.setSessionCredentials("mq acesskey", "mq secretkey", "ALIYUN");
  producer.setSendMsgTimeout(500);
  producer.setTcpTransportTryLockTimeout(1000);
  producer.setTcpTransportConnectTimeout(400);

  producer.start();
  std::vector<std::shared_ptr<std::thread>> work_pool;
  auto start = std::chrono::system_clock::now();
  int msgcount = g_msgCount.load();
  g_tps.start();

  int threadCount = info.thread_count;
  for (int j = 0; j < threadCount; j++) {
    std::shared_ptr<std::thread> th = std::make_shared<std::thread>(SyncProducerWorker, &info, &producer);
    work_pool.push_back(th);
  }

  {
    std::unique_lock<std::mutex> lck(g_mtx);
    g_finished.wait(lck);
    g_quit.store(true);
  }

  auto end = std::chrono::system_clock::now();
  auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

  std::cout << "per msg time: " << duration.count() / (double)msgcount << "ms \n"
            << "========================finished==============================\n";

  for (size_t th = 0; th != work_pool.size(); ++th) {
    work_pool[th]->join();
  }

  producer.shutdown();

  return 0;
}

  • 功能:同步等待消息发送的结果,适合对可靠性要求高的场景。
**1.2 异步消息发送 **AsyncProducer.cpp
/*
 * 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 <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <chrono>
#include <condition_variable>
#include <iomanip>
#include <iostream>
#include <mutex>
#include <thread>

#include "common.h"

using namespace rocketmq;

std::atomic<bool> g_quit;
std::mutex g_mtx;
std::condition_variable g_finished;
SendCallback* g_callback = NULL;
TpsReportService g_tps;

class MySendCallback : public SendCallback {
  virtual void onSuccess(SendResult& sendResult) {
    g_msgCount--;
    g_tps.Increment();
    if (g_msgCount.load() <= 0) {
      std::unique_lock<std::mutex> lck(g_mtx);
      g_finished.notify_one();
    }
  }
  virtual void onException(MQException& e) { cout << "send Exception\n"; }
};

class MyAutoDeleteSendCallback : public AutoDeleteSendCallBack {
 public:
  virtual ~MyAutoDeleteSendCallback() {}
  virtual void onSuccess(SendResult& sendResult) {
    g_msgCount--;
    if (g_msgCount.load() <= 0) {
      std::unique_lock<std::mutex> lck(g_mtx);
      g_finished.notify_one();
    }
  }
  virtual void onException(MQException& e) { std::cout << "send Exception" << e << "\n"; }
};

void AsyncProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* producer) {
  while (!g_quit.load()) {
    if (g_msgCount.load() <= 0) {
      std::unique_lock<std::mutex> lck(g_mtx);
      g_finished.notify_one();
    }
    MQMessage msg(info->topic,  // topic
                  "*",          // tag
                  info->body);  // body

    if (info->IsAutoDeleteSendCallback) {
      g_callback = new MyAutoDeleteSendCallback();  // auto delete
    }

    try {
      producer->send(msg, g_callback);
    } catch (MQException& e) {
      std::cout << e << endl;  // if catch excepiton , need re-send this msg by
                               // service
    }
  }
}

int main(int argc, char* argv[]) {
  RocketmqSendAndConsumerArgs info;
#if 0
  if (!ParseArgs(argc, argv, &info)) {
    exit(-1);
  }
#else
    info.namesrv = "192.168.8.138:9876;192.168.8.139:9876";
    info.namesrv_domain = "";
    info.groupname = "please_rename_unique_group_name";
    info.topic = "TopicTest";
    info.body = "msgbody for test";
#endif
  DefaultMQProducer producer("please_rename_unique_group_name");
  if (!info.IsAutoDeleteSendCallback) {
    g_callback = new MySendCallback();
  }

  PrintRocketmqSendAndConsumerArgs(info);

  if (!info.namesrv.empty())
    producer.setNamesrvAddr(info.namesrv);

  producer.setGroupName(info.groupname);
  producer.setInstanceName(info.groupname);
  producer.setNamesrvDomain(info.namesrv_domain);
  producer.start();
  g_tps.start();
  std::vector<std::shared_ptr<std::thread>> work_pool;
  auto start = std::chrono::system_clock::now();
  int msgcount = g_msgCount.load();
  for (int j = 0; j < info.thread_count; j++) {
    std::shared_ptr<std::thread> th = std::make_shared<std::thread>(AsyncProducerWorker, &info, &producer);
    work_pool.push_back(th);
  }

  {
    std::unique_lock<std::mutex> lck(g_mtx);
    g_finished.wait(lck);
    g_quit.store(true);
  }

  auto end = std::chrono::system_clock::now();
  auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

  std::cout << "per msg time: " << duration.count() / (double)msgcount << "ms \n"
            << "========================finished==============================\n";

  producer.shutdown();
  for (size_t th = 0; th != work_pool.size(); ++th) {
    work_pool[th]->join();
  }
  if (!info.IsAutoDeleteSendCallback) {
    delete g_callback;
  }
  return 0;
}

  • 功能:异步发送消息,提高吞吐量,适合性能敏感场景。
异步消息发送(v1.2) BatchProducer.cpp
/*
 * 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <condition_variable>
#include <iomanip>
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
#include "common.h"

using namespace rocketmq;
using namespace std;
std::atomic<bool> g_quit;
std::mutex g_mtx;
std::condition_variable g_finished;
TpsReportService g_tps;

void SyncProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* producer) {
  while (!g_quit.load()) {
    if (g_msgCount.load() <= 0) {
      std::unique_lock<std::mutex> lck(g_mtx);
      g_finished.notify_one();
      break;
    }

    vector<MQMessage> msgs;
    MQMessage msg1(info->topic, "*", info->body);
    msg1.setProperty("property1", "value1");
    MQMessage msg2(info->topic, "*", info->body);
    msg2.setProperty("property1", "value1");
    msg2.setProperty("property2", "value2");
    MQMessage msg3(info->topic, "*", info->body);
    msg3.setProperty("property1", "value1");
    msg3.setProperty("property2", "value2");
    msg3.setProperty("property3", "value3");
    msgs.push_back(msg1);
    msgs.push_back(msg2);
    msgs.push_back(msg3);
    try {
      auto start = std::chrono::system_clock::now();
      SendResult sendResult = producer->send(msgs);
      g_tps.Increment();
      --g_msgCount;
      auto end = std::chrono::system_clock::now();
      auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
      if (duration.count() >= 500) {
        std::cout << "send RT more than: " << duration.count() << " ms with msgid: " << sendResult.getMsgId() << endl;
      }
    } catch (const MQException& e) {
      std::cout << "send failed: " << e.what() << std::endl;
      std::unique_lock<std::mutex> lck(g_mtx);
      g_finished.notify_one();
      return;
    }
  }
}

int main(int argc, char* argv[]) {
  RocketmqSendAndConsumerArgs info;

#if 0
  if (!ParseArgs(argc, argv, &info)) {
    exit(-1);
  }
#else
    info.namesrv = "192.168.8.138:9876;192.168.8.139:9876";
    info.namesrv_domain = "";
    info.groupname = "please_rename_unique_group_name";
    info.topic = "TopicTest";
    info.body = "msgbody for test";
#endif
  PrintRocketmqSendAndConsumerArgs(info);
  DefaultMQProducer producer("please_rename_unique_group_name");
  producer.setNamesrvAddr(info.namesrv);
  producer.setNamesrvDomain(info.namesrv_domain);
  producer.setGroupName(info.groupname);
  producer.setInstanceName(info.groupname);
  producer.setSessionCredentials("mq acesskey", "mq secretkey", "ALIYUN");
  producer.setSendMsgTimeout(500);
  producer.setTcpTransportTryLockTimeout(1000);
  producer.setTcpTransportConnectTimeout(400);

  producer.start();
  std::vector<std::shared_ptr<std::thread>> work_pool;
  auto start = std::chrono::system_clock::now();
  int msgcount = g_msgCount.load();
  g_tps.start();

  int threadCount = info.thread_count;
  for (int j = 0; j < threadCount; j++) {
    std::shared_ptr<std::thread> th = std::make_shared<std::thread>(SyncProducerWorker, &info, &producer);
    work_pool.push_back(th);
  }

  {
    std::unique_lock<std::mutex> lck(g_mtx);
    g_finished.wait(lck);
    g_quit.store(true);
  }

  auto end = std::chrono::system_clock::now();
  auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

  std::cout << "per msg time: " << duration.count() / (double)msgcount << "ms \n"
            << "========================finished==============================\n";

  for (size_t th = 0; th != work_pool.size(); ++th) {
    work_pool[th]->join();
  }

  producer.shutdown();

  return 0;
}

1.3 单向消息发送
1
  • 功能:不等待服务器响应,适合对可靠性要求不高但性能要求极高的场景。

2. 消息消费

**2.1 推模式消费 **PushConsumer.cpp
/*
 * 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 <stdlib.h>
#include <string.h>

#include <chrono>
#include <condition_variable>
#include <iomanip>
#include <iostream>
#include <map>
#include <mutex>
#include <string>
#include <vector>

#include "common.h"

std::mutex g_mtx;
std::condition_variable g_finished;
TpsReportService g_tps;

using namespace rocketmq;

class MyMsgListener : public MessageListenerConcurrently {
 public:
  MyMsgListener() {}
  virtual ~MyMsgListener() {}

  virtual ConsumeStatus consumeMessage(const std::vector<MQMessageExt>& msgs) {
    g_msgCount.store(g_msgCount.load() - msgs.size());
    for (size_t i = 0; i < msgs.size(); ++i) {
      g_tps.Increment();
      cout << "msg body: "<<  msgs[i].getBody() << endl;
    }

    if (g_msgCount.load() <= 0) {
      std::unique_lock<std::mutex> lck(g_mtx);
      g_finished.notify_one();
    }
    return CONSUME_SUCCESS;
  }
};

int main(int argc, char* argv[]) {
  RocketmqSendAndConsumerArgs info;

#if 0
  if (!ParseArgs(argc, argv, &info)) {
    exit(-1);
  }
#else
    info.namesrv = "192.168.8.138:9876;192.168.8.139:9876";
    info.namesrv_domain = "";
    info.groupname = "please_rename_unique_group_name";
    info.topic = "TopicTest";
    info.body = "msgbody for test";
#endif
  PrintRocketmqSendAndConsumerArgs(info);
  DefaultMQPushConsumer consumer("please_rename_unique_group_name");
  DefaultMQProducer producer("please_rename_unique_group_name");
  producer.setSessionCredentials("AccessKey", "SecretKey", "ALIYUN");
  producer.setTcpTransportTryLockTimeout(1000);
  producer.setTcpTransportConnectTimeout(400);
  producer.setNamesrvDomain(info.namesrv_domain);
  producer.setNamesrvAddr(info.namesrv);
  producer.setGroupName("msg-persist-group_producer_sandbox");
  producer.start();

  consumer.setNamesrvAddr(info.namesrv);
  consumer.setGroupName(info.groupname);
  consumer.setSessionCredentials("AccessKey", "SecretKey", "ALIYUN");
  consumer.setConsumeThreadCount(info.thread_count);
  consumer.setNamesrvDomain(info.namesrv_domain);
  consumer.setConsumeFromWhere(CONSUME_FROM_LAST_OFFSET);

  if (info.syncpush)
    consumer.setAsyncPull(false);  // set sync pull
  if (info.broadcasting) {
    consumer.setMessageModel(rocketmq::BROADCASTING);
  }

  consumer.setInstanceName(info.groupname);

  consumer.subscribe(info.topic, "*");
  consumer.setConsumeThreadCount(15);
  consumer.setTcpTransportTryLockTimeout(1000);
  consumer.setTcpTransportConnectTimeout(400);

  MyMsgListener msglistener;
  consumer.registerMessageListener(&msglistener);

  try {
    consumer.start();
  } catch (MQClientException& e) {
    cout << e << endl;
  }
  g_tps.start();

  int msgcount = g_msgCount.load();
  for (int i = 0; i < msgcount; ++i) {
    MQMessage msg(info.topic,  // topic
                  "*",         // tag
                  info.body);  // body

    //    std::this_thread::sleep_for(std::chrono::seconds(100000));
    try {
      producer.send(msg);
    } catch (MQException& e) {
      std::cout << e << endl;  // if catch excepiton , need re-send this msg by
                               // service
    }
  }

  {
    std::unique_lock<std::mutex> lck(g_mtx);
    g_finished.wait(lck);
  }
  producer.shutdown();
  consumer.shutdown();
  return 0;
}

  • 功能:客户端自动接收并处理消息,适合实时消费场景。
推模式消费 AsyncPushConsumer.cpp
/*
 * 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 <stdlib.h>
#include <string.h>

#include <condition_variable>
#include <iomanip>
#include <iostream>
#include <vector>

#include "common.h"

std::mutex g_mtx;
std::condition_variable g_finished;
TpsReportService g_tps;
using namespace rocketmq;

class MyMsgListener : public MessageListenerConcurrently {
 public:
  MyMsgListener() {}
  virtual ~MyMsgListener() {}

  virtual ConsumeStatus consumeMessage(const std::vector<MQMessageExt>& msgs) {
    for (const auto& msg : msgs) {
        std::cout << "Received message: "<< "Tags:" << msg.getTags() << ", body:" << msg.getBody() << std::endl;
    }

    g_msgCount.store(g_msgCount.load() - msgs.size());
    for (size_t i = 0; i < msgs.size(); ++i) {
      g_tps.Increment();
    }

    if (g_msgCount.load() <= 0) {
      std::unique_lock<std::mutex> lck(g_mtx);
      g_finished.notify_one();
    }
    return CONSUME_SUCCESS;
  }
};

int main(int argc, char* argv[]) {
  RocketmqSendAndConsumerArgs info;

#if 0
  if (!ParseArgs(argc, argv, &info)) {
    exit(-1);
  }
#else
    info.namesrv = "192.168.8.138:9876;192.168.8.139:9876";
    info.namesrv_domain = "";
    info.groupname = "please_rename_unique_group_name";
    info.topic = "TopicTest";
    info.body = "msgbody for test";
#endif
  PrintRocketmqSendAndConsumerArgs(info);
  DefaultMQPushConsumer consumer("please_rename_unique_group_name");
  DefaultMQProducer producer("please_rename_unique_group_name");

  producer.setNamesrvAddr(info.namesrv);
  producer.setGroupName("msg-persist-group_producer_sandbox");
  producer.setNamesrvDomain(info.namesrv_domain);
  producer.start();

  consumer.setNamesrvAddr(info.namesrv);
  consumer.setGroupName(info.groupname);
  consumer.setNamesrvDomain(info.namesrv_domain);
  consumer.setConsumeFromWhere(CONSUME_FROM_LAST_OFFSET);

  consumer.setInstanceName(info.groupname);

  consumer.subscribe(info.topic, "*");
  consumer.setConsumeThreadCount(15);
  consumer.setTcpTransportTryLockTimeout(1000);
  consumer.setTcpTransportConnectTimeout(400);

  MyMsgListener msglistener;
  consumer.registerMessageListener(&msglistener);

  try {
    consumer.start();
  } catch (MQClientException& e) {
    cout << e << endl;
  }
  g_tps.start();

  int msgcount = g_msgCount.load();
  for (int i = 0; i < msgcount; ++i) {
    MQMessage msg(info.topic,  // topic
                  "*",         // tag
                  info.body);  // body

    try {
      producer.send(msg);
    } catch (MQException& e) {
      std::cout << e << endl;  // if catch excepiton , need re-send this msg by
                               // service
    }
  }

  {
    std::unique_lock<std::mutex> lck(g_mtx);
    g_finished.wait(lck);
  }
  producer.shutdown();
  consumer.shutdown();
  return 0;
}
推模式消费 OrderlyPushConsumer.cpp
/*
 * 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 <stdlib.h>
#include <string.h>

#include <condition_variable>
#include <iomanip>
#include <iostream>
#include <map>
#include <mutex>
#include <thread>
#include <vector>

#include "common.h"

using namespace rocketmq;

std::condition_variable g_finished;
std::mutex g_mtx;
std::atomic<int> g_consumedCount(0);
std::atomic<bool> g_quit(false);
TpsReportService g_tps;

class MyMsgListener : public MessageListenerOrderly {
 public:
  MyMsgListener() {}
  virtual ~MyMsgListener() {}

  virtual ConsumeStatus consumeMessage(const vector<MQMessageExt>& msgs) {
    if (g_consumedCount.load() >= g_msgCount) {
      std::unique_lock<std::mutex> lK(g_mtx);
      g_quit.store(true);
      g_finished.notify_one();
    }
    for (size_t i = 0; i < msgs.size(); i++) {
      ++g_consumedCount;
      g_tps.Increment();
    }
    return CONSUME_SUCCESS;
  }
};

int main(int argc, char* argv[]) {
  RocketmqSendAndConsumerArgs info;

#if 0
  if (!ParseArgs(argc, argv, &info)) {
    exit(-1);
  }
#else
    info.namesrv = "192.168.8.138:9876;192.168.8.139:9876";
    info.namesrv_domain = "";
    info.groupname = "please_rename_unique_group_name";
    info.topic = "TopicTest";
    info.body = "msgbody for test";
#endif
  PrintRocketmqSendAndConsumerArgs(info);
  DefaultMQPushConsumer consumer("please_rename_unique_group_name");
  DefaultMQProducer producer("please_rename_unique_group_name");

  producer.setNamesrvAddr(info.namesrv);
  producer.setGroupName("msg-persist-group_producer_sandbox");
  producer.start();

  consumer.setNamesrvAddr(info.namesrv);
  consumer.setNamesrvDomain(info.namesrv_domain);
  consumer.setGroupName(info.groupname);
  consumer.setConsumeFromWhere(CONSUME_FROM_LAST_OFFSET);
  consumer.subscribe(info.topic, "*");
  consumer.setConsumeThreadCount(info.thread_count);
  consumer.setConsumeMessageBatchMaxSize(31);
  if (info.syncpush)
    consumer.setAsyncPull(false);

  MyMsgListener msglistener;
  consumer.registerMessageListener(&msglistener);
  g_tps.start();

  try {
    consumer.start();
  } catch (MQClientException& e) {
    std::cout << e << std::endl;
  }

  int msgcount = g_msgCount.load();
  for (int i = 0; i < msgcount; ++i) {
    MQMessage msg(info.topic,  // topic
                  "*",         // tag
                  info.body);  // body

    try {
      producer.send(msg);
    } catch (MQException& e) {
      std::cout << e << endl;  // if catch excepiton , need re-send this msg by
                               // service
    }
  }

  while (!g_quit.load()) {
    std::unique_lock<std::mutex> lk(g_mtx);
    g_finished.wait(lk);
  }

  producer.shutdown();
  consumer.shutdown();
  return 0;
}

2.2 拉模式消费 PullConsumer.cpp
/*
 * 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 <stdlib.h>

#include <chrono>
#include <iomanip>
#include <iostream>
#include <map>
#include <vector>

#include "common.h"

using namespace rocketmq;

std::map<MQMessageQueue, uint64_t> g_offseTable;

void putMessageQueueOffset(MQMessageQueue mq, uint64_t offset) {
  g_offseTable[mq] = offset;
}

uint64_t getMessageQueueOffset(MQMessageQueue mq) {
  map<MQMessageQueue, uint64_t>::iterator it = g_offseTable.find(mq);
  if (it != g_offseTable.end()) {
    return it->second;
  }
  return 0;
}

int main(int argc, char* argv[]) {
  RocketmqSendAndConsumerArgs info;
#if 0
  if (!ParseArgs(argc, argv, &info)) {
    exit(-1);
  }
#else
    info.namesrv = "192.168.8.138:9876;192.168.8.139:9876";
    info.namesrv_domain = "";
    info.groupname = "please_rename_unique_group_name";
    info.topic = "TopicTest";
    info.body = "msgbody for test";
#endif
  PrintRocketmqSendAndConsumerArgs(info);
  DefaultMQPullConsumer consumer("please_rename_unique_group_name");
  consumer.setNamesrvAddr(info.namesrv);
  consumer.setNamesrvDomain(info.namesrv_domain);
  consumer.setGroupName(info.groupname);
  consumer.setInstanceName(info.groupname);
  consumer.registerMessageQueueListener(info.topic, NULL);
  consumer.start();
  std::vector<MQMessageQueue> mqs;

  try {
    consumer.fetchSubscribeMessageQueues(info.topic, mqs);
    auto iter = mqs.begin();
    for (; iter != mqs.end(); ++iter) {
      std::cout << "mq:" << (*iter).toString() << endl;
    }
  } catch (MQException& e) {
    std::cout << e << endl;
  }

  auto start = std::chrono::system_clock::now();
  auto iter = mqs.begin();
  for (; iter != mqs.end(); ++iter) {
    MQMessageQueue mq = (*iter);
    // if cluster model
    // putMessageQueueOffset(mq, g_consumer.fetchConsumeOffset(mq,true));
    // if broadcast model
    // putMessageQueueOffset(mq, your last consume offset);

    bool noNewMsg = false;
    do {
      try {
        PullResult result = consumer.pull(mq, "*", getMessageQueueOffset(mq), 32);
        g_msgCount += result.msgFoundList.size();
        std::cout << result.msgFoundList.size() << std::endl;
        // if pull request timeout or received NULL response, pullStatus will be
        // setted to BROKER_TIMEOUT,
        // And nextBeginOffset/minOffset/MaxOffset will be setted to 0
        if (result.pullStatus != BROKER_TIMEOUT) {
          putMessageQueueOffset(mq, result.nextBeginOffset);
          PrintPullResult(&result);
        } else {
          cout << "broker timeout occur" << endl;
        }
        switch (result.pullStatus) {
          case FOUND:
          case NO_MATCHED_MSG:
          case OFFSET_ILLEGAL:
          case BROKER_TIMEOUT:
            break;
          case NO_NEW_MSG:
            noNewMsg = true;
            break;
          default:
            break;
        }
      } catch (MQClientException& e) {
        std::cout << e << std::endl;
      }
    } while (!noNewMsg);
  }

  auto end = std::chrono::system_clock::now();
  auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

  std::cout << "msg count: " << g_msgCount.load() << "\n";
  std::cout << "per msg time: " << duration.count() / (double)g_msgCount.load() << "ms \n"
            << "========================finished==============================\n";

  consumer.shutdown();
  return 0;
}

  • 功能:手动拉取消息,适合对消费过程需要精细控制的场景。

3. 事务消息 TransactionProducer.cpp

/*
 * 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 <atomic>
#include <condition_variable>
#include <iomanip>
#include <iostream>
#include <mutex>
#include <thread>
#include "TransactionListener.h"
#include "TransactionMQProducer.h"
#include "TransactionSendResult.h"
#include "common.h"

using namespace rocketmq;

std::atomic<bool> g_quit;
std::mutex g_mtx;
std::condition_variable g_finished;
TpsReportService g_tps;

class MyTransactionListener : public TransactionListener {
  virtual LocalTransactionState executeLocalTransaction(const MQMessage& msg, void* arg) {
    if (!arg) {
      std::cout << "executeLocalTransaction transactionId:" << msg.getTransactionId()
                << ", return state: COMMIT_MESAGE " << endl;
      return LocalTransactionState::COMMIT_MESSAGE;
    }

    LocalTransactionState state = (LocalTransactionState)(*(int*)arg % 3);
    std::cout << "executeLocalTransaction transactionId:" << msg.getTransactionId() << ", return state: " << state
              << endl;
    return state;
  }

  virtual LocalTransactionState checkLocalTransaction(const MQMessageExt& msg) {
    std::cout << "checkLocalTransaction enter msg:" << msg.toString() << endl;
    return LocalTransactionState::COMMIT_MESSAGE;
  }
};

void SyncProducerWorker(RocketmqSendAndConsumerArgs* info, TransactionMQProducer* producer) {
  while (!g_quit.load()) {
    if (g_msgCount.load() <= 0) {
      std::this_thread::sleep_for(std::chrono::seconds(60));
      std::unique_lock<std::mutex> lck(g_mtx);
      g_finished.notify_one();
      break;
    }

    MQMessage msg(info->topic,  // topic
                  "*",          // tag
                  info->body);  // body
    try {
      auto start = std::chrono::system_clock::now();
      std::cout << "before sendMessageInTransaction" << endl;
      LocalTransactionState state = LocalTransactionState::UNKNOWN;
      TransactionSendResult sendResult = producer->sendMessageInTransaction(msg, &state);
      std::cout << "after sendMessageInTransaction msgId: " << sendResult.getMsgId() << endl;
      g_tps.Increment();
      --g_msgCount;
      auto end = std::chrono::system_clock::now();
      auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
      if (duration.count() >= 500) {
        std::cout << "send RT more than: " << duration.count() << " ms with msgid: " << sendResult.getMsgId() << endl;
      }
    } catch (const MQException& e) {
      std::cout << "send failed: " << e.what() << std::endl;
    }
  }
}

int main(int argc, char* argv[]) {
  RocketmqSendAndConsumerArgs info;
#if 0
  if (!ParseArgs(argc, argv, &info)) {
    exit(-1);
  }
#else
    info.namesrv = "192.168.8.138:9876;192.168.8.139:9876";
    info.namesrv_domain = "";
    info.groupname = "please_rename_unique_group_name";
    info.topic = "TopicTest";
    info.body = "msgbody for test";
#endif
  PrintRocketmqSendAndConsumerArgs(info);
  TransactionMQProducer producer("please_rename_unique_group_name");
  producer.setNamesrvAddr(info.namesrv);
  producer.setNamesrvDomain(info.namesrv_domain);
  producer.setGroupName(info.groupname);
  producer.setInstanceName(info.groupname);
  producer.setSessionCredentials("mq acesskey", "mq secretkey", "ALIYUN");
  producer.setSendMsgTimeout(500);
  producer.setTcpTransportTryLockTimeout(1000);
  producer.setTcpTransportConnectTimeout(400);
  producer.setLogLevel(eLOG_LEVEL_DEBUG);
  producer.setTransactionListener(new MyTransactionListener());
  producer.start();
  std::vector<std::shared_ptr<std::thread>> work_pool;
  auto start = std::chrono::system_clock::now();
  int msgcount = g_msgCount.load();
  g_tps.start();

  int threadCount = info.thread_count;
  for (int j = 0; j < threadCount; j++) {
    std::shared_ptr<std::thread> th = std::make_shared<std::thread>(SyncProducerWorker, &info, &producer);
    work_pool.push_back(th);
  }

  {
    std::unique_lock<std::mutex> lck(g_mtx);
    g_finished.wait(lck);
    g_quit.store(true);
  }

  auto end = std::chrono::system_clock::now();
  auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

  std::cout << "per msg time: " << duration.count() / (double)msgcount << "ms \n"
            << "========================finished==============================\n";

  for (size_t th = 0; th != work_pool.size(); ++th) {
    work_pool[th]->join();
  }

  producer.shutdown();

  return 0;
}

  • 输出结果
Failed to send message: msg: transactionListener is null,error:-1,in file </root/rocketmq-client-cpp-2.2.0/src/producer/TransactionMQProducerImpl.cpp> line:44
[root@localhost myproject_1_35]# 
  • 功能:确保消息与本地事务的一致性,适合分布式事务场景。

**4. 延时消息 ** SendDelayMsg.cpp

  • 延迟消息的等级定义在服务端MessageStoreConfig.java 中,如下:
private String messageDelayLevel = "1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h";
/*
 * 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 <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <condition_variable>
#include <iomanip>
#include <iostream>
#include <mutex>
#include <thread>

#include "common.h"

using namespace rocketmq;

int main(int argc, char* argv[]) {
  RocketmqSendAndConsumerArgs info;
#if 0
  if (!ParseArgs(argc, argv, &info)) {
    exit(-1);
  }
#else
    info.namesrv = "192.168.8.138:9876;192.168.8.139:9876";
    info.namesrv_domain = "";
    info.groupname = "please_rename_unique_group_name";
    info.topic = "TopicTest";
    info.body = "msgbody for test";
#endif
  PrintRocketmqSendAndConsumerArgs(info);
  DefaultMQProducer producer("please_rename_unique_group_name");
  producer.setNamesrvAddr(info.namesrv);
  producer.setNamesrvDomain(info.namesrv_domain);
  producer.setGroupName(info.groupname);
  producer.setInstanceName(info.groupname);

  producer.setSendMsgTimeout(500);
  producer.setTcpTransportTryLockTimeout(1000);
  producer.setTcpTransportConnectTimeout(400);

  producer.start();

  MQMessage msg(info.topic,  // topic
                "*",         // tag
                info.body);  // body

  // messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h
  // 2h
  msg.setDelayTimeLevel(5);  // 1m
  try {
    SendResult sendResult = producer.send(msg, info.SelectUnactiveBroker);
  } catch (const MQException& e) {
    std::cout << "send failed: " << std::endl;
  }

  producer.shutdown();
  return 0;
}

  • 功能:发送延时消息,适合定时任务或延迟通知场景。

5. 顺序消息 OrderProducer.cpp

/*
 * 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 <stdlib.h>
#include <string.h>

#include <condition_variable>
#include <iomanip>
#include <iostream>
#include <thread>

#include "common.h"

using namespace rocketmq;

std::condition_variable g_finished;
std::mutex g_mtx;
std::atomic<bool> g_quit(false);

class SelectMessageQueueByHash : public MessageQueueSelector {
 public:
  MQMessageQueue select(const std::vector<MQMessageQueue>& mqs, const MQMessage& msg, void* arg) {
    int orderId = *static_cast<int*>(arg);
    int index = orderId % mqs.size();
    return mqs[index];
  }
};

SelectMessageQueueByHash g_mySelector;

void ProducerWorker(RocketmqSendAndConsumerArgs* info, DefaultMQProducer* producer) {
  while (!g_quit.load()) {
    if (g_msgCount.load() <= 0) {
      std::unique_lock<std::mutex> lck(g_mtx);
      g_finished.notify_one();
    }
    MQMessage msg(info->topic,  // topic
                  "*",          // tag
                  info->body);  // body

    int orderId = 1;
    SendResult sendResult =
        producer->send(msg, &g_mySelector, static_cast<void*>(&orderId), info->retrytimes, info->SelectUnactiveBroker);
    --g_msgCount;
  }
}

int main(int argc, char* argv[]) {
  RocketmqSendAndConsumerArgs info;
#if 0
  if (!ParseArgs(argc, argv, &info)) {
    exit(-1);
  }
#else
    info.namesrv = "192.168.8.138:9876;192.168.8.139:9876";
    info.namesrv_domain = "";
    info.groupname = "please_rename_unique_group_name";
    info.topic = "TopicTest";
    info.body = "msgbody for test";
#endif

  DefaultMQProducer producer("please_rename_unique_group_name");
  PrintRocketmqSendAndConsumerArgs(info);

  producer.setNamesrvAddr(info.namesrv);
  producer.setNamesrvDomain(info.namesrv_domain);
  producer.setGroupName(info.groupname);
  producer.setInstanceName(info.groupname);

  producer.start();

  int msgcount = g_msgCount.load();
  std::vector<std::shared_ptr<std::thread>> work_pool;

  int threadCount = info.thread_count;
  for (int j = 0; j < threadCount; j++) {
    std::shared_ptr<std::thread> th = std::make_shared<std::thread>(ProducerWorker, &info, &producer);
    work_pool.push_back(th);
  }

  auto start = std::chrono::system_clock::now();
  {
    std::unique_lock<std::mutex> lck(g_mtx);
    g_finished.wait(lck);
    g_quit.store(true);
  }

  auto end = std::chrono::system_clock::now();
  auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

  std::cout << "per msg time: " << duration.count() / (double)msgcount << "ms \n"
            << "========================finished==============================\n";

  for (size_t th = 0; th != work_pool.size(); ++th) {
    work_pool[th]->join();
  }

  producer.shutdown();

  return 0;
}

  • 功能:保证同一分区内消息顺序,适合需要有序处理的场景。

6. 消息过滤

基于 Tag 的过滤
consumer.subscribe("TestTopic", "TagA || TagB");
  • 功能:仅接收指定 Tag 的消息。
基于 SQL 表达式的过滤
  • 功能:通过 SQL 表达式过滤消息,适合复杂过滤场景。

7. 监控与日志

  • 客户端监控:支持获取生产者/消费者状态、统计信息等。
  • 日志记录:默认集成日志功能,便于排查问题。

总结

上述代码覆盖了 rocketmq-client-cpp 的主要功能,包括生产消息、消费消息、事务消息、延时消息、顺序消息等。这些功能可以根据业务需求自由组合。如果有更复杂的使用场景或问题,欢迎进一步交流!

附录 官网 example 中 common.h

/*
 * 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.
 */
#ifndef ROCKETMQ_CLIENT4CPP_EXAMPLE_COMMON_H_
#define ROCKETMQ_CLIENT4CPP_EXAMPLE_COMMON_H_

#include <functional>
#include <atomic>
#include <chrono>
#include <iostream>
#include <memory>
#include <string>
#include <thread>
#include <vector>
#ifndef WIN32
#include "unistd.h"
#endif
#include "Arg_helper.h"
#include "DefaultMQProducer.h"
#include "DefaultMQPullConsumer.h"
#include "DefaultMQPushConsumer.h"
using namespace std;

std::atomic<int> g_msgCount(1);

class RocketmqSendAndConsumerArgs {
 public:
  RocketmqSendAndConsumerArgs()
      : body("msgbody for test"),
        thread_count(std::thread::hardware_concurrency()),
        broadcasting(false),
        syncpush(false),
        SelectUnactiveBroker(false),
        IsAutoDeleteSendCallback(false),
        retrytimes(5),
        PrintMoreInfo(false) {}

 public:
  std::string namesrv;
  std::string namesrv_domain;
  std::string groupname;
  std::string topic;
  std::string body;
  int thread_count;
  bool broadcasting;
  bool syncpush;
  bool SelectUnactiveBroker;  // default select active broker
  bool IsAutoDeleteSendCallback;
  int retrytimes;  // default retry 5 times;
  bool PrintMoreInfo;
};

class TpsReportService {
 public:
  TpsReportService() : tps_interval_(1), quit_flag_(false), tps_count_(0) {}
  void start() {
    if (tps_thread_ == NULL) {
      std::cout << "tps_thread_ is null" << std::endl;
      return;
    }
    tps_thread_.reset(new std::thread(std::bind(&TpsReportService::TpsReport, this)));
  }

  ~TpsReportService() {
    quit_flag_.store(true);
    if (tps_thread_ == NULL) {
      std::cout << "tps_thread_ is null" << std::endl;
      return;
    }
    if (tps_thread_->joinable())
      tps_thread_->join();
  }

  void Increment() { ++tps_count_; }

  void TpsReport() {
    while (!quit_flag_.load()) {
      std::this_thread::sleep_for(tps_interval_);
      std::cout << "tps: " << tps_count_.load() << std::endl;
      tps_count_.store(0);
    }
  }

 private:
  std::chrono::seconds tps_interval_;
  std::shared_ptr<std::thread> tps_thread_;
  std::atomic<bool> quit_flag_;
  std::atomic<long> tps_count_;
};

void PrintPullResult(rocketmq::PullResult* result) {
  std::cout << result->toString() << std::endl;
  if (result->pullStatus == rocketmq::FOUND) {
    std::cout << result->toString() << endl;
    std::vector<rocketmq::MQMessageExt>::iterator it = result->msgFoundList.begin();
    for (; it != result->msgFoundList.end(); ++it) {
      cout << "=======================================================" << endl << (*it).toString() << endl;
    }
  }
}

static void PrintRocketmqSendAndConsumerArgs(const RocketmqSendAndConsumerArgs& info) {
  std::cout << "nameserver: " << info.namesrv << endl
            << "topic: " << info.topic << endl
            << "groupname: " << info.groupname << endl
            << "produce content: " << info.body << endl
            << "msg  count: " << g_msgCount.load() << endl
            << "thread count: " << info.thread_count << endl;
}

static void help() {
  std::cout << "need option,like follow: \n"
            << "-n nameserver addr, if not set -n and -i ,no nameSrv will be got \n"
               "-i nameserver domain name,  if not set -n and -i ,no nameSrv will be "
               "got \n"
               "-g groupname \n"
               "-t  msg topic \n"
               "-m messagecout(default value: 1) \n"
               "-c content(default value: only test ) \n"
               "-b (BROADCASTING model, default value: CLUSTER) \n"
               "-s sync push(default is async push)\n"
               "-r setup retry times(default value: 5 times)\n"
               "-u select active broker to send msg(default value: false)\n"
               "-d use AutoDeleteSendcallback by cpp client(defalut value: false) \n"
               "-T thread count of send msg or consume msg(defalut value: system cpu "
               "core number) \n"
               "-v print more details information \n";
}

static bool ParseArgs(int argc, char* argv[], RocketmqSendAndConsumerArgs* info) {
#ifndef WIN32
  int ch;
  while ((ch = getopt(argc, argv, "n:i:g:t:m:c:b:s:h:r:T:bu")) != -1) {
    switch (ch) {
      case 'n':
        info->namesrv.insert(0, optarg);
        break;
      case 'i':
        info->namesrv_domain.insert(0, optarg);
        break;
      case 'g':
        info->groupname.insert(0, optarg);
        break;
      case 't':
        info->topic.insert(0, optarg);
        break;
      case 'm':
        g_msgCount.store(atoi(optarg));
        break;
      case 'c':
        info->body.insert(0, optarg);
        break;
      case 'b':
        info->broadcasting = true;
        break;
      case 's':
        info->syncpush = true;
        break;
      case 'r':
        info->retrytimes = atoi(optarg);
        break;
      case 'u':
        info->SelectUnactiveBroker = true;
        break;
      case 'T':
        info->thread_count = atoi(optarg);
        break;
      case 'v':
        info->PrintMoreInfo = true;
        break;
      case 'h':
        help();
        return false;
      default:
        help();
        return false;
    }
  }
#else
  rocketmq::Arg_helper arg_help(argc, argv);
  info->namesrv = arg_help.get_option_value("-n");
  info->namesrv_domain = arg_help.get_option_value("-i");
  info->groupname = arg_help.get_option_value("-g");
  info->topic = arg_help.get_option_value("-t");
  info->broadcasting = atoi(arg_help.get_option_value("-b").c_str());
  string msgContent(arg_help.get_option_value("-c"));
  if (!msgContent.empty())
    info->body = msgContent;
  info->syncpush = atoi(arg_help.get_option_value("-s").c_str());
  int retrytimes = atoi(arg_help.get_option_value("-r").c_str());
  if (retrytimes > 0)
    info->retrytimes = retrytimes;
  info->SelectUnactiveBroker = atoi(arg_help.get_option_value("-u").c_str());
  int thread_count = atoi(arg_help.get_option_value("-T").c_str());
  if (thread_count > 0)
    info->thread_count = thread_count;
  info->PrintMoreInfo = atoi(arg_help.get_option_value("-v").c_str());
  g_msgCount = atoi(arg_help.get_option_value("-m").c_str());
#endif
  if (info->groupname.empty() || info->topic.empty() || (info->namesrv_domain.empty() && info->namesrv.empty())) {
    std::cout << "please use -g to setup groupname and -t setup topic \n";
    help();
    return false;
  }
  return true;
}
#endif  // ROCKETMQ_CLIENT4CPP_EXAMPLE_COMMON_H_

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值