You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rocketmq.apache.org by di...@apache.org on 2020/02/27 08:03:38 UTC

[rocketmq-client-cpp] branch re_dev updated: reconstructed Apache RocketMQ cpp client (#231)

This is an automated email from the ASF dual-hosted git repository.

dinglei pushed a commit to branch re_dev
in repository https://gitbox.apache.org/repos/asf/rocketmq-client-cpp.git


The following commit(s) were added to refs/heads/re_dev by this push:
     new e7427c6  reconstructed Apache RocketMQ cpp client (#231)
e7427c6 is described below

commit e7427c68aeaa09d664864b85e5200ea24baa4e1e
Author: James Yin <yw...@hotmail.com>
AuthorDate: Thu Feb 27 16:03:30 2020 +0800

    reconstructed Apache RocketMQ cpp client (#231)
---
 .gitignore                                         |   12 +-
 CMakeLists.txt                                     |   98 +-
 README.md                                          |  236 ++--
 cmake/BundleStaticLibrary.cmake                    |  134 ++
 cmake/FindJsoncpp.cmake                            |   84 +-
 cmake/FindLibevent.cmake                           |  175 +--
 distribution/deploy.sh                             |    2 +-
 src/common/Arg_helper.cpp => example/ArgHelper.cpp |   21 +-
 include/Arg_helper.h => example/ArgHelper.h        |   17 +-
 example/AsyncProducer.cpp                          |  139 +-
 example/AsyncPushConsumer.cpp                      |  111 --
 example/BatchProducer.cpp                          |  130 +-
 example/CAsyncProducer.c                           |    8 +-
 example/CBatchProducer.c                           |    8 +-
 example/CMakeLists.txt                             |   16 +-
 example/COrderlyAsyncProducer.c                    |    8 +-
 example/OrderProducer.cpp                          |  108 --
 example/OrderlyProducer.cpp                        |  103 ++
 example/OrderlyPushConsumer.cpp                    |  121 +-
 example/Producer.c                                 |   62 +-
 example/PullConsumeMessage.c                       |    9 +-
 example/PullConsumer.cpp                           |   42 +-
 example/PushConsumeMessage.c                       |    7 +-
 example/PushConsumer.cpp                           |  140 +-
 example/PushConsumerOrderly.c                      |    8 +-
 example/SendDelayMsg.cpp                           |   69 +-
 example/SyncProducer.cpp                           |  107 +-
 example/TransactionProducer.cpp                    |  100 +-
 example/common.h                                   |  178 ++-
 .../AllocateMQStrategy.h                           |   21 +-
 include/AsyncCallback.h                            |   58 -
 {src/common => include}/ClientRPCHook.h            |   40 +-
 .../KVTable.h => include/CommandCustomHeader.h     |   31 +-
 include/ConsumeType.h                              |  124 +-
 .../noncopyable.h => include/DefaultMQConsumer.h   |   23 +-
 include/DefaultMQProducer.h                        |  257 ++--
 include/DefaultMQPullConsumer.h                    |  241 ++--
 include/DefaultMQPushConsumer.h                    |  290 ++--
 include/MQAdmin.h                                  |  103 ++
 include/MQClient.h                                 |  202 ---
 include/MQClientConfig.h                           |   96 ++
 include/MQClientException.h                        |   73 +-
 include/MQConsumer.h                               |  113 +-
 include/MQMessage.h                                |   94 +-
 include/MQMessageConst.h                           |   64 +
 include/MQMessageExt.h                             |  121 +-
 include/MQMessageListener.h                        |  164 +--
 include/MQMessageQueue.h                           |  127 +-
 include/MQProducer.h                               |  142 +-
 include/MQPullConsumer.h                           |  103 ++
 src/protocol/KVTable.h => include/MQPushConsumer.h |   35 +-
 include/MQSelector.h                               |   69 +-
 include/MQueueListener.h                           |   72 +-
 .../TopAddressing.h => include/PullCallback.h      |   41 +-
 include/PullResult.h                               |  142 +-
 include/QueryResult.h                              |   84 +-
 src/protocol/KVTable.h => include/RPCHook.h        |   36 +-
 include/RemotingCommand.h                          |  127 ++
 include/RocketMQClient.h                           |  131 +-
 include/{SendMessageHook.h => SendCallback.h}      |   92 +-
 include/SendMessageHook.h                          |   94 +-
 include/SendResult.h                               |  127 +-
 include/SessionCredentials.h                       |   60 +-
 {src/common => include}/TopicFilterType.h          |   13 +-
 include/TransactionListener.h                      |   14 +-
 include/TransactionMQProducer.h                    |   72 +-
 include/TransactionSendResult.h                    |   18 +-
 include/{ => c}/CBatchMessage.h                    |    7 +-
 include/{ => c}/CCommon.h                          |   13 +-
 include/{ => c}/CErrorMessage.h                    |    8 +-
 include/{ => c}/CMQException.h                     |    4 +-
 include/{ => c}/CMessage.h                         |    5 +-
 include/{ => c}/CMessageExt.h                      |    4 +-
 include/{ => c}/CMessageQueue.h                    |    4 +-
 include/{ => c}/CProducer.h                        |    6 +-
 include/{ => c}/CPullConsumer.h                    |    4 +-
 include/{ => c}/CPullResult.h                      |    5 +-
 include/{ => c}/CPushConsumer.h                    |    4 +-
 include/{ => c}/CSendResult.h                      |    5 +-
 include/{ => c}/CTransactionStatus.h               |    5 +-
 libs/signature/CMakeLists.txt                      |    4 +-
 libs/signature/include/spas_client.h               |   12 +-
 project/CMakeLists.txt                             |   58 +-
 src/ClientRemotingProcessor.cpp                    |  158 +++
 src/ClientRemotingProcessor.h                      |   55 +
 src/MQAdminImpl.cpp                                |  136 ++
 src/MQAdminImpl.h                                  |   52 +
 src/MQClientAPIImpl.cpp                            | 1262 +++++++----------
 src/MQClientAPIImpl.h                              |  350 +++--
 src/MQClientConfig.cpp                             |  116 ++
 src/MQClientFactory.cpp                            | 1211 ----------------
 src/MQClientFactory.h                              |  217 ---
 src/MQClientImpl.cpp                               |   90 ++
 src/MQClientImpl.h                                 |   64 +
 src/MQClientInstance.cpp                           |  962 +++++++++++++
 src/MQClientInstance.h                             |  204 +++
 src/MQClientManager.cpp                            |   50 +-
 src/MQClientManager.h                              |   31 +-
 src/common/AsyncArg.h                              |   36 -
 src/common/AsyncCallbackWrap.cpp                   |  192 ---
 src/common/AsyncCallbackWrap.h                     |   80 --
 src/common/ByteOrder.h                             |  458 ++++---
 src/common/ClientRPCHook.cpp                       |   88 +-
 src/common/CommunicationMode.h                     |   13 +-
 src/common/DataBlock.cpp                           |  239 ++++
 src/common/DataBlock.h                             |  211 +++
 src/common/FilterAPI.h                             |   46 +-
 src/common/InputStream.cpp                         |  225 +--
 src/common/InputStream.h                           |  387 +++---
 .../BatchMessage.h => src/common/InvokeCallback.h  |   19 +-
 src/common/MQClient.cpp                            |  224 ---
 src/common/MQVersion.cpp                           |    4 +-
 src/common/MQVersion.h                             |   10 +-
 src/common/MemoryInputStream.cpp                   |  157 ++-
 src/common/MemoryInputStream.h                     |  191 ++-
 src/common/MemoryOutputStream.cpp                  |  329 ++---
 src/common/MemoryOutputStream.h                    |  259 ++--
 src/common/MessageAccessor.cpp                     |   56 -
 src/common/MessageSysFlag.cpp                      |   20 +-
 src/common/MessageSysFlag.h                        |   27 +-
 src/common/NameSpaceUtil.cpp                       |   61 +-
 src/common/NameSpaceUtil.h                         |   30 +-
 src/common/NamesrvConfig.h                         |   18 +-
 src/common/OutputStream.cpp                        |  211 +--
 src/common/OutputStream.h                          |  295 ++--
 src/common/PermName.cpp                            |    9 +-
 src/common/PermName.h                              |   12 +-
 src/common/PullCallbackWrap.cpp                    |   59 +
 ...MQClientErrorContainer.h => PullCallbackWrap.h} |   22 +-
 src/common/PullSysFlag.cpp                         |    5 +-
 src/common/PullSysFlag.h                           |   13 +-
 src/common/SendCallbackWrap.cpp                    |  193 +++
 src/common/SendCallbackWrap.h                      |   72 +
 src/common/ServiceState.h                          |   13 +-
 src/common/ServiceThread.cpp                       |   86 ++
 .../StringIdMaker.h => common/ServiceThread.h}     |   68 +-
 src/{consumer => common}/SubscriptionData.h        |   55 +-
 src/common/SubscriptionGroupConfig.h               |   15 +-
 src/common/TopAddressing.cpp                       |  105 --
 src/common/TopicConfig.cpp                         |   26 +-
 src/common/TopicConfig.h                           |   31 +-
 src/common/UtilAll.cpp                             |  435 +++---
 src/common/UtilAll.h                               |  191 +--
 src/common/Validators.cpp                          |   46 +-
 src/common/Validators.h                            |   20 +-
 src/common/VirtualEnvUtil.cpp                      |   15 +-
 src/common/VirtualEnvUtil.h                        |   13 +-
 src/common/big_endian.cpp                          |    4 +-
 src/common/big_endian.h                            |    3 +-
 src/common/dataBlock.cpp                           |  207 ---
 src/common/dataBlock.h                             |  208 ---
 src/common/noncopyable.h                           |    2 +-
 src/common/sync_http_client.cpp                    |  151 --
 src/common/sync_http_client.h                      |   29 -
 src/common/url.cpp                                 |   65 -
 src/common/url.h                                   |   38 -
 src/concurrent/concurrent_queue.hpp                |  143 ++
 src/concurrent/executor.hpp                        |   86 ++
 src/concurrent/executor_impl.hpp                   |  306 +++++
 src/concurrent/latch.hpp                           |  146 ++
 src/concurrent/thread.hpp                          |  168 +++
 src/concurrent/thread_group.hpp                    |   93 ++
 src/{message/MQMessageId.h => concurrent/time.hpp} |   58 +-
 ...{AllocateMQStrategy.h => AllocateMQAveragely.h} |   44 +-
 src/consumer/ConsumeMessageConcurrentlyService.cpp |  411 ++----
 src/consumer/ConsumeMessageOrderlyService.cpp      |  439 +++---
 src/consumer/ConsumeMsgService.h                   |  224 ++-
 src/consumer/DefaultMQPullConsumer.cpp             |  407 +-----
 src/consumer/DefaultMQPullConsumerImpl.cpp         |  374 +++++
 src/consumer/DefaultMQPullConsumerImpl.h           |  173 +++
 src/consumer/DefaultMQPushConsumer.cpp             | 1024 +-------------
 src/consumer/DefaultMQPushConsumerImpl.cpp         |  603 ++++++++
 src/consumer/DefaultMQPushConsumerImpl.h           |  153 +++
 src/consumer/FindBrokerResult.h                    |   10 +-
 .../MQConsumerInner.h}                             |   36 +-
 .../MessageQueueLock.hpp}                          |   28 +-
 src/consumer/OffsetStore.cpp                       |  402 +++---
 src/consumer/OffsetStore.h                         |   97 +-
 src/consumer/ProcessQueue.cpp                      |  226 +++
 src/consumer/ProcessQueue.h                        |  101 ++
 src/consumer/PullAPIWrapper.cpp                    |  270 ++--
 src/consumer/PullAPIWrapper.h                      |  129 +-
 src/consumer/PullMessageService.h                  |   75 +
 src/consumer/PullRequest.cpp                       |  345 +----
 src/consumer/PullRequest.h                         |  106 +-
 src/consumer/PullResult.cpp                        |  100 +-
 src/consumer/PullResultExt.h                       |   39 +-
 src/consumer/Rebalance.cpp                         |  657 ---------
 src/consumer/Rebalance.h                           |  137 --
 src/consumer/RebalanceImpl.cpp                     |  524 +++++++
 src/consumer/RebalanceImpl.h                       |  113 ++
 src/consumer/RebalancePullImpl.cpp                 |   48 +
 src/consumer/RebalancePullImpl.h                   |   54 +
 src/consumer/RebalancePushImpl.cpp                 |  152 ++
 src/consumer/RebalancePushImpl.h                   |   49 +
 .../RebalanceService.h}                            |   42 +-
 src/consumer/SubscriptionData.cpp                  |   67 +-
 src/extern/CBatchMessage.cpp                       |   23 +-
 src/extern/CErrorMessage.cpp                       |    8 +-
 src/extern/CMessage.cpp                            |   56 +-
 src/extern/CMessageExt.cpp                         |   15 +-
 src/extern/CProducer.cpp                           |  464 ++-----
 src/extern/CPullConsumer.cpp                       |   74 +-
 src/extern/CPushConsumer.cpp                       |  103 +-
 src/extern/CSendResult.cpp                         |   11 +-
 src/{common => extern}/MQClientErrorContainer.cpp  |    0
 src/{common => extern}/MQClientErrorContainer.h    |    1 -
 src/log/Logging.cpp                                |  121 +-
 src/log/Logging.h                                  |  124 +-
 src/message/BatchMessage.cpp                       |   62 -
 src/message/MQDecoder.cpp                          |  578 ++++----
 src/message/MQDecoder.h                            |   37 +-
 src/message/MQMessage.cpp                          |  266 ++--
 src/message/MQMessageExt.cpp                       |  187 +--
 src/message/MQMessageId.h                          |   20 +-
 src/message/MQMessageQueue.cpp                     |   10 +-
 src/message/MessageAccessor.h                      |   51 +
 src/message/MessageBatch.cpp                       |   63 +
 .../TopAddressing.h => message/MessageBatch.h}     |   39 +-
 .../MessageClientIDSetter.cpp}                     |   63 +-
 .../MessageClientIDSetter.h}                       |   45 +-
 src/producer/DefaultMQProducer.cpp                 |  635 ++-------
 src/producer/DefaultMQProducerImpl.cpp             |  767 +++++++++++
 src/producer/DefaultMQProducerImpl.h               |  155 +++
 src/producer/LatencyFaultTolerancyImpl.cpp         |   94 ++
 src/producer/LatencyFaultTolerancyImpl.h           |   87 ++
 src/producer/MQFaultStrategy.cpp                   |   82 ++
 src/producer/MQFaultStrategy.h                     |   66 +
 .../producer/MQProducerInner.h                     |   77 +-
 src/producer/SendResult.cpp                        |   29 +-
 src/producer/TopicPublishInfo.h                    |  270 +---
 src/producer/TransactionMQProducer.cpp             |  200 +--
 src/protocol/CommandHeader.cpp                     | 1447 +++++++++++---------
 src/protocol/CommandHeader.h                       |  656 ++++-----
 src/protocol/ConsumerRunningInfo.cpp               |  106 +-
 src/protocol/ConsumerRunningInfo.h                 |   86 +-
 src/protocol/HeartbeatData.h                       |   98 +-
 src/protocol/KVTable.h                             |   21 +-
 src/protocol/LockBatchBody.cpp                     |  147 +-
 src/protocol/LockBatchBody.h                       |   78 +-
 src/protocol/MQProtos.h                            |  397 +++---
 src/protocol/MessageQueue.cpp                      |   96 +-
 src/protocol/MessageQueue.h                        |   85 +-
 src/protocol/ProcessQueueInfo.h                    |  132 +-
 src/protocol/RemotingCommand.cpp                   |  354 ++---
 src/protocol/RemotingCommand.h                     |   97 --
 src/protocol/RemotingSerializable.cpp              |   91 ++
 src/protocol/RemotingSerializable.h                |   45 +-
 src/protocol/TopicList.h                           |   20 +-
 src/protocol/TopicRouteData.h                      |   62 +-
 src/thread/disruptor/batch_descriptor.h            |   70 -
 src/thread/disruptor/claim_strategy.h              |  231 ----
 src/thread/disruptor/event_processor.h             |  130 --
 src/thread/disruptor/event_publisher.h             |   50 -
 src/thread/disruptor/exception_handler.h           |   59 -
 src/thread/disruptor/exceptions.h                  |   38 -
 src/thread/disruptor/interface.h                   |  278 ----
 src/thread/disruptor/ring_buffer.h                 |   90 --
 src/thread/disruptor/sequence.h                    |  139 --
 src/thread/disruptor/sequence_barrier.h            |   92 --
 src/thread/disruptor/sequencer.h                   |  190 ---
 src/thread/disruptor/utils.h                       |   35 -
 src/thread/disruptor/wait_strategy.h               |  372 -----
 src/thread/disruptorLFQ.h                          |  117 --
 src/thread/task_queue.cpp                          |  105 --
 src/thread/task_queue.h                            |  745 ----------
 src/transport/ClientRemotingProcessor.cpp          |  193 ---
 src/transport/ClientRemotingProcessor.h            |   67 -
 src/transport/EventLoop.cpp                        |  137 +-
 src/transport/EventLoop.h                          |   48 +-
 .../transport/RequestProcessor.h                   |   20 +-
 src/transport/ResponseFuture.cpp                   |  176 +--
 src/transport/ResponseFuture.h                     |   90 +-
 src/transport/SocketUtil.cpp                       |  182 ++-
 src/transport/SocketUtil.h                         |   59 +-
 src/transport/TcpRemotingClient.cpp                |  861 ++++++------
 src/transport/TcpRemotingClient.h                  |  150 +-
 src/transport/TcpTransport.cpp                     |  258 ++--
 src/transport/TcpTransport.h                       |   57 +-
 test/CMakeLists.txt                                |   63 +-
 test/src/{message => }/BatchMessageTest.cpp        |    0
 test/src/MQClientAPIImpTest.cpp                    |  197 ---
 test/src/MQClientFactoryTest.cpp                   |  106 --
 test/src/MQClientManagerTest.cpp                   |   49 -
 test/src/{producer => }/StringIdMakerTest.cpp      |    0
 test/src/common/MQVersionTest.cpp                  |   45 -
 test/src/common/UrlTest.cpp                        |   76 -
 test/src/common/VirtualEnvUtilTest.cpp             |   33 +-
 test/src/extern/CMessageTest.cpp                   |   32 +-
 test/src/extern/CProducerTest.cpp                  |   41 +-
 test/src/extern/CPullConsumerTest.cpp              |   37 +-
 test/src/extern/CPushConsumerTest.cpp              |    4 -
 test/src/message/MQDecoderTest.cpp                 |   17 +-
 test/src/message/MQMessageExtTest.cpp              |    2 +-
 test/src/message/MQMessageTest.cpp                 |   12 +-
 test/src/protocol/CommandHeaderTest.cpp            |  368 +----
 test/src/protocol/ConsumerRunningInfoTest.cpp      |  123 +-
 test/src/protocol/LockBatchBodyTest.cpp            |   22 +-
 test/src/transport/ClientRemotingProcessorTest.cpp |    5 +-
 299 files changed, 19070 insertions(+), 21931 deletions(-)

diff --git a/.gitignore b/.gitignore
index 22c7350..327bb7c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,15 @@
-.idea
+# clion
+.idea/
+
+# visual studio code
+.vscode/
+.VSCodeCounter
+
+# cmake
 cmake-build-debug/
+
+# project
 bin
 build
 libs/signature/lib
 tmp_*
-Testing
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c70b7e7..49e6a4d 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -37,72 +37,28 @@ project(rocketmq-client-cpp)
 if (NOT CMAKE_BUILD_TYPE)
     set(CMAKE_BUILD_TYPE "Release")
 endif ()
-set(CMAKE_CONFIGURATION_TYPES "Release")
+if (NOT CMAKE_CONFIGURATION_TYPES)
+    set(CMAKE_CONFIGURATION_TYPES "Release")
+endif ()
 set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
 set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)
 set(CMAKE_VERBOSE_MAKEFILE 1)
-option(BUILD_ROCKETMQ_STATIC "build rocketmq-client static library" ON)
-option(BUILD_ROCKETMQ_SHARED "build rocketmq-client shared library" ON)
-
-#Find dependency 
-option(Boost_USE_STATIC_LIBS "only find boost static libs" ON) # only find static libs
-set(Boost_USE_MULTITHREADED ON)
-set(Boost_USE_STATIC_RUNTIME ON)
-if (WIN32)
-    find_package(Boost 1.56 REQUIRED COMPONENTS atomic thread system chrono date_time
-            log log_setup regex serialization filesystem locale iostreams zlib)
-    if (Boost_FOUND)
-        message(STATUS "** Boost Include dir: ${Boost_INCLUDE_DIR}")
-        message(STATUS "** Boost Libraries dir: ${Boost_LIBRARY_DIRS}")
-        message(STATUS "** Boost Libraries: ${Boost_LIBRARIES}")
-        include_directories(${Boost_INCLUDE_DIRS})
-    endif ()
-else ()
-    #find_package(Boost 1.56 REQUIRED COMPONENTS atomic thread system chrono date_time log log_setup regex serialization filesystem locale iostreams) 
-    set(Boost_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/bin/include)
-    set(Boost_LIBRARY_DIRS ${PROJECT_SOURCE_DIR}/bin/lib)
-    set(Boost_LIBRARIES ${Boost_LIBRARY_DIRS}/libboost_atomic.a;${Boost_LIBRARY_DIRS}/libboost_thread.a;${Boost_LIBRARY_DIRS}/libboost_system.a;${Boost_LIBRARY_DIRS}/libboost_chrono.a;
-            ${Boost_LIBRARY_DIRS}/libboost_date_time.a;${Boost_LIBRARY_DIRS}/libboost_log.a;${Boost_LIBRARY_DIRS}/libboost_log_setup.a;
-            ${Boost_LIBRARY_DIRS}/libboost_regex.a;${Boost_LIBRARY_DIRS}/libboost_serialization.a;${Boost_LIBRARY_DIRS}/libboost_filesystem.a;
-            ${Boost_LIBRARY_DIRS}/libboost_locale.a;${Boost_LIBRARY_DIRS}/libboost_iostreams.a)
-    include_directories(${Boost_INCLUDE_DIRS})
-endif ()
 
-message(STATUS "** Boost_INCLUDE_DIR: ${Boost_INCLUDE_DIR}")
-message(STATUS "** Boost_LIBRARIES: ${Boost_LIBRARIES}")
+option(BUILD_ROCKETMQ_STATIC "build rocketmq-client static library" OFF)
+option(BUILD_ROCKETMQ_SHARED "build rocketmq-client shared library" ON)
 
-option(Libevent_USE_STATIC_LIBS "only find libevent static libs" ON) # only find static libs
-if (WIN32)
-    find_package(Libevent 2.0.22 REQUIRED COMPONENTS)
-    if (LIBEVENT_FOUND)
-        include_directories(${LIBEVENT_INCLUDE_DIRS})
-        message(STATUS "** libevent Include dir: ${LIBEVENT_INCLUDE_DIR}")
-        message(STATUS "** libevent Libraries: ${LIBEVENT_LIBRARIES}")
-    endif ()
-else ()
-    #find_package(Libevent 2.0.22 REQUIRED COMPONENTS)
-    set(LIBEVENT_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/bin/include)
-    set(LIBEVENT_LIBRARIES_DIR ${PROJECT_SOURCE_DIR}/bin/lib)
-    set(LIBEVENT_LIBRARIES ${LIBEVENT_LIBRARIES_DIR}/libevent.a;${LIBEVENT_LIBRARIES_DIR}/libevent_core.a;${LIBEVENT_LIBRARIES_DIR}/libevent_extra.a;${LIBEVENT_LIBRARIES_DIR}/libevent_pthreads.a)
-    include_directories(${LIBEVENT_INCLUDE_DIRS})
-endif ()
+# Find dependency
+#find_package(spdlog REQUIRED)
 
+option(Libevent_USE_STATIC_LIBS "only find libevent static libs" OFF) # only find static libs
+find_package(Libevent 2.0.21 REQUIRED)
+include_directories(${LIBEVENT_INCLUDE_DIRS})
 message(STATUS "** LIBEVENT_INCLUDE_DIR: ${LIBEVENT_INCLUDE_DIR}")
 message(STATUS "** LIBEVENT_LIBRARIES: ${LIBEVENT_LIBRARIES}")
 
-option(JSONCPP_USE_STATIC_LIBS "only find jsoncpp static libs" ON) # only find static libs
-if (WIN32)
-    find_package(Jsoncpp 0.10.6)
-    if (JSONCPP_FOUND)
-        include_directories(${JSONCPP_INCLUDE_DIRS})
-    endif ()
-else ()
-    set(JSONCPP_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/bin/include/jsoncpp)
-    set(JSONCPP_LIBRARIES_DIR ${PROJECT_SOURCE_DIR}/bin/lib)
-    set(JSONCPP_LIBRARIES ${JSONCPP_LIBRARIES_DIR}/libjsoncpp.a)
-    include_directories(${JSONCPP_INCLUDE_DIRS})
-endif ()
-
+option(JSONCPP_USE_STATIC_LIBS "only find jsoncpp static libs" OFF) # only find static libs
+find_package(Jsoncpp 0.10.6 REQUIRED)
+include_directories(${JSONCPP_INCLUDE_DIRS})
 message(STATUS "** JSONCPP_INCLUDE_DIRS: ${JSONCPP_INCLUDE_DIRS}")
 message(STATUS "** JSONCPP_LIBRARIES: ${JSONCPP_LIBRARIES}")
 
@@ -126,14 +82,12 @@ IF (WIN32)
     set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
 ELSE ()
     set(C_FLAGS
-            #-g
             -Wall
             -Wno-deprecated
             -fPIC
             -fno-strict-aliasing
             )
     set(CXX_FLAGS
-            #-g
             -Wall
             -Wno-deprecated
             -fPIC
@@ -173,8 +127,8 @@ ELSE ()
     string(REPLACE ";" " " CMAKE_CXX_FLAGS "${CXX_FLAGS}")
     string(REPLACE ";" " " CMAKE_C_FLAGS "${C_FLAGS}")
 
-    set(CMAKE_CXX_FLAGS_DEBUG "-O0 -DDEBUG")
-    set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
+    set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DDEBUG")
+    set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
 
 
     # Declare deplibs, so we can use list in linker later. There's probably
@@ -191,24 +145,7 @@ ELSE ()
         list(APPEND deplibs rt)
     endif ()
     list(APPEND deplibs z)
-    # Code Coverage Configuration
-    add_library(coverage_config INTERFACE)
-
-    option(CODE_COVERAGE "Enable coverage reporting" OFF)
-    if (CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
-        # Add required flags (GCC & LLVM/Clang)
-        target_compile_options(coverage_config INTERFACE
-                -O0        # no optimization
-                -g         # generate debug info
-                --coverage # sets all required flags
-                )
-        if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.13)
-            target_link_options(coverage_config INTERFACE --coverage)
-        else ()
-            target_link_libraries(coverage_config INTERFACE --coverage)
-        endif ()
-        list(APPEND deplibs coverage_config)
-    endif (CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
+
     # add include dir for bsd (posix uses /usr/include/)
     set(CMAKE_INCLUDE_PATH "${CMAKE_INCLUDE_PATH}:/usr/local/include")
 ENDIF ()
@@ -242,8 +179,7 @@ add_subdirectory(example)
 option(RUN_UNIT_TEST "RUN_UNIT_TEST" OFF)
 
 if (RUN_UNIT_TEST)
-    message(STATUS "** RUN_UNIT_TEST: ${RUN_UNIT_TEST} Do execution testing")
-    enable_testing()
+    message(STATUS "** RUN_UNIT_TEST: Do execution testing")
     add_subdirectory(test)
 endif ()
 
diff --git a/README.md b/README.md
index 9c337a4..511a59c 100644
--- a/README.md
+++ b/README.md
@@ -1,78 +1,158 @@
-# RocketMQ-Client-CPP
-[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
-[![TravisCI](https://travis-ci.org/apache/rocketmq-client-cpp.svg)](https://travis-ci.org/apache/rocketmq-client-cpp)
-[![CodeCov](https://codecov.io/gh/apache/rocketmq-client-cpp/branch/master/graph/badge.svg)](https://codecov.io/gh/apache/rocketmq-client-cpp)
-[![GitHub release](https://img.shields.io/badge/release-download-default.svg)](https://github.com/apache/rocketmq-client-cpp/releases)
-[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/apache/rocketmq-client-cpp.svg)](http://isitmaintained.com/project/apache/rocketmq-client-cpp "Average time to resolve an issue")
-[![Percentage of issues still open](http://isitmaintained.com/badge/open/apache/rocketmq-client-cpp.svg)](http://isitmaintained.com/project/apache/rocketmq-client-cpp "Percentage of issues still open")
-![Twitter Follow](https://img.shields.io/twitter/follow/ApacheRocketMQ?style=social)
-
-RocketMQ-Client-CPP is the C/C++ client of Apache RocketMQ, a distributed messaging and streaming platform with low latency, high performance and reliability, trillion-level capacity and flexible scalability.
-
-## Features
-
-- produce messages, including normal and delayed messages, synchronously or asynchronously. 
-- consume messages, in cluster or broadcast model, concurrently or orderly
-- c and c++ style API.
-- cross-platform, all features are supported on Windows, Linux and Mac OS.
-- automatically rebalanced, both in producing and consuming process.
-- reliability, any downtime broker or name server has no impact on the client.
-
-## Build and Install
-
-### Linux and Mac OS
-
-**note**: make sure the following compile tools or libraries have been installed before running the build script **build.sh**.
-
-- compile tools:
-	- gcc-c++ 4.8.2: c++ compiler while need support C++11
-	- cmake 2.8.0: build jsoncpp require it
-	- automake 1.11.1: build libevent require it
-	- autoconf 2.65: build libevent require it
-	- libtool 2.2.6: build libevent require it
-
-- libraries:   
-	- bzip2-devel 1.0.6: boost depend it
-	- zlib-devel
-
-The **build.sh** script will automatically download and build the dependency libraries including libevent, json and boost. It will save libraries under rocketmq-client-cpp folder, and then build both static and shared libraries for rocketmq-client. If the dependent libraries are built failed, you could try to build it manually with sources [libevent 2.0.22](https://github.com/libevent/libevent/archive/release-2.0.22-stable.zip "lib event 2.0.22"), [jsoncpp 0.10.6](https://github.com/open [...]
-
-If your host is not available to internet to download the three library source files, you can copy the three library source files (release-2.0.22-stable.zip  0.10.6.zip and boost_1_58_0.tar.gz) to rocketmq-client-cpp root dir, then the build.sh will automatically use the three library source files to build rocketmq-client-cpp:
-
-    sh build.sh
-
-Finally, both librocketmq.a and librocketmq.so are saved in rocketmq-client-cpp/bin. when using them to build application or library, besides rocketmq you should also link with following libraries -lpthread -lz -ldl -lrt. Here is an example:
-
-    g++ -o consumer_example consumer_example.cpp -lrocketmq -lpthread -lz -ldl -lrt
-
-### Windows
-**note**: make sure the following compile tools or libraries have been installed before running the build script **win32_build.bat**:
-
-- compile tools:
-	- vs2015: libevent,jsoncpp,zlib,boost rocket-client require it
-	- git: download source code 
-	
-The build script will automatically download dependent libraries including libevent json and boost to build shared library:
-
-    win32_build.bat
-
-	
-If your host is not available to internet to download the four library source files by build script, you can copy the four library source files 
-
-[zlib-1.2.3-src](https://codeload.github.com/jsj020122/zlib-1.2.3-src/zip/master "zlib-1.2.3-src") Extract to $(rocketmq-client-cpp root dir)/thirdparty/zlib-1.2.3-src 
-
-[libevent-release-2.0.22](https://codeload.github.com/jsj020122/libevent-release-2.0.22/zip/master "libevent-release-2.0.22") Extract to $(rocketmq-client-cpp root dir)/thirdparty/libevent-release-2.0.22
-
-[boost_1_58_0](https://codeload.github.com/jsj020122/boost_1_58_0/zip/master "boost_1_58_0") Extract to  $(rocketmq-client-cpp root dir)/thirdparty/boost_1_58_0
-
-[jsoncpp-0.10.6](https://codeload.github.com/jsj020122/jsoncpp-0.10.6/zip/master "jsoncpp-0.10.6") Extract to  $(rocketmq-client-cpp root dir)/thirdparty/jsoncpp-0.10.6 
-
-And then run following command to build x86 rocketmq-client:
-
-    win32_build.bat build
-
-to build x64 rocketmq-client:
-
-    win32_build.bat build64
-
-
+# RocketMQ-Client-CPP
+[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
+[![TravisCI](https://travis-ci.org/apache/rocketmq-client-cpp.svg)](https://travis-ci.org/apache/rocketmq-client-cpp)
+[![CodeCov](https://codecov.io/gh/apache/rocketmq-client-cpp/branch/master/graph/badge.svg)](https://codecov.io/gh/apache/rocketmq-client-cpp)
+[![GitHub release](https://img.shields.io/badge/release-download-default.svg)](https://github.com/apache/rocketmq-client-cpp/releases)
+[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/apache/rocketmq-client-cpp.svg)](http://isitmaintained.com/project/apache/rocketmq-client-cpp "Average time to resolve an issue")
+[![Percentage of issues still open](http://isitmaintained.com/badge/open/apache/rocketmq-client-cpp.svg)](http://isitmaintained.com/project/apache/rocketmq-client-cpp "Percentage of issues still open")
+![Twitter Follow](https://img.shields.io/twitter/follow/ApacheRocketMQ?style=social)
+
+RocketMQ-Client-CPP is the C/C++ client of Apache RocketMQ, a distributed messaging and streaming platform with low latency, high performance and reliability, trillion-level capacity and flexible scalability.
+
+## Features
+
+- produce messages, including normal and delayed messages, synchronously or asynchronously. 
+- consume messages, in cluster or broadcast model, concurrently or orderly
+- c and c++ style API.
+- cross-platform, all features are supported on Windows, Linux and Mac OS.
+- automatically rebalanced, both in producing and consuming process.
+- reliability, any downtime broker or name server has no impact on the client.
+
+## Build and Install
+
+### CentOS
+
+```bash
+# install toolchain
+yum install -y gcc gcc-c++ cmake
+
+# install dependencies
+yum install -y spdlog-devel libevent-devel jsoncpp-devel zlib-devel
+
+# configure porject
+mkdir build && cd build
+cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local \
+  -DLibevent_USE_STATIC_LIBS=OFF -DJSONCPP_USE_STATIC_LIBS=OFF \
+  -DBUILD_ROCKETMQ_STATIC=OFF -DBUILD_ROCKETMQ_SHARED=ON \
+  -DRUN_UNIT_TEST=OFF ..
+
+# build librocketmq.so
+make rocketmq_shared -j 6
+
+# build example: SyncProducer, PushConsumer, etc.
+make SyncProducer
+make PushConsumer
+```
+
+If encounter error about "fmt/format.h" header file, modify "printf.h" as shown below.
+
+```bash
+sed -i "s/#include \"fmt\/format.h\"/#include \"format.h\"/" /usr/include/spdlog/fmt/bundled/printf.h
+```
+
+### Ubuntu
+
+```bash
+# install toolchain
+apt install -y gcc g++ cmake
+
+# install dependencies
+apt install -y libspdlog-dev libevent-dev libjsoncpp-dev zlib1g-dev
+
+# configure porject
+mkdir build && cd build
+cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local \
+  -DLibevent_USE_STATIC_LIBS=OFF -DJSONCPP_USE_STATIC_LIBS=OFF \
+  -DBUILD_ROCKETMQ_STATIC=OFF -DBUILD_ROCKETMQ_SHARED=ON \
+  -DRUN_UNIT_TEST=OFF ..
+
+# build librocketmq.so
+make rocketmq_shared -j 6
+
+# build example: SyncProducer, PushConsumer, etc.
+make SyncProducer
+make PushConsumer
+```
+
+### macOS
+
+```bash
+# install toolchain
+brew install cmake
+
+# dependencies
+brew install spdlog libevent jsoncpp zlib
+
+# configure porject
+mkdir build && cd build
+cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local \
+  -DLibevent_USE_STATIC_LIBS=OFF -DJSONCPP_USE_STATIC_LIBS=OFF \
+  -DBUILD_ROCKETMQ_STATIC=OFF -DBUILD_ROCKETMQ_SHARED=ON \
+  -DRUN_UNIT_TEST=OFF ..
+
+# build librocketmq.so
+make rocketmq_shared -j 4
+
+# build example: SyncProducer, PushConsumer, etc.
+make SyncProducer
+make PushConsumer
+```
+
+## Build and Install (Old SDK)
+
+### Linux and Mac OS
+
+**note**: make sure the following compile tools or libraries have been installed before running the build script **build.sh**.
+
+- compile tools:
+	- gcc-c++ 4.8.2: c++ compiler while need support C++11
+	- cmake 2.8.0: build jsoncpp require it
+	- automake 1.11.1: build libevent require it
+	- autoconf 2.65: build libevent require it
+	- libtool 2.2.6: build libevent require it
+
+- libraries:   
+	- bzip2-devel 1.0.6: boost depend it
+	- zlib-devel
+
+The **build.sh** script will automatically download and build the dependency libraries including libevent, json and boost. It will save libraries under rocketmq-client-cpp folder, and then build both static and shared libraries for rocketmq-client. If the dependent libraries are built failed, you could try to build it manually with sources [libevent 2.0.22](https://github.com/libevent/libevent/archive/release-2.0.22-stable.zip "lib event 2.0.22"), [jsoncpp 0.10.6](https://github.com/open [...]
+
+If your host is not available to internet to download the three library source files, you can copy the three library source files (release-2.0.22-stable.zip  0.10.6.zip and boost_1_58_0.tar.gz) to rocketmq-client-cpp root dir, then the build.sh will automatically use the three library source files to build rocketmq-client-cpp:
+
+    sh build.sh
+
+Finally, both librocketmq.a and librocketmq.so are saved in rocketmq-client-cpp/bin. when using them to build application or library, besides rocketmq you should also link with following libraries -lpthread -lz -ldl -lrt. Here is an example:
+
+    g++ -o consumer_example consumer_example.cpp -lrocketmq -lpthread -lz -ldl -lrt
+
+### Windows
+**note**: make sure the following compile tools or libraries have been installed before running the build script **win32_build.bat**:
+
+- compile tools:
+	- vs2015: libevent,jsoncpp,zlib,boost rocket-client require it
+	- git: download source code 
+	
+The build script will automatically download dependent libraries including libevent json and boost to build shared library:
+
+    win32_build.bat
+
+	
+If your host is not available to internet to download the four library source files by build script, you can copy the four library source files 
+
+[zlib-1.2.3-src](https://codeload.github.com/jsj020122/zlib-1.2.3-src/zip/master "zlib-1.2.3-src") Extract to $(rocketmq-client-cpp root dir)/thirdparty/zlib-1.2.3-src 
+
+[libevent-release-2.0.22](https://codeload.github.com/jsj020122/libevent-release-2.0.22/zip/master "libevent-release-2.0.22") Extract to $(rocketmq-client-cpp root dir)/thirdparty/libevent-release-2.0.22
+
+[boost_1_58_0](https://codeload.github.com/jsj020122/boost_1_58_0/zip/master "boost_1_58_0") Extract to  $(rocketmq-client-cpp root dir)/thirdparty/boost_1_58_0
+
+[jsoncpp-0.10.6](https://codeload.github.com/jsj020122/jsoncpp-0.10.6/zip/master "jsoncpp-0.10.6") Extract to  $(rocketmq-client-cpp root dir)/thirdparty/jsoncpp-0.10.6 
+
+And then run following command to build x86 rocketmq-client:
+
+    win32_build.bat build
+
+to build x64 rocketmq-client:
+
+    win32_build.bat build64
+
+
diff --git a/cmake/BundleStaticLibrary.cmake b/cmake/BundleStaticLibrary.cmake
new file mode 100644
index 0000000..4ab9a24
--- /dev/null
+++ b/cmake/BundleStaticLibrary.cmake
@@ -0,0 +1,134 @@
+# 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.
+
+# ref: https://cristianadam.eu/20190501/bundling-together-static-libraries-with-cmake/
+
+set(STATIC_LIBRARY_REGEX "${CMAKE_STATIC_LIBRARY_SUFFIX}")
+string(REPLACE ".", "\\.", STATIC_LIBRARY_REGEX ${STATIC_LIBRARY_REGEX})
+set(STATIC_LIBRARY_REGEX "^.+${STATIC_LIBRARY_REGEX}$")
+
+function(bundle_static_library tgt_name bundled_tgt_name)
+  list(APPEND static_libs ${tgt_name})
+  set(static_libraries)
+
+  function(_recursively_collect_dependencies input_target)
+    set(_input_link_libraries LINK_LIBRARIES)
+    get_target_property(_input_type ${input_target} TYPE)
+    if(${_input_type} STREQUAL "INTERFACE_LIBRARY")
+      set(_input_link_libraries INTERFACE_LINK_LIBRARIES)
+    endif()
+    get_target_property(public_dependencies ${input_target}
+                        ${_input_link_libraries})
+    foreach(dependency IN LISTS public_dependencies)
+      if(TARGET ${dependency})
+        get_target_property(alias ${dependency} ALIASED_TARGET)
+        if(TARGET ${alias})
+          set(dependency ${alias})
+        endif()
+        get_target_property(_type ${dependency} TYPE)
+        if(${_type} STREQUAL "STATIC_LIBRARY")
+          list(APPEND static_libs ${dependency})
+        endif()
+
+        get_property(library_already_added GLOBAL
+                     PROPERTY _${tgt_name}_static_bundle_${dependency})
+        if(NOT library_already_added)
+          set_property(GLOBAL PROPERTY _${tgt_name}_static_bundle_${dependency}
+                                       ON)
+          _recursively_collect_dependencies(${dependency})
+        endif()
+      else()
+        string(REGEX MATCH ${STATIC_LIBRARY_REGEX} IS_STATIC_LIBRARY ${dependency})
+        if(IS_STATIC_LIBRARY)
+          list(APPEND static_libs ${dependency})
+        endif()
+      endif()
+    endforeach()
+    set(static_libs
+        ${static_libs}
+        PARENT_SCOPE)
+  endfunction()
+
+  _recursively_collect_dependencies(${tgt_name})
+
+  list(REMOVE_DUPLICATES static_libs)
+
+  set(bundled_tgt_full_name
+      ${LIBRARY_OUTPUT_PATH}/${CMAKE_STATIC_LIBRARY_PREFIX}${bundled_tgt_name}${CMAKE_STATIC_LIBRARY_SUFFIX}
+  )
+
+  if(CMAKE_CXX_COMPILER_ID MATCHES "^(Clang|GNU)$")
+    file(WRITE ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri.in
+         "CREATE ${bundled_tgt_full_name}\n")
+
+    foreach(tgt IN LISTS static_libs)
+      if(TARGET ${tgt})
+        file(APPEND ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri.in
+             "ADDLIB $<TARGET_FILE:${tgt}>\n")
+      else()
+        file(APPEND ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri.in
+             "ADDLIB ${tgt}\n")
+      endif()
+    endforeach()
+
+    file(APPEND ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri.in "SAVE\n")
+    file(APPEND ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri.in "END\n")
+
+    file(
+      GENERATE
+      OUTPUT ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri
+      INPUT ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri.in)
+
+    set(ar_tool ${CMAKE_AR})
+    if(CMAKE_INTERPROCEDURAL_OPTIMIZATION)
+      set(ar_tool ${CMAKE_CXX_COMPILER_AR})
+    endif()
+
+    message(
+      STATUS "** Bundled static library: ${bundled_tgt_full_name}")
+    add_custom_command(
+      OUTPUT ${bundled_tgt_full_name}
+      COMMAND ${ar_tool} -M < ${CMAKE_BINARY_DIR}/${bundled_tgt_name}.mri
+      COMMENT "Bundling ${bundled_tgt_name}"
+      VERBATIM)
+  elseif(MSVC)
+    find_program(lib_tool lib)
+
+    foreach(tgt IN LISTS static_libs)
+      list(APPEND static_libs_full_names $<TARGET_FILE:${tgt}>)
+    endforeach()
+
+    add_custom_command(
+      OUTPUT ${bundled_tgt_full_name}
+      COMMAND ${lib_tool} /NOLOGO /OUT:${bundled_tgt_full_name}
+              ${static_libs_full_names}
+      COMMENT "Bundling ${bundled_tgt_name}"
+      VERBATIM)
+  else()
+    message(FATAL_ERROR "Unknown bundle scenario!")
+  endif()
+
+  add_custom_target("${bundled_tgt_name}_" ALL DEPENDS ${bundled_tgt_full_name})
+  add_dependencies("${bundled_tgt_name}_" ${tgt_name})
+
+  add_library(${bundled_tgt_name} STATIC IMPORTED)
+  set_target_properties(
+    ${bundled_tgt_name}
+    PROPERTIES IMPORTED_LOCATION ${bundled_tgt_full_name}
+               INTERFACE_INCLUDE_DIRECTORIES
+               $<TARGET_PROPERTY:${tgt_name},INTERFACE_INCLUDE_DIRECTORIES>)
+  add_dependencies(${bundled_tgt_name} "${bundled_tgt_name}_")
+
+endfunction()
diff --git a/cmake/FindJsoncpp.cmake b/cmake/FindJsoncpp.cmake
index 9632118..cdef2b1 100755
--- a/cmake/FindJsoncpp.cmake
+++ b/cmake/FindJsoncpp.cmake
@@ -30,66 +30,70 @@
 #  JSONCPP_LIBRARIES, where to find the jsoncpp library.
 
 # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
-if( JSONCPP_USE_STATIC_LIBS )
-  set(_jsoncpp_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES    :${CMAKE_FIND_LIBRARY_SUFFIXES})
-    if(WIN32)
+if (JSONCPP_USE_STATIC_LIBS)
+    set(_jsoncpp_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES :${CMAKE_FIND_LIBRARY_SUFFIXES})
+    if (WIN32)
         list(INSERT CMAKE_FIND_LIBRARY_SUFFIXES 0 .lib .a)
-    else()
+    else ()
         set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
-    endif()
-else()
-  set(_jsoncpp_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES    :${CMAKE_FIND_LIBRARY_SUFFIXES})
-    if(WIN32)
+    endif ()
+else ()
+    set(_jsoncpp_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES :${CMAKE_FIND_LIBRARY_SUFFIXES})
+    if (WIN32)
         list(INSERT CMAKE_FIND_LIBRARY_SUFFIXES 0 .dll .so)
-    else()
+    elseif (APPLE)
+        set(CMAKE_FIND_LIBRARY_SUFFIXES .dylib)
+    else ()
         set(CMAKE_FIND_LIBRARY_SUFFIXES .so)
-    endif()
-endif()
+    endif ()
+endif ()
 
-FIND_PATH(JSONCPP_INCLUDE_DIRS 
-NAMES
-	json.h
-	json/json.h
-PATHS
-    ${CMAKE_SOURCE_DIR}/bin/include
-    C:/jsoncpp/include
-    ${CMAKE_SOURCE_DIR}/win32-deps/include
-    C:/jsoncpp-0.10.6/include
-PATH_SUFFIXES jsoncpp
-)
+set(JSONCPP_INCLUDE_SEARCH_PATH ${CMAKE_SOURCE_DIR}/bin/include /usr/local/include C:/jsoncpp/include
+        ${CMAKE_SOURCE_DIR}/win32-deps/include C:/jsoncpp-0.10.6/include)
+set(JSONCPP_LIBRARIE_SEARCH_PATH ${CMAKE_SOURCE_DIR}/bin/lib /usr/local/lib C:/jsoncpp/lib
+        ${CMAKE_SOURCE_DIR}/win32-deps/lib C:/jsoncpp-0.10.6/)
+if (JSONCPP_ROOT)
+    list(INSERT JSONCPP_INCLUDE_SEARCH_PATH 0 ${JSONCPP_ROOT}/include)
+    list(INSERT JSONCPP_LIBRARIE_SEARCH_PATH 0 ${JSONCPP_ROOT}/lib)
+endif ()
+
+find_path(JSONCPP_INCLUDE_DIRS
+        NAMES json.h json/json.h
+        PATHS ${JSONCPP_INCLUDE_SEARCH_PATH}
+        PATH_SUFFIXES jsoncpp)
 
 find_library(JSONCPP_LIBRARIES
-    NAMES jsoncpp
-    PATHS ${CMAKE_SOURCE_DIR}/bin/lib C:/jsoncpp/lib ${CMAKE_SOURCE_DIR}/win32-deps/lib C:/jsoncpp-0.10.6/
-)
+        NAMES jsoncpp
+        PATHS ${JSONCPP_LIBRARIE_SEARCH_PATH})
+
 IF (JSONCPP_LIBRARIES AND JSONCPP_INCLUDE_DIRS)
     SET(JSONCPP_LIBRARIES ${JSONCPP_LIBRARIES})
     SET(JSONCPP_FOUND "YES")
 ELSE (JSONCPP_LIBRARIES AND JSONCPP_INCLUDE_DIRS)
-  SET(JSONCPP_FOUND "NO")
+    SET(JSONCPP_FOUND "NO")
 ENDIF (JSONCPP_LIBRARIES AND JSONCPP_INCLUDE_DIRS)
 
 
 IF (JSONCPP_FOUND)
-   IF (NOT JSONCPP_FIND_QUIETLY)
-      MESSAGE(STATUS "Found JSONCpp: ${JSONCPP_LIBRARIES}")
-   ENDIF (NOT JSONCPP_FIND_QUIETLY)
+    IF (NOT JSONCPP_FIND_QUIETLY)
+        MESSAGE(STATUS "Found JSONCpp: ${JSONCPP_LIBRARIES}")
+    ENDIF (NOT JSONCPP_FIND_QUIETLY)
 ELSE (JSONCPP_FOUND)
-   IF (JSONCPP_FIND_REQUIRED)
-      MESSAGE(FATAL_ERROR "Could not find JSONCPP library include: ${JSONCPP_INCLUDE_DIRS}, lib: ${JSONCPP_LIBRARIES}")
-   ENDIF (JSONCPP_FIND_REQUIRED)
+    IF (JSONCPP_FIND_REQUIRED)
+        MESSAGE(FATAL_ERROR "Could not find JSONCPP library include: ${JSONCPP_INCLUDE_DIRS}, lib: ${JSONCPP_LIBRARIES}")
+    ENDIF (JSONCPP_FIND_REQUIRED)
 ENDIF (JSONCPP_FOUND)
 
 # Deprecated declarations.
-SET (NATIVE_JSONCPP_INCLUDE_PATH ${JSONCPP_INCLUDE_DIRS} )
-GET_FILENAME_COMPONENT (NATIVE_JSONCPP_LIB_PATH ${JSONCPP_LIBRARIES} PATH)
+SET(NATIVE_JSONCPP_INCLUDE_PATH ${JSONCPP_INCLUDE_DIRS})
+GET_FILENAME_COMPONENT(NATIVE_JSONCPP_LIB_PATH ${JSONCPP_LIBRARIES} PATH)
 
 MARK_AS_ADVANCED(
-  JSONCPP_LIBRARIES
-  JSONCPP_INCLUDE_DIRS
-  )
+        JSONCPP_LIBRARIES
+        JSONCPP_INCLUDE_DIRS
+)
 
 # Restore the original find library ordering
-if( JSONCPP_USE_STATIC_LIBS )
-  set(CMAKE_FIND_LIBRARY_SUFFIXES ${_jsoncpp_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
-endif()
+if (JSONCPP_USE_STATIC_LIBS)
+    set(CMAKE_FIND_LIBRARY_SUFFIXES ${_jsoncpp_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
+endif ()
diff --git a/cmake/FindLibevent.cmake b/cmake/FindLibevent.cmake
index c013d49..0165e70 100755
--- a/cmake/FindLibevent.cmake
+++ b/cmake/FindLibevent.cmake
@@ -41,112 +41,125 @@ find_package(PkgConfig QUIET)
 pkg_check_modules(PC_LIBEVENT QUIET libevent)
 
 # Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
-if( Libevent_USE_STATIC_LIBS )
-  set(_libevent_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES    :${CMAKE_FIND_LIBRARY_SUFFIXES})                                                                       
-    if(WIN32)
+if (Libevent_USE_STATIC_LIBS)
+    set(_libevent_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES :${CMAKE_FIND_LIBRARY_SUFFIXES})
+    if (WIN32)
         list(INSERT CMAKE_FIND_LIBRARY_SUFFIXES 0 .lib .a)
-    else()
+    else ()
         set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
-    endif()
-else()
-  set(_libevent_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES    :${CMAKE_FIND_LIBRARY_SUFFIXES})
-    if(WIN32)
+    endif ()
+else ()
+    set(_libevent_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES :${CMAKE_FIND_LIBRARY_SUFFIXES})
+    if (WIN32)
         list(INSERT CMAKE_FIND_LIBRARY_SUFFIXES 0 .dll .so)
-    else()
+    elseif (APPLE)
+        set(CMAKE_FIND_LIBRARY_SUFFIXES .dylib)
+    else ()
         set(CMAKE_FIND_LIBRARY_SUFFIXES .so)
-    endif()
-endif()
+    endif ()
+endif ()
+
+set(LIBEVENT_INCLUDE_SEARCH_PATH ${CMAKE_SOURCE_DIR}/bin/include /usr/local/include C:/libevent/include
+        ${CMAKE_SOURCE_DIR}/win32-deps/include)
+set(LIBEVENT_LIBRARIE_SEARCH_PATH ${CMAKE_SOURCE_DIR}/bin/lib /usr/local/lib C:/libevent-2.0.22-stable
+        C:/libevent-2.0.22-stable/lib C:/libevent/lib ${CMAKE_SOURCE_DIR}/win32-deps/lib)
+if (LIBEVENT_ROOT)
+    list(INSERT LIBEVENT_INCLUDE_SEARCH_PATH 0 ${JSONCPP_ROOT}/include)
+    list(INSERT LIBEVENT_LIBRARIE_SEARCH_PATH 0 ${JSONCPP_ROOT}/lib)
+endif ()
+
 # Look for the Libevent 2.0 or 1.4 headers
 find_path(LIBEVENT_INCLUDE_DIR
-  NAMES
-    WIN32-Code/event2/event-config.h
-    event2/event-config.h
-    event-config.h
-  PATHS ${CMAKE_SOURCE_DIR}/bin/include C:/libevent/include ${CMAKE_SOURCE_DIR}/win32-deps/include
-  HINTS
-    ${PC_LIBEVENT_INCLUDE_DIRS}
-)
+        NAMES WIN32-Code/event2/event-config.h event2/event-config.h event-config.h
+        PATHS ${LIBEVENT_INCLUDE_SEARCH_PATH}
+        HINTS ${PC_LIBEVENT_INCLUDE_DIRS})
 
 # ------------------------------------------------------------------------
 #  Prefix initialization 
 # ------------------------------------------------------------------------
 set(Libevent_LIB_PREFIX "")
 set(LIBEVENT_EVENT_CONFIG_DIR ${LIBEVENT_INCLUDE_DIR})
-if(WIN32)
-  set(Libevent_LIB_PREFIX "lib")
-  set(LIBEVENT_EVENT_CONFIG_DIR "${LIBEVENT_INCLUDE_DIR}/../WIN32-Code/")
-endif()
+if (WIN32)
+    set(Libevent_LIB_PREFIX "lib")
+    set(LIBEVENT_EVENT_CONFIG_DIR "${LIBEVENT_INCLUDE_DIR}/../WIN32-Code/")
+endif ()
 
-if(LIBEVENT_INCLUDE_DIR)
-  set(_version_regex "^#define[ \t]+_EVENT_VERSION[ \t]+\"([^\"]+)\".*")
-  if(EXISTS "${LIBEVENT_EVENT_CONFIG_DIR}/event2/event-config.h")
-    # Libevent 2.0
-    file(STRINGS "${LIBEVENT_EVENT_CONFIG_DIR}/event2/event-config.h"
-      LIBEVENT_VERSION REGEX "${_version_regex}")     
-  else()
-    # Libevent 1.4
-    if(EXISTS "${LIBEVENT_EVENT_CONFIG_DIR}/event-config.h")
-      file(STRINGS "${LIBEVENT_EVENT_CONFIG_DIR}/event-config.h"
-        LIBEVENT_VERSION REGEX "${_version_regex}")
-    endif()    
-  endif()
-  string(REGEX REPLACE "${_version_regex}" "\\1"
-    LIBEVENT_VERSION "${LIBEVENT_VERSION}")
-  unset(_version_regex)
-endif()
+if (LIBEVENT_INCLUDE_DIR)
+    set(_version_regex "^#define[ \t]+_EVENT_VERSION[ \t]+\"([^\"]+)\".*")
+    if (EXISTS "${LIBEVENT_EVENT_CONFIG_DIR}/event2/event-config.h")
+        # Libevent 2.0
+        file(STRINGS "${LIBEVENT_EVENT_CONFIG_DIR}/event2/event-config.h"
+                LIBEVENT_VERSION REGEX "${_version_regex}")
+        if (NOT LIBEVENT_VERSION)
+            # Libevent 2.1
+            set(_version_regex "^#define[ \t]+EVENT__VERSION[ \t]+\"([^\"]+)\".*")
+            file(STRINGS "${LIBEVENT_EVENT_CONFIG_DIR}/event2/event-config.h"
+                    LIBEVENT_VERSION REGEX "${_version_regex}")
+        endif ()
+    else ()
+        # Libevent 1.4
+        if (EXISTS "${LIBEVENT_EVENT_CONFIG_DIR}/event-config.h")
+            file(STRINGS "${LIBEVENT_EVENT_CONFIG_DIR}/event-config.h"
+                    LIBEVENT_VERSION REGEX "${_version_regex}")
+        endif ()
+    endif ()
+    string(REGEX REPLACE "${_version_regex}" "\\1"
+            LIBEVENT_VERSION "${LIBEVENT_VERSION}")
+    unset(_version_regex)
+endif ()
 
 set(_LIBEVENT_REQUIRED_VARS)
-if(WIN32)
-  set(Libevent_FIND_COMPONENTS ${Libevent_LIB_PREFIX}event core extras) 
-else()
-  set(Libevent_FIND_COMPONENTS ${Libevent_LIB_PREFIX}event core extra pthreads)
-endif()  
-message(status "** libevent components: ${Libevent_FIND_COMPONENTS}")
-foreach(COMPONENT ${Libevent_FIND_COMPONENTS})
-  set(_LIBEVENT_LIBNAME "${Libevent_LIB_PREFIX}event")
-  # Note: compare two variables to avoid a CMP0054 policy warning
-  if(COMPONENT STREQUAL _LIBEVENT_LIBNAME)
+if (WIN32)
+    set(Libevent_FIND_COMPONENTS ${Libevent_LIB_PREFIX}event core extras)
+else ()
+    set(Libevent_FIND_COMPONENTS ${Libevent_LIB_PREFIX}event core extra pthreads)
+endif ()
+message(STATUS "** libevent components: ${Libevent_FIND_COMPONENTS}")
+foreach (COMPONENT ${Libevent_FIND_COMPONENTS})
     set(_LIBEVENT_LIBNAME "${Libevent_LIB_PREFIX}event")
-  else()
-    set(_LIBEVENT_LIBNAME "${Libevent_LIB_PREFIX}event_${COMPONENT}")
-  endif()
-  string(TOUPPER "${COMPONENT}" COMPONENT_UPPER)
-  message(status "** ${_LIBEVENT_LIBNAME}")
-  find_library(LIBEVENT_${COMPONENT_UPPER}_LIBRARY
-    NAMES ${_LIBEVENT_LIBNAME}
-    PATHS ${CMAKE_SOURCE_DIR}/bin/lib C:/libevent-2.0.22-stable C:/libevent-2.0.22-stable/lib C:/libevent/lib ${CMAKE_SOURCE_DIR}/win32-deps/lib
-    HINTS ${PC_LIBEVENT_LIBRARY_DIRS}
-  )
-  if(LIBEVENT_${COMPONENT_UPPER}_LIBRARY)
-    set(Libevent_${COMPONENT}_FOUND 1)
-  endif()
-  list(APPEND _LIBEVENT_REQUIRED_VARS LIBEVENT_${COMPONENT_UPPER}_LIBRARY)
-endforeach()
+    # Note: compare two variables to avoid a CMP0054 policy warning
+    if (COMPONENT STREQUAL _LIBEVENT_LIBNAME)
+        set(_LIBEVENT_LIBNAME "${Libevent_LIB_PREFIX}event")
+    else ()
+        set(_LIBEVENT_LIBNAME "${Libevent_LIB_PREFIX}event_${COMPONENT}")
+    endif ()
+    string(TOUPPER "${COMPONENT}" COMPONENT_UPPER)
+    message(STATUS "** ${_LIBEVENT_LIBNAME}")
+    find_library(LIBEVENT_${COMPONENT_UPPER}_LIBRARY
+            NAMES ${_LIBEVENT_LIBNAME}
+            PATHS ${LIBEVENT_LIBRARIE_SEARCH_PATH}
+            HINTS ${PC_LIBEVENT_LIBRARY_DIRS}
+            )
+    if (LIBEVENT_${COMPONENT_UPPER}_LIBRARY)
+        set(Libevent_${COMPONENT}_FOUND 1)
+    endif ()
+    list(APPEND _LIBEVENT_REQUIRED_VARS LIBEVENT_${COMPONENT_UPPER}_LIBRARY)
+endforeach ()
 unset(_LIBEVENT_LIBNAME)
 
 include(FindPackageHandleStandardArgs)
 # handle the QUIETLY and REQUIRED arguments and set LIBEVENT_FOUND to TRUE
 # if all listed variables are TRUE and the requested version matches.
 find_package_handle_standard_args(Libevent REQUIRED_VARS
-                                  ${_LIBEVENT_REQUIRED_VARS}
-                                  LIBEVENT_INCLUDE_DIR
-                                  VERSION_VAR LIBEVENT_VERSION
-                                  HANDLE_COMPONENTS)
+        ${_LIBEVENT_REQUIRED_VARS}
+        LIBEVENT_INCLUDE_DIR
+        VERSION_VAR LIBEVENT_VERSION
+        HANDLE_COMPONENTS)
 
-if(LIBEVENT_FOUND)
-  set(LIBEVENT_INCLUDE_DIRS  ${LIBEVENT_INCLUDE_DIR})
-  set(LIBEVENT_LIBRARIES)
-  foreach(COMPONENT ${Libevent_FIND_COMPONENTS})
-    string(TOUPPER "${COMPONENT}" COMPONENT_UPPER)
-    list(APPEND LIBEVENT_LIBRARIES ${LIBEVENT_${COMPONENT_UPPER}_LIBRARY})
-    set(LIBEVENT_${COMPONENT_UPPER}_FOUND ${Libevent_${COMPONENT}_FOUND})
-  endforeach()
-endif()
+if (LIBEVENT_FOUND)
+    set(LIBEVENT_INCLUDE_DIRS ${LIBEVENT_INCLUDE_DIR})
+    set(LIBEVENT_LIBRARIES)
+    foreach (COMPONENT ${Libevent_FIND_COMPONENTS})
+        string(TOUPPER "${COMPONENT}" COMPONENT_UPPER)
+        list(APPEND LIBEVENT_LIBRARIES ${LIBEVENT_${COMPONENT_UPPER}_LIBRARY})
+        set(LIBEVENT_${COMPONENT_UPPER}_FOUND ${Libevent_${COMPONENT}_FOUND})
+    endforeach ()
+endif ()
 
 mark_as_advanced(LIBEVENT_INCLUDE_DIR ${_LIBEVENT_REQUIRED_VARS})
 
 # Restore the original find library ordering
-if( Libevent_USE_STATIC_LIBS )    
-  set(CMAKE_FIND_LIBRARY_SUFFIXES ${_libevent_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})                                                                        
-endif()
+if (Libevent_USE_STATIC_LIBS)
+    set(CMAKE_FIND_LIBRARY_SUFFIXES ${_libevent_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
+endif ()
 unset(_LIBEVENT_REQUIRED_VARS)
diff --git a/distribution/deploy.sh b/distribution/deploy.sh
index 726c182..7af6e30 100755
--- a/distribution/deploy.sh
+++ b/distribution/deploy.sh
@@ -16,7 +16,7 @@
 # limitations under the License.
 
 
-VERSION="1.2.4"
+VERSION="1.2.3"
 PKG_NAME="rocketmq-client-cpp"
 CWD_DIR=$(cd "$(dirname "$0")"; pwd)
 DEPLOY_BUILD_HOME=${CWD_DIR}/${PKG_NAME}
diff --git a/src/common/Arg_helper.cpp b/example/ArgHelper.cpp
similarity index 74%
rename from src/common/Arg_helper.cpp
rename to example/ArgHelper.cpp
index 61ac549..1506233 100644
--- a/src/common/Arg_helper.cpp
+++ b/example/ArgHelper.cpp
@@ -14,32 +14,32 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include "ArgHelper.h"
 
-#include "Arg_helper.h"
 #include "UtilAll.h"
 
 namespace rocketmq {
-//<!***************************************************************************
-Arg_helper::Arg_helper(int argc, char* argv[]) {
+
+ArgHelper::ArgHelper(int argc, char* argv[]) {
   for (int i = 0; i < argc; i++) {
     m_args.push_back(argv[i]);
   }
 }
 
-Arg_helper::Arg_helper(string arg_str_) {
-  vector<string> v;
+ArgHelper::ArgHelper(std::string arg_str_) {
+  std::vector<std::string> v;
   UtilAll::Split(v, arg_str_, " ");
   m_args.insert(m_args.end(), v.begin(), v.end());
 }
 
-string Arg_helper::get_option(int idx_) const {
+std::string ArgHelper::get_option(int idx_) const {
   if ((size_t)idx_ >= m_args.size()) {
     return "";
   }
   return m_args[idx_];
 }
 
-bool Arg_helper::is_enable_option(string opt_) const {
+bool ArgHelper::is_enable_option(std::string opt_) const {
   for (size_t i = 0; i < m_args.size(); ++i) {
     if (opt_ == m_args[i]) {
       return true;
@@ -48,8 +48,8 @@ bool Arg_helper::is_enable_option(string opt_) const {
   return false;
 }
 
-string Arg_helper::get_option_value(string opt_) const {
-  string ret = "";
+std::string ArgHelper::get_option_value(std::string opt_) const {
+  std::string ret = "";
   for (size_t i = 0; i < m_args.size(); ++i) {
     if (opt_ == m_args[i]) {
       size_t value_idx = ++i;
@@ -63,5 +63,4 @@ string Arg_helper::get_option_value(string opt_) const {
   return ret;
 }
 
-//<!***************************************************************************
-}  //<!end namespace;
+}  // namespace rocketmq
diff --git a/include/Arg_helper.h b/example/ArgHelper.h
similarity index 76%
rename from include/Arg_helper.h
rename to example/ArgHelper.h
index bda4fce..bd1e15d 100644
--- a/include/Arg_helper.h
+++ b/example/ArgHelper.h
@@ -14,20 +14,20 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-#ifndef _ARG_HELPER_H_
-#define _ARG_HELPER_H_
+#ifndef __ARG_HELPER_H__
+#define __ARG_HELPER_H__
 
 #include <string>
 #include <vector>
+
 #include "RocketMQClient.h"
 
 namespace rocketmq {
-//<!***************************************************************************
-class ROCKETMQCLIENT_API Arg_helper {
+
+class ROCKETMQCLIENT_API ArgHelper {
  public:
-  Arg_helper(int argc, char* argv[]);
-  Arg_helper(std::string arg_str_);
+  ArgHelper(int argc, char* argv[]);
+  ArgHelper(std::string arg_str_);
   std::string get_option(int idx_) const;
   bool is_enable_option(std::string opt_) const;
   std::string get_option_value(std::string opt_) const;
@@ -36,7 +36,6 @@ class ROCKETMQCLIENT_API Arg_helper {
   std::vector<std::string> m_args;
 };
 
-//<!***************************************************************************
 }  // namespace rocketmq
 
-#endif  //<!_ARG_HELPER_H_;
+#endif  // __ARG_HELPER_H__
diff --git a/example/AsyncProducer.cpp b/example/AsyncProducer.cpp
index 279cea3..a8acd5d 100644
--- a/example/AsyncProducer.cpp
+++ b/example/AsyncProducer.cpp
@@ -14,71 +14,51 @@
  * 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"
+#include "concurrent/latch.hpp"
 
 using namespace rocketmq;
 
-boost::atomic<bool> g_quit;
-std::mutex g_mtx;
-std::condition_variable g_finished;
-SendCallback* g_callback = NULL;
 TpsReportService g_tps;
+latch* g_finish = nullptr;
+
+std::atomic<int> g_success(0);
+std::atomic<int> g_failed(0);
+
+class MyAutoDeleteSendCallback : public AutoDeleteSendCallback {
+ public:
+  MyAutoDeleteSendCallback(MQMessage* msg) : m_msg(msg) {}
+  virtual ~MyAutoDeleteSendCallback() { delete m_msg; }
 
-class MySendCallback : public SendCallback {
-  virtual void onSuccess(SendResult& sendResult) {
-    g_msgCount--;
+  void onSuccess(SendResult& sendResult) override {
+    g_success++;
+    g_finish->count_down();
     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();
-    }
+  void onException(MQException& e) noexcept override {
+    g_failed++;
+    g_finish->count_down();
+    // std::cout << "send Exception: " << e << std::endl;
   }
-  virtual void onException(MQException& e) { std::cout << "send Exception" << e << "\n"; }
+
+ private:
+  MQMessage* m_msg;
 };
 
 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
+  while (g_msgCount.fetch_sub(1) > 0) {
+    auto* msg = new MQMessage(info->topic,  // topic
+                              "*",          // tag
+                              info->body);  // body
 
-    if (info->IsAutoDeleteSendCallback) {
-      g_callback = new MyAutoDeleteSendCallback();  // auto delete
-    }
+    SendCallback* callback = new MyAutoDeleteSendCallback(msg);
 
     try {
-      producer->send(msg, g_callback);
-    } catch (MQException& e) {
-      std::cout << e << endl;  // if catch excepiton , need re-send this msg by
-                               // service
+      producer->send(msg, callback);  // auto delete
+    } catch (std::exception& e) {
+      std::cout << "[BUG]:" << e.what() << std::endl;
+      throw e;
     }
   }
 }
@@ -88,48 +68,53 @@ int main(int argc, char* argv[]) {
   if (!ParseArgs(argc, argv, &info)) {
     exit(-1);
   }
-
-  DefaultMQProducer producer("please_rename_unique_group_name");
-  if (!info.IsAutoDeleteSendCallback) {
-    g_callback = new MySendCallback();
-  }
-
   PrintRocketmqSendAndConsumerArgs(info);
 
-  if (!info.namesrv.empty())
-    producer.setNamesrvAddr(info.namesrv);
+  auto* producer = new DefaultMQProducer(info.groupname);
+  producer->setNamesrvAddr(info.namesrv);
+  producer->setGroupName(info.groupname);
+  producer->setSendMsgTimeout(3000);
+  producer->setRetryTimes(info.retrytimes);
+  producer->setRetryTimes4Async(info.retrytimes);
+  producer->setSendLatencyFaultEnable(!info.selectUnactiveBroker);
+  producer->setTcpTransportTryLockTimeout(1000);
+  producer->setTcpTransportConnectTimeout(400);
+  producer->start();
 
-  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);
+  g_finish = new latch(msgcount);
+  g_tps.start();
+
+  auto start = std::chrono::system_clock::now();
+
+  int threadCount = info.thread_count;
+  for (int j = 0; j < threadCount; 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);
+  for (size_t th = 0; th != work_pool.size(); ++th) {
+    work_pool[th]->join();
   }
 
+  g_finish->wait();
+
   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";
+  std::cout << "per msg time: " << duration.count() / (double)msgcount << "ms" << std::endl
+            << "========================finished=============================" << std::endl
+            << "success: " << g_success << ", failed: " << g_failed << std::endl;
 
-  producer.shutdown();
-  for (size_t th = 0; th != work_pool.size(); ++th) {
-    work_pool[th]->join();
-  }
-  if (!info.IsAutoDeleteSendCallback) {
-    delete g_callback;
+  try {
+    producer->shutdown();
+  } catch (std::exception& e) {
+    std::cout << "encounter exception: " << e.what() << std::endl;
   }
+
+  delete producer;
+  delete g_finish;
+
   return 0;
 }
diff --git a/example/AsyncPushConsumer.cpp b/example/AsyncPushConsumer.cpp
deleted file mode 100644
index 414f967..0000000
--- a/example/AsyncPushConsumer.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
-* 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 <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();
-    }
-
-    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 (!ParseArgs(argc, argv, &info)) {
-    exit(-1);
-  }
-  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;
-}
\ No newline at end of file
diff --git a/example/BatchProducer.cpp b/example/BatchProducer.cpp
index d889ea9..12e95f7 100644
--- a/example/BatchProducer.cpp
+++ b/example/BatchProducer.cpp
@@ -1,75 +1,55 @@
 /*
-* 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 <iomanip>
-#include <iostream>
-#include <iostream>
-#include <mutex>
-#include <thread>
-#include <vector>
+ * 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 "common.h"
 
 using namespace rocketmq;
-using namespace std;
-boost::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;
+  while (g_msgCount.fetch_sub(1) > 0) {
+    std::vector<MQMessage*> msgs;
     MQMessage msg1(info->topic, "*", info->body);
-    msg1.setProperty("property1", "value1");
+    msg1.putProperty("property1", "value1");
     MQMessage msg2(info->topic, "*", info->body);
-    msg2.setProperty("property1", "value1");
-    msg2.setProperty("property2", "value2");
+    msg2.putProperty("property1", "value1");
+    msg2.putProperty("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);
+    msg3.putProperty("property1", "value1");
+    msg3.putProperty("property2", "value2");
+    msg3.putProperty("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();
+
+      g_tps.Increment();
+
       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;
+        std::cout << "send RT more than: " << duration.count() << "ms with msgid: " << sendResult.getMsgId()
+                  << std::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;
     }
   }
 }
@@ -80,45 +60,43 @@ int main(int argc, char* argv[]) {
     exit(-1);
   }
   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();
+
+  auto* producer = new DefaultMQProducer(info.groupname);
+  producer->setNamesrvAddr(info.namesrv);
+  producer->setGroupName(info.groupname);
+  producer->setSendMsgTimeout(3000);
+  producer->setRetryTimes(info.retrytimes);
+  producer->setRetryTimes4Async(info.retrytimes);
+  producer->setSendLatencyFaultEnable(!info.selectUnactiveBroker);
+  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();
 
+  auto start = std::chrono::system_clock::now();
+
   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);
+    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);
+  for (size_t th = 0; th != work_pool.size(); ++th) {
+    work_pool[th]->join();
   }
 
   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";
+  std::cout << "per msg time: " << duration.count() / (double)msgcount << "ms" << std::endl
+            << "========================finished=============================" << std::endl;
 
-  for (size_t th = 0; th != work_pool.size(); ++th) {
-    work_pool[th]->join();
-  }
+  producer->shutdown();
 
-  producer.shutdown();
+  delete producer;
 
   return 0;
 }
diff --git a/example/CAsyncProducer.c b/example/CAsyncProducer.c
index 2d2af61..7f58c29 100644
--- a/example/CAsyncProducer.c
+++ b/example/CAsyncProducer.c
@@ -14,12 +14,8 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-
 #include <stdio.h>
-#include "CProducer.h"
-#include "CCommon.h"
-#include "CMessage.h"
-#include "CSendResult.h"
+
 #ifdef _WIN32
 #include <windows.h>
 #else
@@ -27,6 +23,8 @@
 #include <memory.h>
 #endif
 
+#include "c/CProducer.h"
+
 void thread_sleep(unsigned milliseconds) {
 #ifdef _WIN32
   Sleep(milliseconds);
diff --git a/example/CBatchProducer.c b/example/CBatchProducer.c
index 148d9f0..de40e04 100644
--- a/example/CBatchProducer.c
+++ b/example/CBatchProducer.c
@@ -14,14 +14,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 #include <stdio.h>
 #include <string.h>
-#include "CBatchMessage.h"
-#include "CCommon.h"
-#include "CMessage.h"
-#include "CProducer.h"
-#include "CSendResult.h"
+
+#include "c/CProducer.h"
 
 void StartSendMessage(CProducer* producer) {
   int i = 0;
diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt
index aecec5c..6ef72a8 100755
--- a/example/CMakeLists.txt
+++ b/example/CMakeLists.txt
@@ -18,17 +18,13 @@ project(example)
 set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin)
 
 include_directories(${CMAKE_SOURCE_DIR}/include)
-include_directories(${Boost_INCLUDE_DIRS})
+include_directories(${CMAKE_SOURCE_DIR}/src)
 
-link_directories(${Boost_LIBRARY_DIRS})
 link_directories(${LIBEVENT_LIBRARY})
 link_directories(${JSONCPP_LIBRARY})
 
-#if (BUILD_ROCKETMQ_SHARED)
-#    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBOOST_ALL_DYN_LINK -shared ")
-#endif()
-
-file(GLOB files "*.c*")
+file(GLOB files RELATIVE "${PROJECT_SOURCE_DIR}" "*.c*")
+list(REMOVE_ITEM files "ArgHelper.cpp")
 foreach(file ${files})
     get_filename_component(basename ${file} NAME_WE)
     add_executable(${basename} ${file})
@@ -42,11 +38,9 @@ foreach(file ${files})
 
     if (MSVC)
         if (BUILD_ROCKETMQ_SHARED)
-            target_link_libraries (${basename}  rocketmq_shared ${deplibs}
-            ${Boost_LIBRARIES} ${LIBEVENT_LIBRARIES} ${JSONCPP_LIBRARIES})
+            target_link_libraries (${basename}  rocketmq_shared ${deplibs} ${LIBEVENT_LIBRARIES} ${JSONCPP_LIBRARIES})
         else()
-            target_link_libraries (${basename}  rocketmq_static ${deplibs}
-            ${Boost_LIBRARIES} ${LIBEVENT_LIBRARIES} ${JSONCPP_LIBRARIES})
+            target_link_libraries (${basename}  rocketmq_static ${deplibs} ${LIBEVENT_LIBRARIES} ${JSONCPP_LIBRARIES})
         endif()
     else()
         if (BUILD_ROCKETMQ_SHARED)
diff --git a/example/COrderlyAsyncProducer.c b/example/COrderlyAsyncProducer.c
index 48a822c..9cf04f0 100644
--- a/example/COrderlyAsyncProducer.c
+++ b/example/COrderlyAsyncProducer.c
@@ -14,12 +14,8 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-
 #include <stdio.h>
-#include "CProducer.h"
-#include "CCommon.h"
-#include "CMessage.h"
-#include "CSendResult.h"
+
 #ifdef _WIN32
 #include <windows.h>
 #else
@@ -27,6 +23,8 @@
 #include <memory.h>
 #endif
 
+#include "c/CProducer.h"
+
 void thread_sleep(unsigned milliseconds) {
 #ifdef _WIN32
   Sleep(milliseconds);
diff --git a/example/OrderProducer.cpp b/example/OrderProducer.cpp
deleted file mode 100644
index 613add4..0000000
--- a/example/OrderProducer.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
-* 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::condition_variable g_finished;
-std::mutex g_mtx;
-boost::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 (!ParseArgs(argc, argv, &info)) {
-    exit(-1);
-  }
-
-  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;
-}
diff --git a/example/OrderlyProducer.cpp b/example/OrderlyProducer.cpp
new file mode 100644
index 0000000..237532b
--- /dev/null
+++ b/example/OrderlyProducer.cpp
@@ -0,0 +1,103 @@
+/*
+ * 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 "common.h"
+
+using namespace rocketmq;
+
+TpsReportService g_tps;
+
+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_msgCount.fetch_sub(1) > 0) {
+    MQMessage msg(info->topic,  // topic
+                  "*",          // tag
+                  info->body);  // body
+    try {
+      auto start = std::chrono::system_clock::now();
+      int orderId = 1;
+      SendResult sendResult = producer->send(&msg, &g_mySelector, static_cast<void*>(&orderId), info->retrytimes);
+      auto end = std::chrono::system_clock::now();
+
+      g_tps.Increment();
+
+      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()
+                  << std::endl;
+      }
+    } catch (const MQException& e) {
+      std::cout << "send failed: " << e.what() << std::endl;
+    }
+  }
+}
+
+int main(int argc, char* argv[]) {
+  RocketmqSendAndConsumerArgs info;
+  if (!ParseArgs(argc, argv, &info)) {
+    exit(-1);
+  }
+  PrintRocketmqSendAndConsumerArgs(info);
+
+  auto* producer = new DefaultMQProducer(info.groupname);
+  producer->setNamesrvAddr(info.namesrv);
+  producer->setGroupName(info.groupname);
+  producer->setSendMsgTimeout(3000);
+  producer->setRetryTimes(info.retrytimes);
+  producer->setRetryTimes4Async(info.retrytimes);
+  producer->setSendLatencyFaultEnable(!info.selectUnactiveBroker);
+  producer->setTcpTransportTryLockTimeout(1000);
+  producer->setTcpTransportConnectTimeout(400);
+  producer->start();
+
+  std::vector<std::shared_ptr<std::thread>> work_pool;
+  int msgcount = g_msgCount.load();
+  g_tps.start();
+
+  auto start = std::chrono::system_clock::now();
+
+  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);
+  }
+
+  for (size_t th = 0; th != work_pool.size(); ++th) {
+    work_pool[th]->join();
+  }
+
+  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" << std::endl
+            << "========================finished=============================" << std::endl;
+
+  producer->shutdown();
+
+  delete producer;
+
+  return 0;
+}
diff --git a/example/OrderlyPushConsumer.cpp b/example/OrderlyPushConsumer.cpp
index c8a9eaa..2d8a541 100644
--- a/example/OrderlyPushConsumer.cpp
+++ b/example/OrderlyPushConsumer.cpp
@@ -1,56 +1,47 @@
 /*
-* 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>
-
+ * 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 "common.h"
+#include "concurrent/latch.hpp"
 
 using namespace rocketmq;
 
-std::condition_variable g_finished;
-std::mutex g_mtx;
-boost::atomic<int> g_consumedCount(0);
-boost::atomic<bool> g_quit(false);
 TpsReportService g_tps;
+latch g_finished(1);
 
 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();
+  virtual ConsumeStatus consumeMessage(const std::vector<MQMessageExt*>& msgs) {
+    auto old = g_msgCount.fetch_sub(msgs.size());
+    if (old > 0) {
+      for (size_t i = 0; i < msgs.size(); ++i) {
+        g_tps.Increment();
+        // std::cout << msgs[i]->getMsgId() << std::endl;
+        // std::cout << "msg body: " << msgs[i].getBody() << std::endl;
+      }
+      if (old <= msgs.size()) {
+        g_finished.count_down();
+      }
+      return CONSUME_SUCCESS;
+    } else {
+      return RECONSUME_LATER;
     }
-    for (size_t i = 0; i < msgs.size(); i++) {
-      ++g_consumedCount;
-      g_tps.Increment();
-    }
-    return CONSUME_SUCCESS;
   }
 };
 
@@ -60,53 +51,33 @@ int main(int argc, char* argv[]) {
     exit(-1);
   }
   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);
+  auto* consumer = new DefaultMQPushConsumer(info.groupname);
+  consumer->setNamesrvAddr(info.namesrv);
+  consumer->setGroupName(info.groupname);
+  consumer->setTcpTransportTryLockTimeout(1000);
+  consumer->setTcpTransportConnectTimeout(400);
+  consumer->setConsumeThreadNum(info.thread_count);
+  consumer->setConsumeMessageBatchMaxSize(31);
+  consumer->setConsumeFromWhere(CONSUME_FROM_LAST_OFFSET);
+  consumer->subscribe(info.topic, "*");
 
   MyMsgListener msglistener;
-  consumer.registerMessageListener(&msglistener);
+  consumer->registerMessageListener(&msglistener);
+
   g_tps.start();
 
   try {
-    consumer.start();
+    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
+  g_finished.wait();
 
-    try {
-      producer.send(msg);
-    } catch (MQException& e) {
-      std::cout << e << endl;  // if catch excepiton , need re-send this msg by
-                               // service
-    }
-  }
+  consumer->shutdown();
 
-  while (!g_quit.load()) {
-    std::unique_lock<std::mutex> lk(g_mtx);
-    g_finished.wait(lk);
-  }
+  delete consumer;
 
-  producer.shutdown();
-  consumer.shutdown();
   return 0;
 }
diff --git a/example/Producer.c b/example/Producer.c
index 9ae23a9..8693992 100644
--- a/example/Producer.c
+++ b/example/Producer.c
@@ -1,37 +1,35 @@
 /*
- * 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.
- */
-
+* 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 "CCommon.h"
-#include "CMessage.h"
-#include "CProducer.h"
-#include "CSendResult.h"
+
 #ifdef _WIN32
 #include <windows.h>
 #else
-#include <memory.h>
 #include <unistd.h>
+#include <memory.h>
 #endif
 
-void thread_sleep(unsigned int milliseconds) {
+#include "c/CProducer.h"
+
+void thread_sleep(unsigned milliseconds) {
 #ifdef _WIN32
   Sleep(milliseconds);
 #else
-  usleep(milliseconds * 1000);  // suspend execution for microsecond intervals
+  usleep(milliseconds * 1000);  // takes microseconds
 #endif
 }
 
@@ -42,32 +40,26 @@ void StartSendMessage(CProducer* producer) {
   SetMessageTags(msg, "Test_Tag");
   SetMessageKeys(msg, "Test_Keys");
   CSendResult result;
-  for (i = 0; i < 3; i++) {
+  for (i = 0; i < 10; i++) {
     memset(body, 0, sizeof(body));
     snprintf(body, sizeof(body), "new message body, index %d", i);
     SetMessageBody(msg, body);
-    int status = SendMessageSync(producer, msg, &result);
-    if (status == OK) {
-      printf("send message[%d] result status:%d, msgId:%s\n", i, (int)result.sendStatus, result.msgId);
-    } else {
-      printf("send message[%d] failed !\n", i);
-    }
+    SendMessageSync(producer, msg, &result);
+    printf("send message[%d] result status:%d, msgId:%s\n", i, (int)result.sendStatus, result.msgId);
     thread_sleep(1000);
   }
   DestroyMessage(msg);
 }
 
 int main(int argc, char* argv[]) {
+  printf("Producer Initializing.....\n");
   CProducer* producer = CreateProducer("Group_producer");
   SetProducerNameServerAddress(producer, "127.0.0.1:9876");
   StartProducer(producer);
-  printf("Producer initialized. \n");
-
+  printf("Producer start.....\n");
   StartSendMessage(producer);
-
   ShutdownProducer(producer);
   DestroyProducer(producer);
-  printf("Producer stopped !\n");
-
+  printf("Producer Shutdown!\n");
   return 0;
 }
diff --git a/example/PullConsumeMessage.c b/example/PullConsumeMessage.c
index 0868d08..2977543 100644
--- a/example/PullConsumeMessage.c
+++ b/example/PullConsumeMessage.c
@@ -14,13 +14,8 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-
 #include <stdio.h>
-#include "CPullConsumer.h"
-#include "CCommon.h"
-#include "CMessageExt.h"
-#include "CPullResult.h"
-#include "CMessageQueue.h"
+
 #ifdef _WIN32
 #include <windows.h>
 #else
@@ -28,6 +23,8 @@
 #include <memory.h>
 #endif
 
+#include "c/CPullConsumer.h"
+
 void thread_sleep(unsigned milliseconds) {
 #ifdef _WIN32
   Sleep(milliseconds);
diff --git a/example/PullConsumer.cpp b/example/PullConsumer.cpp
index 52e9094..6046d6c 100644
--- a/example/PullConsumer.cpp
+++ b/example/PullConsumer.cpp
@@ -1,20 +1,19 @@
 /*
-* 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.
-*/
-
+ * 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>
 
@@ -35,7 +34,7 @@ void putMessageQueueOffset(MQMessageQueue mq, uint64_t offset) {
 }
 
 uint64_t getMessageQueueOffset(MQMessageQueue mq) {
-  map<MQMessageQueue, uint64_t>::iterator it = g_offseTable.find(mq);
+  auto it = g_offseTable.find(mq);
   if (it != g_offseTable.end()) {
     return it->second;
   }
@@ -50,9 +49,7 @@ int main(int argc, char* argv[]) {
   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;
@@ -61,10 +58,10 @@ int main(int argc, char* argv[]) {
     consumer.fetchSubscribeMessageQueues(info.topic, mqs);
     auto iter = mqs.begin();
     for (; iter != mqs.end(); ++iter) {
-      std::cout << "mq:" << (*iter).toString() << endl;
+      std::cout << "mq:" << iter->toString() << std::endl;
     }
   } catch (MQException& e) {
-    std::cout << e << endl;
+    std::cout << e << std::endl;
   }
 
   auto start = std::chrono::system_clock::now();
@@ -89,7 +86,7 @@ int main(int argc, char* argv[]) {
           putMessageQueueOffset(mq, result.nextBeginOffset);
           PrintPullResult(&result);
         } else {
-          cout << "broker timeout occur" << endl;
+          std::cout << "broker timeout occur" << std::endl;
         }
         switch (result.pullStatus) {
           case FOUND:
@@ -117,5 +114,6 @@ int main(int argc, char* argv[]) {
             << "========================finished==============================\n";
 
   consumer.shutdown();
+
   return 0;
 }
diff --git a/example/PushConsumeMessage.c b/example/PushConsumeMessage.c
index 2cb9c3f..de8b647 100644
--- a/example/PushConsumeMessage.c
+++ b/example/PushConsumeMessage.c
@@ -14,11 +14,8 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-
 #include <stdio.h>
-#include "CPushConsumer.h"
-#include "CCommon.h"
-#include "CMessageExt.h"
+
 #ifdef _WIN32
 #include <windows.h>
 #else
@@ -26,6 +23,8 @@
 #include <memory.h>
 #endif
 
+#include "c/CPushConsumer.h"
+
 void thread_sleep(unsigned milliseconds) {
 #ifdef _WIN32
   Sleep(milliseconds);
diff --git a/example/PushConsumer.cpp b/example/PushConsumer.cpp
index f0d4926..9aba07c 100644
--- a/example/PushConsumer.cpp
+++ b/example/PushConsumer.cpp
@@ -1,56 +1,47 @@
 /*
-* 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>
-
+ * 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 "common.h"
-
-std::mutex g_mtx;
-std::condition_variable g_finished;
-TpsReportService g_tps;
+#include "concurrent/latch.hpp"
 
 using namespace rocketmq;
 
+TpsReportService g_tps;
+latch g_finished(1);
+
 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();
+  virtual ConsumeStatus consumeMessage(const std::vector<MQMessageExt*>& msgs) {
+    auto old = g_msgCount.fetch_sub(msgs.size());
+    if (old > 0) {
+      for (size_t i = 0; i < msgs.size(); ++i) {
+        g_tps.Increment();
+        // std::cout << msgs[i]->getMsgId() << std::endl;
+        // std::cout << "msg body: " << msgs[i].getBody() << std::endl;
+      }
+      if (old <= msgs.size()) {
+        g_finished.count_down();
+      }
+      return CONSUME_SUCCESS;
+    } else {
+      return RECONSUME_LATER;
     }
-    return CONSUME_SUCCESS;
   }
 };
 
@@ -60,66 +51,37 @@ int main(int argc, char* argv[]) {
     exit(-1);
   }
   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);
+  auto* consumer = new DefaultMQPushConsumer(info.groupname);
+  consumer->setNamesrvAddr(info.namesrv);
+  consumer->setGroupName(info.groupname);
+  consumer->setTcpTransportTryLockTimeout(1000);
+  consumer->setTcpTransportConnectTimeout(400);
+  consumer->setConsumeThreadNum(info.thread_count);
+  consumer->setConsumeFromWhere(CONSUME_FROM_LAST_OFFSET);
 
-  if (info.syncpush)
-    consumer.setAsyncPull(false);  // set sync pull
   if (info.broadcasting) {
-    consumer.setMessageModel(rocketmq::BROADCASTING);
+    consumer->setMessageModel(rocketmq::BROADCASTING);
   }
 
-  consumer.setInstanceName(info.groupname);
-
-  consumer.subscribe(info.topic, "*");
-  consumer.setConsumeThreadCount(15);
-  consumer.setTcpTransportTryLockTimeout(1000);
-  consumer.setTcpTransportConnectTimeout(400);
+  consumer->subscribe(info.topic, "*");
 
   MyMsgListener msglistener;
-  consumer.registerMessageListener(&msglistener);
+  consumer->registerMessageListener(&msglistener);
+
+  g_tps.start();
 
   try {
-    consumer.start();
+    consumer->start();
   } catch (MQClientException& e) {
-    cout << e << endl;
+    std::cout << e << std::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
+  g_finished.wait();
 
-    //    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
-    }
-  }
+  consumer->shutdown();
+
+  delete consumer;
 
-  {
-    std::unique_lock<std::mutex> lck(g_mtx);
-    g_finished.wait(lck);
-  }
-  producer.shutdown();
-  consumer.shutdown();
   return 0;
 }
diff --git a/example/PushConsumerOrderly.c b/example/PushConsumerOrderly.c
index 4b2c2bb..2fd9c6f 100644
--- a/example/PushConsumerOrderly.c
+++ b/example/PushConsumerOrderly.c
@@ -14,13 +14,13 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
+#include <stdio.h>
+
 #ifndef WIN32
 #include <unistd.h>
 #endif
-#include <stdio.h>
-#include "CPushConsumer.h"
-#include "CCommon.h"
-#include "CMessageExt.h"
+
+#include "c/CPushConsumer.h"
 
 int doConsumeMessage(struct CPushConsumer* consumer, CMessageExt* msgExt) {
   printf("Hello,doConsumeMessage by Application!\n");
diff --git a/example/SendDelayMsg.cpp b/example/SendDelayMsg.cpp
index 2486427..3a5b6ce 100644
--- a/example/SendDelayMsg.cpp
+++ b/example/SendDelayMsg.cpp
@@ -1,31 +1,19 @@
 /*
-* 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 <iomanip>
-#include <iostream>
-#include <iostream>
-#include <mutex>
-#include <thread>
-
+ * 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 "common.h"
 
 using namespace rocketmq;
@@ -36,31 +24,30 @@ int main(int argc, char* argv[]) {
     exit(-1);
   }
   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();
+  auto* producer = new DefaultMQProducer(info.groupname);
+  producer->setNamesrvAddr(info.namesrv);
+  producer->setGroupName(info.groupname);
+  producer->setSendMsgTimeout(3000);
+  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
+  // 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);
+    SendResult sendResult = producer->send(&msg);
   } catch (const MQException& e) {
     std::cout << "send failed: " << std::endl;
   }
 
-  producer.shutdown();
+  producer->shutdown();
+
+  delete producer;
+
   return 0;
 }
diff --git a/example/SyncProducer.cpp b/example/SyncProducer.cpp
index 0edb6dc..d840fdd 100644
--- a/example/SyncProducer.cpp
+++ b/example/SyncProducer.cpp
@@ -1,61 +1,44 @@
 /*
-* 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 <iomanip>
-#include <iostream>
-#include <iostream>
-#include <mutex>
-#include <thread>
-
+ * 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 "common.h"
 
 using namespace rocketmq;
 
-boost::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();
-    }
+  while (g_msgCount.fetch_sub(1) > 0) {
     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;
+      SendResult sendResult = producer->send(&msg);
       auto end = std::chrono::system_clock::now();
+
+      g_tps.Increment();
+
       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;
+        std::cout << "send RT more than: " << duration.count() << "ms with msgid: " << sendResult.getMsgId()
+                  << std::endl;
       }
     } catch (const MQException& e) {
-      std::cout << "send failed: " << std::endl;
+      std::cout << "send failed: " << e.what() << std::endl;
     }
   }
 }
@@ -66,45 +49,43 @@ int main(int argc, char* argv[]) {
     exit(-1);
   }
   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();
+
+  auto* producer = new DefaultMQProducer(info.groupname);
+  producer->setNamesrvAddr(info.namesrv);
+  producer->setGroupName(info.groupname);
+  producer->setSendMsgTimeout(3000);
+  producer->setRetryTimes(info.retrytimes);
+  producer->setRetryTimes4Async(info.retrytimes);
+  producer->setSendLatencyFaultEnable(!info.selectUnactiveBroker);
+  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();
 
+  auto start = std::chrono::system_clock::now();
+
   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);
+    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);
+  for (size_t th = 0; th != work_pool.size(); ++th) {
+    work_pool[th]->join();
   }
 
   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";
+  std::cout << "per msg time: " << duration.count() / (double)msgcount << "ms" << std::endl
+            << "========================finished=============================" << std::endl;
 
-  for (size_t th = 0; th != work_pool.size(); ++th) {
-    work_pool[th]->join();
-  }
+  producer->shutdown();
 
-  producer.shutdown();
+  delete producer;
 
   return 0;
 }
diff --git a/example/TransactionProducer.cpp b/example/TransactionProducer.cpp
index 1aabb08..f6985f9 100644
--- a/example/TransactionProducer.cpp
+++ b/example/TransactionProducer.cpp
@@ -14,73 +14,49 @@
  * 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);
+    LocalTransactionState state = (LocalTransactionState)(((intptr_t)arg) % 3);
     std::cout << "executeLocalTransaction transactionId:" << msg.getTransactionId() << ", return state: " << state
-              << endl;
+              << std::endl;
     return state;
   }
 
   virtual LocalTransactionState checkLocalTransaction(const MQMessageExt& msg) {
-    std::cout << "checkLocalTransaction enter msg:" << msg.toString() << endl;
+    std::cout << "checkLocalTransaction enter msg:" << msg.toString() << std::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;
-    }
-
+  int old = g_msgCount.fetch_sub(1);
+  while (old > 0) {
     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;
+      intptr_t arg = old - 1;
+      TransactionSendResult sendResult = producer->sendMessageInTransaction(&msg, (void*)arg);
       auto end = std::chrono::system_clock::now();
+
+      g_tps.Increment();
+
       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;
+        std::cout << "send RT more than: " << duration.count() << "ms with msgid: " << sendResult.getMsgId()
+                  << std::endl;
       }
     } catch (const MQException& e) {
       std::cout << "send failed: " << e.what() << std::endl;
     }
+    old = g_msgCount.fetch_sub(1);
   }
 }
 
@@ -90,46 +66,48 @@ int main(int argc, char* argv[]) {
     exit(-1);
   }
   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();
+
+  auto* producer = new TransactionMQProducer(info.groupname);
+  producer->setNamesrvAddr(info.namesrv);
+  producer->setGroupName(info.groupname);
+  producer->setSendMsgTimeout(3000);
+  producer->setRetryTimes(info.retrytimes);
+  producer->setRetryTimes4Async(info.retrytimes);
+  producer->setSendLatencyFaultEnable(!info.selectUnactiveBroker);
+  producer->setTcpTransportTryLockTimeout(1000);
+  producer->setTcpTransportConnectTimeout(400);
+
+  MyTransactionListener myListener;
+  producer->setTransactionListener(&myListener);
+
+  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();
 
+  auto start = std::chrono::system_clock::now();
+
   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);
+    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);
+  for (size_t th = 0; th != work_pool.size(); ++th) {
+    work_pool[th]->join();
   }
 
   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";
+  std::cout << "per msg time: " << duration.count() / (double)msgcount << "ms" << std::endl
+            << "========================finished=============================" << std::endl;
 
-  for (size_t th = 0; th != work_pool.size(); ++th) {
-    work_pool[th]->join();
-  }
+  std::this_thread::sleep_for(std::chrono::seconds(30));
+  producer->shutdown();
 
-  producer.shutdown();
+  delete producer;
 
   return 0;
 }
diff --git a/example/common.h b/example/common.h
index 5b674c3..db242f7 100644
--- a/example/common.h
+++ b/example/common.h
@@ -1,102 +1,106 @@
 /*
-* 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.
-*/
+ * 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 <boost/atomic.hpp>
-#include <boost/chrono.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/thread.hpp>
+#include <atomic>
+#include <chrono>
 #include <iostream>
+#include <memory>
 #include <string>
 #include <thread>
-#include <vector>
 
-#include "Arg_helper.h"
+#ifndef WIN32
+#include <unistd.h>
+#else
+#include "ArgHelper.h"
+#endif
+
 #include "DefaultMQProducer.h"
+#include "TransactionMQProducer.h"
 #include "DefaultMQPullConsumer.h"
 #include "DefaultMQPushConsumer.h"
-using namespace std;
 
-boost::atomic<int> g_msgCount(1);
+std::atomic<int> g_msgCount(1);
 
 class RocketmqSendAndConsumerArgs {
  public:
   RocketmqSendAndConsumerArgs()
       : body("msgbody for test"),
-        thread_count(boost::thread::hardware_concurrency()),
+        thread_count(1),
         broadcasting(false),
-        syncpush(false),
-        SelectUnactiveBroker(false),
-        IsAutoDeleteSendCallback(false),
-        retrytimes(5),
-        PrintMoreInfo(false) {}
+        selectUnactiveBroker(false),
+        isAutoDeleteSendCallback(true),
+        retrytimes(1),
+        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;
+  bool selectUnactiveBroker;  // default select active broker
+  bool isAutoDeleteSendCallback;
+  int retrytimes;  // default retry 1 times;
+  bool printMoreInfo;
 };
 
 class TpsReportService {
  public:
-  TpsReportService() : tps_interval_(1), quit_flag_(false), tps_count_(0) {}
+  TpsReportService() : tps_interval_(1), quit_flag_(false), tps_count_(0), all_count_(0) {}
+
   void start() {
-    if (tps_thread_ == NULL) {
-      std::cout << "tps_thread_ is null" << std::endl;
-      return;
+    if (tps_thread_ == nullptr) {
+      tps_thread_.reset(new std::thread(std::bind(&TpsReportService::TpsReport, this)));
     }
-    tps_thread_.reset(new boost::thread(boost::bind(&TpsReportService::TpsReport, this)));
   }
 
   ~TpsReportService() {
     quit_flag_.store(true);
-    if (tps_thread_ == NULL) {
+
+    if (tps_thread_ == nullptr) {
       std::cout << "tps_thread_ is null" << std::endl;
       return;
     }
-    if (tps_thread_->joinable())
+
+    if (tps_thread_->joinable()) {
       tps_thread_->join();
+    }
   }
 
   void Increment() { ++tps_count_; }
 
   void TpsReport() {
     while (!quit_flag_.load()) {
-      boost::this_thread::sleep_for(tps_interval_);
-      std::cout << "tps: " << tps_count_.load() << std::endl;
-      tps_count_.store(0);
+      std::this_thread::sleep_for(tps_interval_);
+      auto tps = tps_count_.exchange(0);
+      all_count_ += tps;
+      std::cout << "all: " << all_count_ << ", tps: " << tps << std::endl;
     }
   }
 
  private:
-  boost::chrono::seconds tps_interval_;
-  boost::shared_ptr<boost::thread> tps_thread_;
-  boost::atomic<bool> quit_flag_;
-  boost::atomic<long> tps_count_;
+  std::chrono::seconds tps_interval_;
+  std::shared_ptr<std::thread> tps_thread_;
+  std::atomic<bool> quit_flag_;
+  std::atomic<long> tps_count_;
+  uint64_t all_count_;
 };
 
 /*
@@ -111,53 +115,46 @@ static void PrintResult(rocketmq::SendResult* result) {
 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;
+    std::cout << result->toString() << std::endl;
+    for (auto& msg : result->msgFoundList) {
+      std::cout << "=======================================================" << std::endl
+                << msg->toString() << std::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;
+  std::cout << "nameserver: " << info.namesrv << std::endl
+            << "topic: " << info.topic << std::endl
+            << "groupname: " << info.groupname << std::endl
+            << "produce content: " << info.body << std::endl
+            << "msg count: " << g_msgCount.load() << std::endl
+            << "thread count: " << info.thread_count << std::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"
+  std::cout << "need option, like follow:\n"
+               "-n nameserver addr, 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: \"msgbody for test\")\n"
+               "-b (BROADCASTING model, default value: CLUSTER)\n"
+               "-r setup retry times(default value: 1)\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";
+               "-d use AutoDeleteSendcallback by cpp client(defalut value: false)\n"
+               "-T thread count of send msg or consume msg(defalut value: 1)\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) {
+  while ((ch = getopt(argc, argv, "n:g:t:m:c:b: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;
@@ -173,20 +170,17 @@ static bool ParseArgs(int argc, char* argv[], RocketmqSendAndConsumerArgs* info)
       case 'b':
         info->broadcasting = true;
         break;
-      case 's':
-        info->syncpush = true;
-        break;
       case 'r':
         info->retrytimes = atoi(optarg);
         break;
       case 'u':
-        info->SelectUnactiveBroker = true;
+        info->selectUnactiveBroker = true;
         break;
       case 'T':
         info->thread_count = atoi(optarg);
         break;
       case 'v':
-        info->PrintMoreInfo = true;
+        info->printMoreInfo = true;
         break;
       case 'h':
         help();
@@ -199,29 +193,31 @@ static bool ParseArgs(int argc, char* argv[], RocketmqSendAndConsumerArgs* info)
 #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())
+  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)
+  if (retrytimes > 0) {
     info->retrytimes = retrytimes;
-  info->SelectUnactiveBroker = atoi(arg_help.get_option_value("-u").c_str());
+  }
+  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)
+  if (thread_count > 0) {
     info->thread_count = thread_count;
-  info->PrintMoreInfo = atoi(arg_help.get_option_value("-v").c_str());
+  }
+  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())) {
+  if (info->groupname.empty() || info->topic.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_
diff --git a/src/common/MQClientErrorContainer.h b/include/AllocateMQStrategy.h
similarity index 64%
copy from src/common/MQClientErrorContainer.h
copy to include/AllocateMQStrategy.h
index 3e09f0a..0343654 100644
--- a/src/common/MQClientErrorContainer.h
+++ b/include/AllocateMQStrategy.h
@@ -14,23 +14,26 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef __MQ_CLIENT_ERROR_CONTAINER_H__
-#define __MQ_CLIENT_ERROR_CONTAINER_H__
+#ifndef __ALLOCATE_MQ_STRATEGY_H__
+#define __ALLOCATE_MQ_STRATEGY_H__
 
-#include <mutex>
 #include <string>
+#include <vector>
+
+#include "MQMessageQueue.h"
 
 namespace rocketmq {
 
-class MQClientErrorContainer {
+class ROCKETMQCLIENT_API AllocateMQStrategy {
  public:
-  static void setErr(const std::string& str);
-  static const std::string& getErr();
+  virtual ~AllocateMQStrategy() = default;
 
- private:
-  static thread_local std::string t_err;
+  virtual void allocate(const std::string& currentCID,
+                        std::vector<MQMessageQueue>& mqAll,
+                        std::vector<std::string>& cidAll,
+                        std::vector<MQMessageQueue>& outReuslt) = 0;
 };
 
 }  // namespace rocketmq
 
-#endif  // __MQ_CLIENT_ERROR_CONTAINER_H__
+#endif  // __ALLOCATE_MQ_STRATEGY_H__
diff --git a/include/AsyncCallback.h b/include/AsyncCallback.h
deleted file mode 100644
index d9dbfe3..0000000
--- a/include/AsyncCallback.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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 __SENDCALLBACK_H__
-#define __SENDCALLBACK_H__
-
-#include "MQClientException.h"
-#include "PullResult.h"
-#include "RocketMQClient.h"
-#include "SendResult.h"
-
-namespace rocketmq {
-//<!***************************************************************************
-struct AsyncCallback {};
-//<!***************************************************************************
-typedef enum sendCallbackType { noAutoDeleteSendCallback = 0, autoDeleteSendCallback = 1 } sendCallbackType;
-
-class ROCKETMQCLIENT_API SendCallback : public AsyncCallback {
- public:
-  virtual ~SendCallback() {}
-  virtual void onSuccess(SendResult& sendResult) = 0;
-  virtual void onException(MQException& e) = 0;
-  virtual sendCallbackType getSendCallbackType() { return noAutoDeleteSendCallback; }
-};
-
-// async SendCallback will be deleted automatically by rocketmq cpp after invoke callback interface
-class ROCKETMQCLIENT_API AutoDeleteSendCallBack : public SendCallback {
- public:
-  virtual ~AutoDeleteSendCallBack() {}
-  virtual void onSuccess(SendResult& sendResult) = 0;
-  virtual void onException(MQException& e) = 0;
-  virtual sendCallbackType getSendCallbackType() { return autoDeleteSendCallback; }
-};
-
-//<!************************************************************************
-class ROCKETMQCLIENT_API PullCallback : public AsyncCallback {
- public:
-  virtual ~PullCallback() {}
-  virtual void onSuccess(MQMessageQueue& mq, PullResult& result, bool bProducePullRequest) = 0;
-  virtual void onException(MQException& e) = 0;
-};
-//<!***************************************************************************
-}  // namespace rocketmq
-#endif
diff --git a/src/common/ClientRPCHook.h b/include/ClientRPCHook.h
similarity index 54%
rename from src/common/ClientRPCHook.h
rename to include/ClientRPCHook.h
index 72e2f76..e2a7d26 100644
--- a/src/common/ClientRPCHook.h
+++ b/include/ClientRPCHook.h
@@ -14,32 +14,32 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#ifndef __CLIENT_RPC_HOOK_H__
+#define __CLIENT_RPC_HOOK_H__
 
-#ifndef __CLIENTRPCHOOK_H__
-#define __CLIENTRPCHOOK_H__
-
-#include "RemotingCommand.h"
+#include "RPCHook.h"
 #include "SessionCredentials.h"
+
 namespace rocketmq {
-class RPCHook {
+
+class ROCKETMQCLIENT_API ClientRPCHook : public RPCHook {
  public:
-  RPCHook() {}
-  virtual ~RPCHook() {}
-  virtual void doBeforeRequest(const string& remoteAddr, RemotingCommand& request) = 0;
-  virtual void doAfterResponse(RemotingCommand& request, RemotingCommand& response) = 0;
-};
+  ClientRPCHook(const SessionCredentials& sessionCredentials) : sessionCredentials_(sessionCredentials) {}
+  ~ClientRPCHook() override = default;
+
+  void doBeforeRequest(const std::string& remoteAddr, RemotingCommand& request, bool toSent) override;
+  void doAfterResponse(const std::string& remoteAddr,
+                       RemotingCommand& request,
+                       RemotingCommand* response,
+                       bool toSent) override;
 
-class ClientRPCHook : public RPCHook {
  private:
-  SessionCredentials sessionCredentials;
+  void signCommand(RemotingCommand& command);
 
- public:
-  ClientRPCHook(const SessionCredentials& session_credentials) : sessionCredentials(session_credentials) {}
-  virtual ~ClientRPCHook() {}
+ private:
+  SessionCredentials sessionCredentials_;
+};
 
-  virtual void doBeforeRequest(const string& remoteAddr, RemotingCommand& request);
+}  // namespace rocketmq
 
-  virtual void doAfterResponse(RemotingCommand& request, RemotingCommand& response) {}
-};
-}
-#endif
+#endif  // __CLIENT_RPC_HOOK_H__
diff --git a/src/protocol/KVTable.h b/include/CommandCustomHeader.h
similarity index 64%
copy from src/protocol/KVTable.h
copy to include/CommandCustomHeader.h
index e9b6a53..66c1b56 100644
--- a/src/protocol/KVTable.h
+++ b/include/CommandCustomHeader.h
@@ -14,31 +14,30 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#ifndef __COMMAND_CUSTOM_HEADER_H__
+#define __COMMAND_CUSTOM_HEADER_H__
 
-#ifndef __KVTABLE_H__
-#define __KVTABLE_H__
 #include <map>
 #include <string>
-#include "RemotingSerializable.h"
 
-using std::map;
-using std::string;
+#include "RocketMQClient.h"
 
-namespace rocketmq {
-//<!***************************************************************************
-class KVTable : public RemotingSerializable {
- public:
-  virtual ~KVTable() { m_table.clear(); }
+namespace Json {
+class Value;
+}
 
-  void Encode(string& outData) {}
+namespace rocketmq {
 
-  const map<string, string>& getTable() { return m_table; }
+class ROCKETMQCLIENT_API CommandCustomHeader {
+ public:
+  virtual ~CommandCustomHeader() = default;
 
-  void setTable(const map<string, string>& table) { m_table = table; }
+  // write CustomHeader to extFields (map<string,string>)
+  virtual void Encode(Json::Value& extFields) {}
 
- private:
-  map<string, string> m_table;
+  virtual void SetDeclaredFieldOfCommandHeader(std::map<std::string, std::string>& requestMap) {}
 };
+
 }  // namespace rocketmq
 
-#endif
+#endif  // __COMMAND_CUSTOM_HEADER_H__
diff --git a/include/ConsumeType.h b/include/ConsumeType.h
index 4cbe5cd..ab54829 100644
--- a/include/ConsumeType.h
+++ b/include/ConsumeType.h
@@ -1,61 +1,63 @@
-/*
- * 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 __CONSUMETYPE_H__
-#define __CONSUMETYPE_H__
-
-namespace rocketmq {
-//<!***************************************************************************
-enum ConsumeType {
-  CONSUME_ACTIVELY,
-  CONSUME_PASSIVELY,
-};
-
-//<!***************************************************************************
-enum ConsumeFromWhere {
-  /**
-   *new consumer will consume from end offset of queue,
-   * and then consume from last consumed offset of queue follow-up
-   */
-  CONSUME_FROM_LAST_OFFSET,
-
-  // @Deprecated
-  CONSUME_FROM_LAST_OFFSET_AND_FROM_MIN_WHEN_BOOT_FIRST,
-  // @Deprecated
-  CONSUME_FROM_MIN_OFFSET,
-  // @Deprecated
-  CONSUME_FROM_MAX_OFFSET,
-  /**
-   *new consumer will consume from first offset of queue,
-   * and then consume from last consumed offset of queue follow-up
-   */
-  CONSUME_FROM_FIRST_OFFSET,
-  /**
-   *new consumer will consume from the queue offset specified by timestamp,
-   * and then consume from last consumed offset of queue follow-up
-   */
-  CONSUME_FROM_TIMESTAMP,
-};
-
-//<!***************************************************************************
-enum MessageModel {
-  BROADCASTING,
-  CLUSTERING,
-};
-//<!***************************************************************************
-}  // namespace rocketmq
-#endif
+/*
+ * 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 __CONSUME_TYPE_H__
+#define __CONSUME_TYPE_H__
+
+namespace rocketmq {
+
+enum ConsumeType {
+  CONSUME_ACTIVELY,
+  CONSUME_PASSIVELY,
+};
+
+enum ConsumeFromWhere {
+  /**
+   * new consumer will consume from end offset of queue,
+   * and then consume from last consumed offset of queue follow-up
+   */
+  CONSUME_FROM_LAST_OFFSET,
+
+  // [[deprecated]]
+  CONSUME_FROM_LAST_OFFSET_AND_FROM_MIN_WHEN_BOOT_FIRST,
+
+  // [[deprecated]]
+  CONSUME_FROM_MIN_OFFSET,
+
+  // [[deprecated]]
+  CONSUME_FROM_MAX_OFFSET,
+
+  /**
+   * new consumer will consume from first offset of queue,
+   * and then consume from last consumed offset of queue follow-up
+   */
+  CONSUME_FROM_FIRST_OFFSET,
+
+  /**
+   *new consumer will consume from the queue offset specified by timestamp,
+   * and then consume from last consumed offset of queue follow-up
+   */
+  CONSUME_FROM_TIMESTAMP,
+};
+
+enum MessageModel {
+  BROADCASTING,
+  CLUSTERING,
+};
+
+}  // namespace rocketmq
+
+#endif  // __CONSUME_TYPE_H__
diff --git a/src/common/noncopyable.h b/include/DefaultMQConsumer.h
similarity index 64%
copy from src/common/noncopyable.h
copy to include/DefaultMQConsumer.h
index f52f988..1f103ac 100644
--- a/src/common/noncopyable.h
+++ b/include/DefaultMQConsumer.h
@@ -14,20 +14,25 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef __NONCOPYABLE_H__
-#define __NONCOPYABLE_H__
+#ifndef __DEFAULT_MQ_CONSUMER_H__
+#define __DEFAULT_MQ_CONSUMER_H__
+
+#include "ConsumeType.h"
+#include "MQClientConfig.h"
 
 namespace rocketmq {
 
-class noncopyable {
- protected:
-  noncopyable() = default;
-  ~noncopyable() = default;
+class ROCKETMQCLIENT_API DefaultMQConsumerConfig : public MQClientConfig {
+ public:
+  DefaultMQConsumerConfig() : m_messageModel(CLUSTERING) {}
 
-  noncopyable(const noncopyable&) = delete;
-  noncopyable& operator=(const noncopyable&) = delete;
+  MessageModel getMessageModel() const { return m_messageModel; }
+  void setMessageModel(MessageModel messageModel) { m_messageModel = messageModel; }
+
+ protected:
+  MessageModel m_messageModel;
 };
 
 }  // namespace rocketmq
 
-#endif  //__NONCOPYABLE_H__
+#endif  // __DEFAULT_MQ_CONSUMER_H__
diff --git a/include/DefaultMQProducer.h b/include/DefaultMQProducer.h
index 630e765..71a1da9 100644
--- a/include/DefaultMQProducer.h
+++ b/include/DefaultMQProducer.h
@@ -1,118 +1,139 @@
-/*
- * 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 __DEFAULTMQPRODUCER_H__
-#define __DEFAULTMQPRODUCER_H__
-
-#include "BatchMessage.h"
-#include "MQMessageQueue.h"
-#include "MQProducer.h"
-#include "RocketMQClient.h"
-#include "SendResult.h"
-
-namespace rocketmq {
-//<!***************************************************************************
-class ROCKETMQCLIENT_API DefaultMQProducer : public MQProducer {
- public:
-  DefaultMQProducer(const std::string& groupname);
-  virtual ~DefaultMQProducer();
-
-  //<!begin mqadmin;
-  virtual void start();
-  virtual void shutdown();
-  //<!end mqadmin;
-
-  //<! begin MQProducer;
-  virtual SendResult send(MQMessage& msg, bool bSelectActiveBroker = false);
-  virtual SendResult send(MQMessage& msg, const MQMessageQueue& mq);
-  virtual SendResult send(MQMessage& msg, MessageQueueSelector* selector, void* arg);
-  virtual SendResult send(MQMessage& msg,
-                          MessageQueueSelector* selector,
-                          void* arg,
-                          int autoRetryTimes,
-                          bool bActiveBroker = false);
-  virtual SendResult send(std::vector<MQMessage>& msgs);
-  virtual SendResult send(std::vector<MQMessage>& msgs, const MQMessageQueue& mq);
-  virtual void send(MQMessage& msg, SendCallback* pSendCallback, bool bSelectActiveBroker = false);
-  virtual void send(MQMessage& msg, const MQMessageQueue& mq, SendCallback* pSendCallback);
-  virtual void send(MQMessage& msg, MessageQueueSelector* selector, void* arg, SendCallback* pSendCallback);
-  virtual void sendOneway(MQMessage& msg, bool bSelectActiveBroker = false);
-  virtual void sendOneway(MQMessage& msg, const MQMessageQueue& mq);
-  virtual void sendOneway(MQMessage& msg, MessageQueueSelector* selector, void* arg);
-  //<! end MQProducer;
-
-  // set and get timeout of per msg
-  int getSendMsgTimeout() const;
-  void setSendMsgTimeout(int sendMsgTimeout);
-
-  /*
-  *  if msgBody size is large than m_compressMsgBodyOverHowmuch
-      rocketmq cpp will compress msgBody according to compressLevel
-  */
-  int getCompressMsgBodyOverHowmuch() const;
-  void setCompressMsgBodyOverHowmuch(int compressMsgBodyOverHowmuch);
-  int getCompressLevel() const;
-  void setCompressLevel(int compressLevel);
-
-  // if msgbody size larger than maxMsgBodySize, exception will be throwed
-  int getMaxMessageSize() const;
-  void setMaxMessageSize(int maxMessageSize);
-
-  // set msg max retry times, default retry times is 5
-  int getRetryTimes() const;
-  void setRetryTimes(int times);
-
-  int getRetryTimes4Async() const;
-  void setRetryTimes4Async(int times);
-
- protected:
-  SendResult sendAutoRetrySelectImpl(MQMessage& msg,
-                                     MessageQueueSelector* pSelector,
-                                     void* pArg,
-                                     int communicationMode,
-                                     SendCallback* pSendCallback,
-                                     int retryTimes,
-                                     bool bActiveBroker = false);
-  SendResult sendSelectImpl(MQMessage& msg,
-                            MessageQueueSelector* pSelector,
-                            void* pArg,
-                            int communicationMode,
-                            SendCallback* sendCallback);
-  SendResult sendDefaultImpl(MQMessage& msg,
-                             int communicationMode,
-                             SendCallback* pSendCallback,
-                             bool bActiveBroker = false);
-  SendResult sendKernelImpl(MQMessage& msg,
-                            const MQMessageQueue& mq,
-                            int communicationMode,
-                            SendCallback* pSendCallback);
-  bool tryToCompressMessage(MQMessage& msg);
-  BatchMessage buildBatchMessage(std::vector<MQMessage>& msgs);
-  bool dealWithNameSpace();
-
- private:
-  int m_sendMsgTimeout;
-  int m_compressMsgBodyOverHowmuch;
-  int m_maxMessageSize;  //<! default:128K;
-  // bool m_retryAnotherBrokerWhenNotStoreOK;
-  int m_compressLevel;
-  int m_retryTimes;
-  int m_retryTimes4Async;
-};
-//<!***************************************************************************
-}  // namespace rocketmq
-#endif
+/*
+ * 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 __DEFAULT_MQ_PRODUCER_H__
+#define __DEFAULT_MQ_PRODUCER_H__
+
+#include "MQClientConfig.h"
+#include "MQProducer.h"
+#include "RPCHook.h"
+
+namespace rocketmq {
+
+class ROCKETMQCLIENT_API DefaultMQProducerConfig : public MQClientConfig {
+ public:
+  DefaultMQProducerConfig();
+  virtual ~DefaultMQProducerConfig() = default;
+
+  // if msgbody size larger than maxMsgBodySize, exception will be throwed
+  int getMaxMessageSize() const { return m_maxMessageSize; }
+  void setMaxMessageSize(int maxMessageSize) { m_maxMessageSize = maxMessageSize; }
+
+  /*
+   * if msgBody size is large than m_compressMsgBodyOverHowmuch
+   *  rocketmq cpp will compress msgBody according to compressLevel
+   */
+  int getCompressMsgBodyOverHowmuch() const { return m_compressMsgBodyOverHowmuch; }
+  void setCompressMsgBodyOverHowmuch(int compressMsgBodyOverHowmuch) {
+    m_compressMsgBodyOverHowmuch = compressMsgBodyOverHowmuch;
+  }
+
+  int getCompressLevel() const { return m_compressLevel; }
+  void setCompressLevel(int compressLevel) {
+    if ((compressLevel >= 0 && compressLevel <= 9) || compressLevel == -1) {
+      m_compressLevel = compressLevel;
+    }
+  }
+
+  // set and get timeout of per msg
+  int getSendMsgTimeout() const { return m_sendMsgTimeout; }
+  void setSendMsgTimeout(int sendMsgTimeout) { m_sendMsgTimeout = sendMsgTimeout; }
+
+  // set msg max retry times, default retry times is 5
+  int getRetryTimes() const { return m_retryTimes; }
+  void setRetryTimes(int times) { m_retryTimes = std::min(std::max(0, times), 15); }
+
+  int getRetryTimes4Async() const { return m_retryTimes4Async; }
+  void setRetryTimes4Async(int times) { m_retryTimes4Async = std::min(std::max(0, times), 15); }
+
+  bool isRetryAnotherBrokerWhenNotStoreOK() const { return m_retryAnotherBrokerWhenNotStoreOK; }
+  void setRetryAnotherBrokerWhenNotStoreOK(bool retryAnotherBrokerWhenNotStoreOK) {
+    m_retryAnotherBrokerWhenNotStoreOK = retryAnotherBrokerWhenNotStoreOK;
+  }
+
+  virtual bool isSendLatencyFaultEnable() const = 0;
+  virtual void setSendLatencyFaultEnable(bool sendLatencyFaultEnable) = 0;
+
+ protected:
+  int m_maxMessageSize;              // default: 4 MB
+  int m_compressMsgBodyOverHowmuch;  // default: 4 KB
+  int m_compressLevel;
+  int m_sendMsgTimeout;
+  int m_retryTimes;
+  int m_retryTimes4Async;
+  bool m_retryAnotherBrokerWhenNotStoreOK;
+};
+
+class ROCKETMQCLIENT_API DefaultMQProducer : public MQProducer, public DefaultMQProducerConfig {
+ public:
+  DefaultMQProducer(const std::string& groupname);
+  DefaultMQProducer(const std::string& groupname, RPCHookPtr rpcHook);
+  virtual ~DefaultMQProducer();
+
+ public:  // MQProducer
+  void start() override;
+  void shutdown() override;
+
+  // Sync: caller will be responsible for the lifecycle of messages.
+  SendResult send(MQMessagePtr msg) override;
+  SendResult send(MQMessagePtr msg, long timeout) override;
+  SendResult send(MQMessagePtr msg, const MQMessageQueue& mq) override;
+  SendResult send(MQMessagePtr msg, const MQMessageQueue& mq, long timeout) override;
+
+  // Async: don't delete msg object, until callback occur.
+  void send(MQMessagePtr msg, SendCallback* sendCallback) noexcept override;
+  void send(MQMessagePtr msg, SendCallback* sendCallback, long timeout) noexcept override;
+  void send(MQMessagePtr msg, const MQMessageQueue& mq, SendCallback* sendCallback) noexcept override;
+  void send(MQMessagePtr msg, const MQMessageQueue& mq, SendCallback* sendCallback, long timeout) noexcept override;
+
+  // Oneyway: same as sync send, but don't care its result.
+  void sendOneway(MQMessagePtr msg) override;
+  void sendOneway(MQMessagePtr msg, const MQMessageQueue& mq) override;
+
+  // Select
+  SendResult send(MQMessagePtr msg, MessageQueueSelector* selector, void* arg) override;
+  SendResult send(MQMessagePtr msg, MessageQueueSelector* selector, void* arg, long timeout) override;
+  void send(MQMessagePtr msg, MessageQueueSelector* selector, void* arg, SendCallback* sendCallback) noexcept override;
+  void send(MQMessagePtr msg,
+            MessageQueueSelector* selector,
+            void* arg,
+            SendCallback* sendCallback,
+            long timeout) noexcept override;
+  void sendOneway(MQMessagePtr msg, MessageQueueSelector* selector, void* arg) override;
+
+  // Transaction
+  TransactionSendResult sendMessageInTransaction(MQMessagePtr msg, void* arg) override;
+
+  // Batch: power by sync send, caller will be responsible for the lifecycle of messages.
+  SendResult send(std::vector<MQMessagePtr>& msgs) override;
+  SendResult send(std::vector<MQMessagePtr>& msgs, long timeout) override;
+  SendResult send(std::vector<MQMessagePtr>& msgs, const MQMessageQueue& mq) override;
+  SendResult send(std::vector<MQMessagePtr>& msgs, const MQMessageQueue& mq, long timeout) override;
+
+ public:  // DefaultMQProducerConfig
+  bool isSendLatencyFaultEnable() const override;
+  void setSendLatencyFaultEnable(bool sendLatencyFaultEnable) override;
+
+ public:
+  void setRPCHook(std::shared_ptr<RPCHook> rpcHook);
+
+ protected:
+  std::shared_ptr<MQProducer> m_producerDelegate;
+};
+
+}  // namespace rocketmq
+
+#endif  // __DEFAULT_MQ_PRODUCER_H__
diff --git a/include/DefaultMQPullConsumer.h b/include/DefaultMQPullConsumer.h
old mode 100644
new mode 100755
index 8e1612d..1bd7aff
--- a/include/DefaultMQPullConsumer.h
+++ b/include/DefaultMQPullConsumer.h
@@ -1,148 +1,93 @@
-/*
- * 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 __DEFAULTMQPULLCONSUMER_H__
-#define __DEFAULTMQPULLCONSUMER_H__
-
-#include <set>
-#include <string>
-#include "MQConsumer.h"
-#include "MQMessageQueue.h"
-#include "MQueueListener.h"
-#include "RocketMQClient.h"
-
-namespace rocketmq {
-class Rebalance;
-class SubscriptionData;
-class OffsetStore;
-class PullAPIWrapper;
-class ConsumerRunningInfo;
-//<!***************************************************************************
-class ROCKETMQCLIENT_API DefaultMQPullConsumer : public MQConsumer {
- public:
-  DefaultMQPullConsumer(const std::string& groupname);
-  virtual ~DefaultMQPullConsumer();
-
-  //<!begin mqadmin;
-  virtual void start();
-  virtual void shutdown();
-  //<!end mqadmin;
-
-  //<!begin MQConsumer
-  virtual bool sendMessageBack(MQMessageExt& msg, int delayLevel, std::string& brokerName);
-  virtual void fetchSubscribeMessageQueues(const std::string& topic, std::vector<MQMessageQueue>& mqs);
-  virtual void doRebalance();
-  virtual void persistConsumerOffset();
-  virtual void persistConsumerOffsetByResetOffset();
-  virtual void updateTopicSubscribeInfo(const std::string& topic, std::vector<MQMessageQueue>& info);
-  virtual ConsumeType getConsumeType();
-  virtual ConsumeFromWhere getConsumeFromWhere();
-  virtual void getSubscriptions(std::vector<SubscriptionData>&);
-  virtual void updateConsumeOffset(const MQMessageQueue& mq, int64 offset);
-  virtual void removeConsumeOffset(const MQMessageQueue& mq);
-  virtual bool producePullMsgTask(boost::weak_ptr<PullRequest> pullRequest);
-  virtual Rebalance* getRebalance() const;
-  //<!end MQConsumer;
-
-  void registerMessageQueueListener(const std::string& topic, MQueueListener* pListener);
-  /**
-   * Pull message from specified queue, if no msg in queue, return directly
-   *
-   * @param mq
-   *            specify the pulled queue
-   * @param subExpression
-   *            set filter expression for pulled msg, broker will filter msg actively
-   *            Now only OR operation is supported, eg: "tag1 || tag2 || tag3"
-   *            if subExpression is setted to "null" or "*", all msg will be subscribed
-   * @param offset
-   *            specify the started pull offset
-   * @param maxNums
-   *            specify max msg num by per pull
-   * @return
-   *            PullResult
-   */
-  virtual PullResult pull(const MQMessageQueue& mq, const std::string& subExpression, int64 offset, int maxNums);
-  virtual void pull(const MQMessageQueue& mq,
-                    const std::string& subExpression,
-                    int64 offset,
-                    int maxNums,
-                    PullCallback* pPullCallback);
-
-  /**
-   * pull msg from specified queue, if no msg, broker will suspend the pull request 20s
-   *
-   * @param mq
-   *            specify the pulled queue
-   * @param subExpression
-   *            set filter expression for pulled msg, broker will filter msg actively
-   *            Now only OR operation is supported, eg: "tag1 || tag2 || tag3"
-   *            if subExpression is setted to "null" or "*", all msg will be subscribed
-   * @param offset
-   *            specify the started pull offset
-   * @param maxNums
-   *            specify max msg num by per pull
-   * @return
-   *            accroding to PullResult
-   */
-  PullResult pullBlockIfNotFound(const MQMessageQueue& mq, const std::string& subExpression, int64 offset, int maxNums);
-  void pullBlockIfNotFound(const MQMessageQueue& mq,
-                           const std::string& subExpression,
-                           int64 offset,
-                           int maxNums,
-                           PullCallback* pPullCallback);
-
-  virtual ConsumerRunningInfo* getConsumerRunningInfo() { return NULL; }
-
-  int64 fetchConsumeOffset(const MQMessageQueue& mq, bool fromStore);
-
-  void fetchMessageQueuesInBalance(const std::string& topic, std::vector<MQMessageQueue> mqs);
-
-  // temp persist consumer offset interface, only valid with
-  // RemoteBrokerOffsetStore, updateConsumeOffset should be called before.
-  void persistConsumerOffset4PullConsumer(const MQMessageQueue& mq);
-
- private:
-  void checkConfig();
-  void copySubscription();
-  bool dealWithNameSpace();
-
-  PullResult pullSyncImpl(const MQMessageQueue& mq,
-                          const std::string& subExpression,
-                          int64 offset,
-                          int maxNums,
-                          bool block);
-
-  void pullAsyncImpl(const MQMessageQueue& mq,
-                     const std::string& subExpression,
-                     int64 offset,
-                     int maxNums,
-                     bool block,
-                     PullCallback* pPullCallback);
-
-  void subscriptionAutomatically(const std::string& topic);
-
- private:
-  std::set<std::string> m_registerTopics;
-
-  MQueueListener* m_pMessageQueueListener;
-  OffsetStore* m_pOffsetStore;
-  Rebalance* m_pRebalance;
-  PullAPIWrapper* m_pPullAPIWrapper;
-};
-//<!***************************************************************************
-}  // namespace rocketmq
-#endif
+/*
+ * 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 __DEFAULT_MQ_PULL_CONSUMER_H__
+#define __DEFAULT_MQ_PULL_CONSUMER_H__
+
+#include <set>
+#include <string>
+
+#include "AllocateMQStrategy.h"
+#include "DefaultMQConsumer.h"
+#include "MQPullConsumer.h"
+#include "RPCHook.h"
+
+namespace rocketmq {
+
+class ROCKETMQCLIENT_API DefaultMQPullConsumerConfig : public DefaultMQConsumerConfig {
+ public:
+  DefaultMQPullConsumerConfig();
+  virtual ~DefaultMQPullConsumerConfig() = default;
+
+  AllocateMQStrategy* getAllocateMQStrategy() { return m_allocateMQStrategy.get(); }
+  void setAllocateMQStrategy(AllocateMQStrategy* strategy) { m_allocateMQStrategy.reset(strategy); }
+
+ protected:
+  std::unique_ptr<AllocateMQStrategy> m_allocateMQStrategy;
+};
+
+class ROCKETMQCLIENT_API DefaultMQPullConsumer : public MQPullConsumer, public DefaultMQPullConsumerConfig {
+ public:
+  DefaultMQPullConsumer(const std::string& groupname);
+  DefaultMQPullConsumer(const std::string& groupname, RPCHookPtr rpcHook);
+  virtual ~DefaultMQPullConsumer();
+
+ public:  // MQConsumer
+  void start() override;
+  void shutdown() override;
+
+  bool sendMessageBack(MQMessageExt& msg, int delayLevel) override;
+  bool sendMessageBack(MQMessageExt& msg, int delayLevel, const std::string& brokerName) override;
+  void fetchSubscribeMessageQueues(const std::string& topic, std::vector<MQMessageQueue>& mqs) override;
+
+ public:  // MQPullConsumer
+  void registerMessageQueueListener(const std::string& topic, MQueueListener* pListener) override;
+
+  PullResult pull(const MQMessageQueue& mq, const std::string& subExpression, int64_t offset, int maxNums) override;
+
+  void pull(const MQMessageQueue& mq,
+            const std::string& subExpression,
+            int64_t offset,
+            int maxNums,
+            PullCallback* pullCallback) override;
+
+  PullResult pullBlockIfNotFound(const MQMessageQueue& mq,
+                                 const std::string& subExpression,
+                                 int64_t offset,
+                                 int maxNums) override;
+
+  void pullBlockIfNotFound(const MQMessageQueue& mq,
+                           const std::string& subExpression,
+                           int64_t offset,
+                           int maxNums,
+                           PullCallback* pullCallback) override;
+
+  void updateConsumeOffset(const MQMessageQueue& mq, int64_t offset) override;
+
+  int64_t fetchConsumeOffset(const MQMessageQueue& mq, bool fromStore) override;
+
+  void fetchMessageQueuesInBalance(const std::string& topic, std::vector<MQMessageQueue>& mqs) override;
+
+ public:
+  void setRPCHook(std::shared_ptr<RPCHook> rpcHook);
+
+ protected:
+  std::shared_ptr<MQPullConsumer> m_pullConsumerDelegate;
+};
+
+}  // namespace rocketmq
+
+#endif  // __DEFAULT_MQ_PULL_CONSUMER_H__
diff --git a/include/DefaultMQPushConsumer.h b/include/DefaultMQPushConsumer.h
old mode 100644
new mode 100755
index 7f69258..1caf98f
--- a/include/DefaultMQPushConsumer.h
+++ b/include/DefaultMQPushConsumer.h
@@ -1,165 +1,125 @@
-/*
- * 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 __DEFAULTMQPUSHCONSUMER_H__
-#define __DEFAULTMQPUSHCONSUMER_H__
-
-#include <boost/asio.hpp>
-#include <boost/asio/io_service.hpp>
-#include <boost/bind.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
-#include <boost/scoped_ptr.hpp>
-#include <boost/thread/thread.hpp>
-#include <string>
-#include "AsyncCallback.h"
-#include "MQConsumer.h"
-#include "MQMessageListener.h"
-#include "MQMessageQueue.h"
-
-namespace rocketmq {
-
-class Rebalance;
-class SubscriptionData;
-class OffsetStore;
-class PullAPIWrapper;
-class PullRequest;
-class ConsumeMsgService;
-class TaskQueue;
-class TaskThread;
-class AsyncPullCallback;
-class ConsumerRunningInfo;
-//<!***************************************************************************
-class ROCKETMQCLIENT_API DefaultMQPushConsumer : public MQConsumer {
- public:
-  DefaultMQPushConsumer(const std::string& groupname);
-  void boost_asio_work();
-  virtual ~DefaultMQPushConsumer();
-
-  //<!begin mqadmin;
-  virtual void start();
-  virtual void shutdown();
-  //<!end mqadmin;
-
-  //<!begin MQConsumer
-  virtual bool sendMessageBack(MQMessageExt& msg, int delayLevel, std::string& brokerName);
-  virtual void fetchSubscribeMessageQueues(const std::string& topic, std::vector<MQMessageQueue>& mqs);
-  virtual void doRebalance();
-  virtual void persistConsumerOffset();
-  virtual void persistConsumerOffsetByResetOffset();
-  virtual void updateTopicSubscribeInfo(const std::string& topic, std::vector<MQMessageQueue>& info);
-  virtual ConsumeType getConsumeType();
-  virtual ConsumeFromWhere getConsumeFromWhere();
-  void setConsumeFromWhere(ConsumeFromWhere consumeFromWhere);
-  virtual void getSubscriptions(std::vector<SubscriptionData>&);
-  virtual void updateConsumeOffset(const MQMessageQueue& mq, int64 offset);
-  virtual void removeConsumeOffset(const MQMessageQueue& mq);
-  virtual PullResult pull(const MQMessageQueue& mq, const std::string& subExpression, int64 offset, int maxNums) {
-    return PullResult();
-  }
-  virtual void pull(const MQMessageQueue& mq,
-                    const std::string& subExpression,
-                    int64 offset,
-                    int maxNums,
-                    PullCallback* pPullCallback) {}
-  virtual ConsumerRunningInfo* getConsumerRunningInfo();
-  //<!end MQConsumer;
-
-  void registerMessageListener(MQMessageListener* pMessageListener);
-  MessageListenerType getMessageListenerType();
-  void subscribe(const std::string& topic, const std::string& subExpression);
-
-  OffsetStore* getOffsetStore() const;
-  virtual Rebalance* getRebalance() const;
-  ConsumeMsgService* getConsumerMsgService() const;
-
-  virtual bool producePullMsgTask(boost::weak_ptr<PullRequest>);
-  virtual bool producePullMsgTaskLater(boost::weak_ptr<PullRequest>, int millis);
-  static void static_triggerNextPullRequest(void* context,
-                                            boost::asio::deadline_timer* t,
-                                            boost::weak_ptr<PullRequest>);
-  void triggerNextPullRequest(boost::asio::deadline_timer* t, boost::weak_ptr<PullRequest>);
-  void runPullMsgQueue(TaskQueue* pTaskQueue);
-  void pullMessage(boost::weak_ptr<PullRequest> pullrequest);
-  void pullMessageAsync(boost::weak_ptr<PullRequest> pullrequest);
-  void setAsyncPull(bool asyncFlag);
-  AsyncPullCallback* getAsyncPullCallBack(boost::weak_ptr<PullRequest>, MQMessageQueue msgQueue);
-  void shutdownAsyncPullCallBack();
-
-  /*
-    for orderly consume, set the pull num of message size by each pullMsg,
-    default value is 1;
-  */
-  void setConsumeMessageBatchMaxSize(int consumeMessageBatchMaxSize);
-  int getConsumeMessageBatchMaxSize() const;
-
-  /*
-    set consuming thread count, default value is cpu cores
-  */
-  void setConsumeThreadCount(int threadCount);
-  int getConsumeThreadCount() const;
-  void setMaxReconsumeTimes(int maxReconsumeTimes);
-  int getMaxReconsumeTimes() const;
-
-  /*
-    set pullMsg thread count, default value is cpu cores
-  */
-  void setPullMsgThreadPoolCount(int threadCount);
-  int getPullMsgThreadPoolCount() const;
-
-  /*
-    set max cache msg size perQueue in memory if consumer could not consume msgs
-    immediately
-    default maxCacheMsgSize perQueue is 1000, set range is:1~65535
-  */
-  void setMaxCacheMsgSizePerQueue(int maxCacheSize);
-  int getMaxCacheMsgSizePerQueue() const;
-
- private:
-  void checkConfig();
-  void copySubscription();
-  void updateTopicSubscribeInfoWhenSubscriptionChanged();
-  bool dealWithNameSpace();
-
- private:
-  uint64_t m_startTime;
-  ConsumeFromWhere m_consumeFromWhere;
-  std::map<std::string, std::string> m_subTopics;
-  int m_consumeThreadCount;
-  OffsetStore* m_pOffsetStore;
-  Rebalance* m_pRebalance;
-  PullAPIWrapper* m_pPullAPIWrapper;
-  ConsumeMsgService* m_consumerService;
-  MQMessageListener* m_pMessageListener;
-  int m_consumeMessageBatchMaxSize;
-  int m_maxMsgCacheSize;
-  int m_maxReconsumeTimes = -1;
-  boost::asio::io_service m_async_ioService;
-  boost::scoped_ptr<boost::thread> m_async_service_thread;
-
-  typedef std::map<MQMessageQueue, AsyncPullCallback*> PullMAP;
-  PullMAP m_PullCallback;
-  bool m_asyncPull;
-  int m_asyncPullTimeout;
-  int m_pullMsgThreadPoolNum;
-
- private:
-  TaskQueue* m_pullmsgQueue;
-  std::unique_ptr<boost::thread> m_pullmsgThread;
-};
-//<!***************************************************************************
-}  // namespace rocketmq
-#endif
+/*
+ * 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 __DEFAULT_MQ_PUSH_CONSUMER_H__
+#define __DEFAULT_MQ_PUSH_CONSUMER_H__
+
+#include "AllocateMQStrategy.h"
+#include "DefaultMQConsumer.h"
+#include "MQPushConsumer.h"
+#include "RPCHook.h"
+
+namespace rocketmq {
+
+class ROCKETMQCLIENT_API DefaultMQPushConsumerConfig : public DefaultMQConsumerConfig {
+ public:
+  DefaultMQPushConsumerConfig();
+  virtual ~DefaultMQPushConsumerConfig() = default;
+
+  ConsumeFromWhere getConsumeFromWhere() const { return m_consumeFromWhere; }
+  void setConsumeFromWhere(ConsumeFromWhere consumeFromWhere) { m_consumeFromWhere = consumeFromWhere; }
+
+  std::string getConsumeTimestamp() { return m_consumeTimestamp; }
+  void setConsumeTimestamp(std::string consumeTimestamp) { m_consumeTimestamp = consumeTimestamp; }
+
+  /**
+   * consuming thread count, default value is cpu cores
+   */
+  int getConsumeThreadNum() const { return m_consumeThreadNum; }
+  void setConsumeThreadNum(int threadNum) {
+    if (threadNum > 0) {
+      m_consumeThreadNum = threadNum;
+    }
+  }
+
+  /**
+   * the pull number of message size by each pullMsg for orderly consume, default value is 1
+   */
+  int getConsumeMessageBatchMaxSize() const { return m_consumeMessageBatchMaxSize; }
+  void setConsumeMessageBatchMaxSize(int consumeMessageBatchMaxSize) {
+    if (consumeMessageBatchMaxSize >= 1) {
+      m_consumeMessageBatchMaxSize = consumeMessageBatchMaxSize;
+    }
+  }
+
+  /**
+   * max cache msg size per Queue in memory if consumer could not consume msgs immediately,
+   * default maxCacheMsgSize per Queue is 1000, set range is:1~65535
+   */
+  int getMaxCacheMsgSizePerQueue() const { return m_maxMsgCacheSize; }
+  void setMaxCacheMsgSizePerQueue(int maxCacheSize) {
+    if (maxCacheSize > 0 && maxCacheSize < 65535) {
+      m_maxMsgCacheSize = maxCacheSize;
+    }
+  }
+
+  int getAsyncPullTimeout() const { return m_asyncPullTimeout; }
+  void setAsyncPullTimeout(int asyncPullTimeout) { m_asyncPullTimeout = asyncPullTimeout; }
+
+  int getMaxReconsumeTimes() { return m_maxReconsumeTimes; }
+  void setMaxReconsumeTimes(int maxReconsumeTimes) { m_maxReconsumeTimes = maxReconsumeTimes; }
+
+  AllocateMQStrategy* getAllocateMQStrategy() { return m_allocateMQStrategy.get(); }
+  void setAllocateMQStrategy(AllocateMQStrategy* strategy) { m_allocateMQStrategy.reset(strategy); }
+
+ protected:
+  ConsumeFromWhere m_consumeFromWhere;
+  std::string m_consumeTimestamp;
+
+  int m_consumeThreadNum;
+  int m_consumeMessageBatchMaxSize;
+  int m_maxMsgCacheSize;
+
+  int m_asyncPullTimeout;  // 30s
+  int m_maxReconsumeTimes;
+
+  std::unique_ptr<AllocateMQStrategy> m_allocateMQStrategy;
+};
+
+class ROCKETMQCLIENT_API DefaultMQPushConsumer : public MQPushConsumer, public DefaultMQPushConsumerConfig {
+ public:
+  DefaultMQPushConsumer(const std::string& groupname);
+  DefaultMQPushConsumer(const std::string& groupname, RPCHookPtr rpcHook);
+  virtual ~DefaultMQPushConsumer();
+
+ public:  // MQConsumer
+  void start() override;
+  void shutdown() override;
+
+  bool sendMessageBack(MQMessageExt& msg, int delayLevel) override;
+  bool sendMessageBack(MQMessageExt& msg, int delayLevel, const std::string& brokerName) override;
+  void fetchSubscribeMessageQueues(const std::string& topic, std::vector<MQMessageQueue>& mqs) override;
+
+ public:  // MQPushConsumer
+  void registerMessageListener(MQMessageListener* messageListener) override;
+  void registerMessageListener(MessageListenerConcurrently* messageListener) override;
+  void registerMessageListener(MessageListenerOrderly* messageListener) override;
+
+  void subscribe(const std::string& topic, const std::string& subExpression) override;
+
+  void suspend() override;
+  void resume() override;
+
+ public:
+  void setRPCHook(std::shared_ptr<RPCHook> rpcHook);
+
+ protected:
+  std::shared_ptr<MQPushConsumer> m_pushConsumerDelegate;
+};
+
+}  // namespace rocketmq
+
+#endif  // __DEFAULT_MQ_PUSH_CONSUMER_H__
diff --git a/include/MQAdmin.h b/include/MQAdmin.h
new file mode 100644
index 0000000..50179ce
--- /dev/null
+++ b/include/MQAdmin.h
@@ -0,0 +1,103 @@
+/*
+ * 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 __MQ_ADMIN_H__
+#define __MQ_ADMIN_H__
+
+#include "MQMessageExt.h"
+#include "MQMessageQueue.h"
+#include "QueryResult.h"
+
+namespace rocketmq {
+
+/**
+ * MQ Admin API
+ */
+class ROCKETMQCLIENT_API MQAdmin {
+ public:
+  virtual ~MQAdmin() = default;
+
+  /**
+   * Creates an topic
+   *
+   * @param key accesskey
+   * @param newTopic topic name
+   * @param queueNum topic's queue number
+   */
+  virtual void createTopic(const std::string& key, const std::string& newTopic, int queueNum) = 0;
+
+  /**
+   * Gets the message queue offset according to some time in milliseconds<br>
+   * be cautious to call because of more IO overhead
+   *
+   * @param mq Instance of MessageQueue
+   * @param timestamp from when in milliseconds.
+   * @return offset
+   */
+  virtual int64_t searchOffset(const MQMessageQueue& mq, uint64_t timestamp) = 0;
+
+  /**
+   * Gets the max offset
+   *
+   * @param mq Instance of MessageQueue
+   * @return the max offset
+   */
+  virtual int64_t maxOffset(const MQMessageQueue& mq) = 0;
+
+  /**
+   * Gets the minimum offset
+   *
+   * @param mq Instance of MessageQueue
+   * @return the minimum offset
+   */
+  virtual int64_t minOffset(const MQMessageQueue& mq) = 0;
+
+  /**
+   * Gets the earliest stored message time
+   *
+   * @param mq Instance of MessageQueue
+   * @return the time in microseconds
+   */
+  virtual int64_t earliestMsgStoreTime(const MQMessageQueue& mq) = 0;
+
+  /**
+   * Query message according to message id
+   *
+   * @param offsetMsgId message id
+   * @return message
+   */
+  virtual MQMessageExtPtr viewMessage(const std::string& offsetMsgId) = 0;
+
+  /**
+   * Query messages
+   *
+   * @param topic message topic
+   * @param key message key index word
+   * @param maxNum max message number
+   * @param begin from when
+   * @param end to when
+   * @return Instance of QueryResult
+   */
+  virtual QueryResult queryMessage(const std::string& topic,
+                                   const std::string& key,
+                                   int maxNum,
+                                   int64_t begin,
+                                   int64_t end) = 0;
+};
+
+}  // namespace rocketmq
+
+#endif  // __MQ_ADMIN_H__
diff --git a/include/MQClient.h b/include/MQClient.h
deleted file mode 100644
index 0e23339..0000000
--- a/include/MQClient.h
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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 __MQADMIN_H__
-#define __MQADMIN_H__
-#include <boost/asio.hpp>
-#include <boost/asio/io_service.hpp>
-#include <boost/bind.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
-#include <boost/thread/mutex.hpp>
-#include <boost/thread/thread.hpp>
-#include "MQMessageExt.h"
-#include "MQMessageQueue.h"
-#include "QueryResult.h"
-#include "RocketMQClient.h"
-#include "SessionCredentials.h"
-
-namespace rocketmq {
-class MQClientFactory;
-//<!***************************************************************************
-
-enum elogLevel {
-  eLOG_LEVEL_FATAL = 1,
-  eLOG_LEVEL_ERROR = 2,
-  eLOG_LEVEL_WARN = 3,
-  eLOG_LEVEL_INFO = 4,
-  eLOG_LEVEL_DEBUG = 5,
-  eLOG_LEVEL_TRACE = 6,
-  eLOG_LEVEL_LEVEL_NUM = 7
-};
-
-class ROCKETMQCLIENT_API MQClient {
- public:
-  MQClient();
-  virtual ~MQClient();
-
- public:
-  // clientid=processId-ipAddr@instanceName;
-  std::string getMQClientId() const;
-  const std::string& getNamesrvAddr() const;
-  void setNamesrvAddr(const std::string& namesrvAddr);
-  const std::string& getNamesrvDomain() const;
-  void setNamesrvDomain(const std::string& namesrvDomain);
-  const std::string& getInstanceName() const;
-  void setInstanceName(const std::string& instanceName);
-  // nameSpace
-  const std::string& getNameSpace() const;
-  void setNameSpace(const std::string& nameSpace);
-  const std::string& getGroupName() const;
-  void setGroupName(const std::string& groupname);
-
-  /**
-   * no realization
-   */
-  void createTopic(const std::string& key, const std::string& newTopic, int queueNum);
-  /**
-   * search earliest msg store time for specified queue
-   *
-   * @param mq
-   *            message queue
-   * @return earliest store time, ms
-   */
-  int64 earliestMsgStoreTime(const MQMessageQueue& mq);
-  /**
-   * search maxOffset of queue
-   *
-   * @param mq
-   *            message queue
-   * @return minOffset of queue
-   */
-  int64 minOffset(const MQMessageQueue& mq);
-  /**
-   * search maxOffset of queue
-   * Note: maxOffset-1 is max offset that could get msg
-   * @param mq
-   *            message queue
-   * @return maxOffset of queue
-   */
-  int64 maxOffset(const MQMessageQueue& mq);
-  /**
-   * get queue offset by timestamp
-   *
-   * @param mq
-   *            mq queue
-   * @param timestamp
-   *            timestamp with ms unit
-   * @return queue offset according to timestamp
-   */
-  int64 searchOffset(const MQMessageQueue& mq, uint64_t timestamp);
-  /**
-   * get whole msg info from broker by msgId
-   *
-   * @param msgId
-   * @return MQMessageExt
-   */
-  MQMessageExt* viewMessage(const std::string& msgId);
-  /**
-   * query message by topic and key
-   *
-   * @param topic
-   *            topic name
-   * @param key
-   *            topic key
-   * @param maxNum
-   *            query num
-   * @param begin
-   *            begin timestamp
-   * @param end
-   *            end timestamp
-   * @return
-   *            according to QueryResult
-   */
-  QueryResult queryMessage(const std::string& topic, const std::string& key, int maxNum, int64 begin, int64 end);
-
-  std::vector<MQMessageQueue> getTopicMessageQueueInfo(const std::string& topic);
-
-  // log configuration interface, default LOG_LEVEL is LOG_LEVEL_INFO, default
-  // log file num is 3, each log size is 100M
-  void setLogLevel(elogLevel inputLevel);
-  elogLevel getLogLevel();
-  void setLogFileSizeAndNum(int fileNum, long perFileSize);  // perFileSize is MB unit
-
-  /** set TcpTransport pull thread num, which dermine the num of threads to
- distribute network data,
-     1. its default value is CPU num, it must be setted before producer/consumer
- start, minimum value is CPU num;
-     2. this pullThread num must be tested on your environment to find the best
- value for RT of sendMsg or delay time of consume msg before you change it;
-     3. producer and consumer need different pullThread num, if set this num,
- producer and consumer must set different instanceName.
-     4. configuration suggestion:
-         1>. minimum RT of sendMsg:
-                 pullThreadNum = brokerNum*2
- **/
-  void setTcpTransportPullThreadNum(int num);
-  const int getTcpTransportPullThreadNum() const;
-
-  /** timeout of tcp connect, it is same meaning for both producer and consumer;
-      1. default value is 3000ms
-      2. input parameter could only be milliSecond, suggestion value is
-  1000-3000ms;
-  **/
-  void setTcpTransportConnectTimeout(uint64_t timeout);  // ms
-  const uint64_t getTcpTransportConnectTimeout() const;
-
-  /** timeout of tryLock tcpTransport before sendMsg/pullMsg, if timeout,
-  returns NULL
-      1. paremeter unit is ms, default value is 3000ms, the minimun value is
-  1000ms
-          suggestion value is 3000ms;
-      2. if configured with value smaller than 1000ms, the tryLockTimeout value
-  will be setted to 1000ms
-  **/
-  void setTcpTransportTryLockTimeout(uint64_t timeout);  // ms
-  const uint64_t getTcpTransportTryLockTimeout() const;
-
-  void setUnitName(std::string unitName);
-  const std::string& getUnitName();
-
-  void setSessionCredentials(const std::string& input_accessKey,
-                             const std::string& input_secretKey,
-                             const std::string& input_onsChannel);
-  const SessionCredentials& getSessionCredentials() const;
-
- protected:
-  virtual void start();
-  virtual void shutdown();
-  MQClientFactory* getFactory() const;
-  virtual bool isServiceStateOk();
-
- protected:
-  std::string m_namesrvAddr;
-  std::string m_namesrvDomain;
-  std::string m_instanceName;
-  std::string m_nameSpace;
-  std::string m_GroupName;
-  MQClientFactory* m_clientFactory;
-  int m_serviceState;
-  int m_pullThreadNum;
-  uint64_t m_tcpConnectTimeout;           // ms
-  uint64_t m_tcpTransportTryLockTimeout;  // s
-
-  std::string m_unitName;
-  SessionCredentials m_SessionCredentials;
-};
-//<!***************************************************************************
-}  // namespace rocketmq
-#endif
diff --git a/include/MQClientConfig.h b/include/MQClientConfig.h
new file mode 100644
index 0000000..cb4de54
--- /dev/null
+++ b/include/MQClientConfig.h
@@ -0,0 +1,96 @@
+/*
+ * 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 __MQ_CLIENT_CONFIG_H__
+#define __MQ_CLIENT_CONFIG_H__
+
+#include <string>
+
+#include "RocketMQClient.h"
+
+namespace rocketmq {
+
+/**
+ * MQ Client Config
+ */
+class ROCKETMQCLIENT_API MQClientConfig {
+ public:
+  MQClientConfig();
+  virtual ~MQClientConfig() = default;
+
+  // clientId=processId-ipAddr@instanceName
+  std::string buildMQClientId() const;
+
+  // groupName
+  const std::string& getGroupName() const;
+  void setGroupName(const std::string& groupname);
+
+  const std::string& getNamesrvAddr() const;
+  void setNamesrvAddr(const std::string& namesrvAddr);
+
+  const std::string& getInstanceName() const;
+  void setInstanceName(const std::string& instanceName);
+
+  void changeInstanceNameToPID();
+
+  /**
+   * set TcpTransport pull thread num, which dermine the num of threads to distribute network data,
+   *
+   *  1. its default value is CPU num, it must be setted before producer/consumer start, minimum value is CPU num;
+   *  2. this pullThread num must be tested on your environment to find the best value for RT of sendMsg or delay time
+   *     of consume msg before you change it;
+   *  3. producer and consumer need different pullThread num, if set this num, producer and consumer must set different
+   *     instanceName.
+   *  4. configuration suggestion:
+   *      1>. minimum RT of sendMsg:
+   *              pullThreadNum = brokerNum*2
+   **/
+  int getTcpTransportWorkerThreadNum() const;
+  void setTcpTransportWorkerThreadNum(int num);
+
+  /**
+   * timeout of tcp connect, it is same meaning for both producer and consumer;
+   *  1. default value is 3000ms
+   *  2. input parameter could only be milliSecond, suggestion value is 1000-3000ms;
+   **/
+  uint64_t getTcpTransportConnectTimeout() const;
+  void setTcpTransportConnectTimeout(uint64_t timeout);  // ms
+
+  /**
+   * timeout of tryLock tcpTransport before sendMsg/pullMsg, if timeout, returns NULL
+   *  1. paremeter unit is ms, default value is 3000ms, the minimun value is 1000ms, suggestion value is 3000ms;
+   *  2. if configured with value smaller than 1000ms, the tryLockTimeout value will be setted to 1000ms
+   **/
+  uint64_t getTcpTransportTryLockTimeout() const;
+  void setTcpTransportTryLockTimeout(uint64_t timeout);  // ms
+
+  const std::string& getUnitName() const;
+  void setUnitName(std::string unitName);
+
+ protected:
+  std::string m_namesrvAddr;
+  std::string m_instanceName;
+  std::string m_groupName;
+  std::string m_unitName;
+
+  int m_tcpWorkerThreadNum;
+  uint64_t m_tcpConnectTimeout;           // ms
+  uint64_t m_tcpTransportTryLockTimeout;  // s
+};
+
+}  // namespace rocketmq
+
+#endif  // __MQ_CLIENT_CONFIG_H__
diff --git a/include/MQClientException.h b/include/MQClientException.h
index ad642cb..56deb7a 100644
--- a/include/MQClientException.h
+++ b/include/MQClientException.h
@@ -14,47 +14,42 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef __MQCLIENTEXCEPTION_H__
-#define __MQCLIENTEXCEPTION_H__
+#ifndef __MQ_CLIENT_EXCEPTION_H__
+#define __MQ_CLIENT_EXCEPTION_H__
 
-#include <string.h>
 #include <exception>
 #include <ostream>
 #include <sstream>
 #include <string>
-#include "CCommon.h"
+
 #include "RocketMQClient.h"
 
 namespace rocketmq {
-//<!***************************************************************************
+
 class ROCKETMQCLIENT_API MQException : public std::exception {
  public:
-  MQException(const std::string& msg, int error, const char* file, int line) throw()
-      : m_error(error), m_line(line), m_file(file) {
-    try {
-      std::stringstream ss;
-      ss << "msg: " << msg << ",error:" << error << ",in file <" << file << "> line:" << line;
-      m_msg = ss.str();
-    } catch (...) {
-    }
-  }
+  MQException(const std::string& msg, int error, const char* file, int line) noexcept
+      : m_error(error), m_line(line), m_msg(msg), m_file(file), m_type("MQException") {}
 
-  MQException(const std::string& msg, int error, const char* file, const char* type, int line) throw()
-      : m_error(error), m_line(line), m_file(file), m_type(type) {
-    try {
+  MQException(const std::string& msg, int error, const char* file, const char* type, int line) noexcept
+      : m_error(error), m_line(line), m_msg(msg), m_file(file), m_type(type) {}
+
+  virtual ~MQException() noexcept = default;
+
+  const char* what() const noexcept override {
+    if (m_what_.empty()) {
       std::stringstream ss;
-      ss << "msg: " << msg << ",error:" << error << ",in file <" << file << "> line:" << line;
-      m_msg = ss.str();
-    } catch (...) {
+      ss << "[" << m_type << "] msg: " << m_msg << ", error: " << m_error << ", in <" << m_file << ":" << m_line << ">";
+      m_what_ = ss.str();
     }
+    return m_what_.c_str();
   }
 
-  virtual ~MQException() throw() {}
-  const char* what() const throw() { return m_msg.c_str(); }
-  int GetError() const throw() { return m_error; }
-  virtual const char* GetType() const throw() { return m_type.c_str(); }
+  int GetError() const noexcept { return m_error; }
   int GetLine() { return m_line; }
+  const char* GetMsg() { return m_msg.c_str(); }
   const char* GetFile() { return m_file.c_str(); }
+  const char* GetType() const noexcept { return m_type.c_str(); }
 
  protected:
   int m_error;
@@ -62,30 +57,42 @@ class ROCKETMQCLIENT_API MQException : public std::exception {
   std::string m_msg;
   std::string m_file;
   std::string m_type;
+
+  mutable std::string m_what_;
 };
 
 inline std::ostream& operator<<(std::ostream& os, const MQException& e) {
-  os << "Type: " << e.GetType() << " , " << e.what();
+  os << e.what();
   return os;
 }
 
-#define DEFINE_MQCLIENTEXCEPTION(name)                                          \
-  class ROCKETMQCLIENT_API name : public MQException {                          \
-   public:                                                                      \
-    name(const std::string& msg, int error, const char* file, int line) throw() \
-        : MQException(msg, error, file, #name, line) {}                         \
-    virtual const char* GetType() const throw() { return m_type.c_str(); }      \
+#define DEFINE_MQCLIENTEXCEPTION2(name, super)                                                     \
+  class ROCKETMQCLIENT_API name : public super {                                                   \
+   public:                                                                                         \
+    name(const std::string& msg, int error, const char* file, int line) noexcept                   \
+        : super(msg, error, file, #name, line) {}                                                  \
+                                                                                                   \
+   protected:                                                                                      \
+    name(const std::string& msg, int error, const char* file, const char* type, int line) noexcept \
+        : super(msg, error, file, type, line) {}                                                   \
   };
 
+#define DEFINE_MQCLIENTEXCEPTION(name) DEFINE_MQCLIENTEXCEPTION2(name, MQException)
+
 DEFINE_MQCLIENTEXCEPTION(MQClientException)
 DEFINE_MQCLIENTEXCEPTION(MQBrokerException)
 DEFINE_MQCLIENTEXCEPTION(InterruptedException)
 DEFINE_MQCLIENTEXCEPTION(RemotingException)
+DEFINE_MQCLIENTEXCEPTION2(RemotingCommandException, RemotingException)
+DEFINE_MQCLIENTEXCEPTION2(RemotingConnectException, RemotingException)
+DEFINE_MQCLIENTEXCEPTION2(RemotingSendRequestException, RemotingException)
+DEFINE_MQCLIENTEXCEPTION2(RemotingTimeoutException, RemotingException)
+DEFINE_MQCLIENTEXCEPTION2(RemotingTooMuchRequestException, RemotingException)
 DEFINE_MQCLIENTEXCEPTION(UnknownHostException)
 
 #define THROW_MQEXCEPTION(e, msg, err) throw e(msg, err, __FILE__, __LINE__)
 #define NEW_MQEXCEPTION(e, msg, err) e(msg, err, __FILE__, __LINE__)
 
-//<!***************************************************************************
 }  // namespace rocketmq
-#endif
+
+#endif  // __MQ_CLIENT_EXCEPTION_H__
diff --git a/include/MQConsumer.h b/include/MQConsumer.h
old mode 100644
new mode 100755
index 87e2c1b..ebbda3f
--- a/include/MQConsumer.h
+++ b/include/MQConsumer.h
@@ -1,68 +1,45 @@
-/*
- * 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 __MQCONSUMER_H__
-#define __MQCONSUMER_H__
-
-#include <string>
-#include "AsyncCallback.h"
-#include "ConsumeType.h"
-#include "MQClient.h"
-#include "RocketMQClient.h"
-
-namespace rocketmq {
-class SubscriptionData;
-class PullRequest;
-class Rebalance;
-class ConsumerRunningInfo;
-//<!************************************************************************
-class ROCKETMQCLIENT_API MQConsumer : public MQClient {
- public:
-  virtual ~MQConsumer() {}
-  virtual bool sendMessageBack(MQMessageExt& msg, int delayLevel, std::string& brokerName) = 0;
-  virtual void fetchSubscribeMessageQueues(const std::string& topic, std::vector<MQMessageQueue>& mqs) = 0;
-  virtual void doRebalance() = 0;
-  virtual void persistConsumerOffset() = 0;
-  virtual void persistConsumerOffsetByResetOffset() = 0;
-  virtual void updateTopicSubscribeInfo(const std::string& topic, std::vector<MQMessageQueue>& info) = 0;
-  virtual void updateConsumeOffset(const MQMessageQueue& mq, int64 offset) = 0;
-  virtual void removeConsumeOffset(const MQMessageQueue& mq) = 0;
-  virtual ConsumeType getConsumeType() = 0;
-  virtual ConsumeFromWhere getConsumeFromWhere() = 0;
-  virtual void getSubscriptions(std::vector<SubscriptionData>&) = 0;
-  virtual bool producePullMsgTask(boost::weak_ptr<PullRequest>) = 0;
-  virtual Rebalance* getRebalance() const = 0;
-  virtual PullResult pull(const MQMessageQueue& mq, const std::string& subExpression, int64 offset, int maxNums) = 0;
-  virtual void pull(const MQMessageQueue& mq,
-                    const std::string& subExpression,
-                    int64 offset,
-                    int maxNums,
-                    PullCallback* pPullCallback) = 0;
-  virtual ConsumerRunningInfo* getConsumerRunningInfo() = 0;
-
- public:
-  MessageModel getMessageModel() const { return m_messageModel; }
-  void setMessageModel(MessageModel messageModel) { m_messageModel = messageModel; }
-  bool isUseNameSpaceMode() const { return m_useNameSpaceMode; }
-
- protected:
-  MessageModel m_messageModel;
-  bool m_useNameSpaceMode = false;
-};
-
-//<!***************************************************************************
-}  // namespace rocketmq
-#endif
+/*
+ * 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 __MQ_CONSUMER_H__
+#define __MQ_CONSUMER_H__
+
+#include <string>
+#include <vector>
+
+#include "MQMessageExt.h"
+
+namespace rocketmq {
+
+/**
+ * MQ Consumer API
+ */
+class ROCKETMQCLIENT_API MQConsumer {
+ public:
+  virtual ~MQConsumer() = default;
+
+ public:  // MQConsumer in Java
+  virtual void start() = 0;
+  virtual void shutdown() = 0;
+
+  virtual bool sendMessageBack(MQMessageExt& msg, int delayLevel) = 0;
+  virtual bool sendMessageBack(MQMessageExt& msg, int delayLevel, const std::string& brokerName) = 0;
+  virtual void fetchSubscribeMessageQueues(const std::string& topic, std::vector<MQMessageQueue>& mqs) = 0;
+};
+
+}  // namespace rocketmq
+
+#endif  // __MQ_CONSUMER_H__
diff --git a/include/MQMessage.h b/include/MQMessage.h
index 70fab36..a2a819e 100644
--- a/include/MQMessage.h
+++ b/include/MQMessage.h
@@ -14,17 +14,23 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef __MESSAGE_H__
-#define __MESSAGE_H__
+#ifndef __MQ_MESSAGE_H__
+#define __MQ_MESSAGE_H__
 
 #include <map>
+#include <memory>
 #include <sstream>
 #include <string>
 #include <vector>
-#include "RocketMQClient.h"
+
+#include "MQMessageConst.h"
 
 namespace rocketmq {
-//<!***************************************************************************
+
+class MQMessage;
+typedef MQMessage* MQMessagePtr;
+typedef std::shared_ptr<MQMessage> MQMessagePtr2;
+
 class ROCKETMQCLIENT_API MQMessage {
  public:
   MQMessage();
@@ -38,12 +44,14 @@ class ROCKETMQCLIENT_API MQMessage {
             const std::string& body,
             bool waitStoreMsgOK);
 
-  virtual ~MQMessage();
   MQMessage(const MQMessage& other);
   MQMessage& operator=(const MQMessage& other);
 
-  void setProperty(const std::string& name, const std::string& value);
+  virtual ~MQMessage();
+
   const std::string& getProperty(const std::string& name) const;
+  void putProperty(const std::string& name, const std::string& value);
+  void clearProperty(const std::string& name);
 
   const std::string& getTopic() const;
   void setTopic(const std::string& topic);
@@ -65,79 +73,35 @@ class ROCKETMQCLIENT_API MQMessage {
   int getFlag() const;
   void setFlag(int flag);
 
-  int getSysFlag() const;
-  void setSysFlag(int sysFlag);
-
   const std::string& getBody() const;
-
   void setBody(const char* body, int len);
   void setBody(const std::string& body);
+  void setBody(std::string&& body);
+
+  const std::string& getTransactionId() const;
+  void setTransactionId(const std::string& transactionId);
 
-  void setTransactionId(const std::string& id) { m_transactionId = id; }
-  std::string getTransactionId() const { return m_transactionId; }
+  const std::map<std::string, std::string>& getProperties() const;
+  void setProperties(const std::map<std::string, std::string>& properties);
+  void setProperties(std::map<std::string, std::string>&& properties);
 
-  std::map<std::string, std::string> getProperties() const;
-  void setProperties(std::map<std::string, std::string>& properties);
+  virtual bool isBatch() { return false; }
 
-  const std::string toString() const {
+  virtual std::string toString() const {
     std::stringstream ss;
-    std::string tags = getTags();
-    ss << "Message [topic=" << m_topic << ", flag=" << m_flag << ", tag=" << tags << "]";
+    ss << "Message [topic=" << m_topic << ", flag=" << m_flag << ", tag=" << getTags() << ", transactionId='"
+       << m_transactionId + "']";
     return ss.str();
   }
 
  protected:
-  friend class MQDecoder;
-  void setPropertyInternal(const std::string& name, const std::string& value);
-  void setPropertiesInternal(std::map<std::string, std::string>& properties);
-
-  void Init(const std::string& topic,
-            const std::string& tags,
-            const std::string& keys,
-            const int flag,
-            const std::string& body,
-            bool waitStoreMsgOK);
-
- public:
-  static const std::string PROPERTY_KEYS;
-  static const std::string PROPERTY_TAGS;
-  static const std::string PROPERTY_WAIT_STORE_MSG_OK;
-  static const std::string PROPERTY_DELAY_TIME_LEVEL;
-  static const std::string PROPERTY_RETRY_TOPIC;
-  static const std::string PROPERTY_REAL_TOPIC;
-  static const std::string PROPERTY_REAL_QUEUE_ID;
-  static const std::string PROPERTY_TRANSACTION_PREPARED;
-  static const std::string PROPERTY_PRODUCER_GROUP;
-  static const std::string PROPERTY_MIN_OFFSET;
-  static const std::string PROPERTY_MAX_OFFSET;
-
-  static const std::string PROPERTY_BUYER_ID;
-  static const std::string PROPERTY_ORIGIN_MESSAGE_ID;
-  static const std::string PROPERTY_TRANSFER_FLAG;
-  static const std::string PROPERTY_CORRECTION_FLAG;
-  static const std::string PROPERTY_MQ2_FLAG;
-  static const std::string PROPERTY_RECONSUME_TIME;
-  static const std::string PROPERTY_MSG_REGION;
-  static const std::string PROPERTY_TRACE_SWITCH;
-  static const std::string PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX;
-  static const std::string PROPERTY_MAX_RECONSUME_TIMES;
-  static const std::string PROPERTY_CONSUME_START_TIMESTAMP;
-  static const std::string PROPERTY_TRANSACTION_PREPARED_QUEUE_OFFSET;
-  static const std::string PROPERTY_TRANSACTION_CHECK_TIMES;
-  static const std::string PROPERTY_CHECK_IMMUNITY_TIME_IN_SECONDS;
-
-  static const std::string KEY_SEPARATOR;
-
- protected:
-  int m_sysFlag;
-
- private:
   std::string m_topic;
   int m_flag;
+  std::map<std::string, std::string> m_properties;
   std::string m_body;
   std::string m_transactionId;
-  std::map<std::string, std::string> m_properties;
 };
-//<!***************************************************************************
+
 }  // namespace rocketmq
-#endif
+
+#endif  // __MQ_MESSAGE_H__
diff --git a/include/MQMessageConst.h b/include/MQMessageConst.h
new file mode 100644
index 0000000..61c5c00
--- /dev/null
+++ b/include/MQMessageConst.h
@@ -0,0 +1,64 @@
+/*
+ * 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 __MQ_MESSAGE_CONST_H__
+#define __MQ_MESSAGE_CONST_H__
+
+#include <string>
+
+#include "RocketMQClient.h"
+
+namespace rocketmq {
+
+class ROCKETMQCLIENT_API MQMessageConst {
+ public:
+  static const std::string PROPERTY_KEYS;
+  static const std::string PROPERTY_TAGS;
+  static const std::string PROPERTY_WAIT_STORE_MSG_OK;
+  static const std::string PROPERTY_DELAY_TIME_LEVEL;
+  static const std::string PROPERTY_RETRY_TOPIC;
+  static const std::string PROPERTY_REAL_TOPIC;
+  static const std::string PROPERTY_REAL_QUEUE_ID;
+  static const std::string PROPERTY_TRANSACTION_PREPARED;
+  static const std::string PROPERTY_PRODUCER_GROUP;
+  static const std::string PROPERTY_MIN_OFFSET;
+  static const std::string PROPERTY_MAX_OFFSET;
+
+  static const std::string PROPERTY_BUYER_ID;
+  static const std::string PROPERTY_ORIGIN_MESSAGE_ID;
+  static const std::string PROPERTY_TRANSFER_FLAG;
+  static const std::string PROPERTY_CORRECTION_FLAG;
+  static const std::string PROPERTY_MQ2_FLAG;
+  static const std::string PROPERTY_RECONSUME_TIME;
+  static const std::string PROPERTY_MSG_REGION;
+  static const std::string PROPERTY_TRACE_SWITCH;
+  static const std::string PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX;
+  static const std::string PROPERTY_MAX_RECONSUME_TIMES;
+  static const std::string PROPERTY_CONSUME_START_TIMESTAMP;
+  static const std::string PROPERTY_TRANSACTION_PREPARED_QUEUE_OFFSET;
+  static const std::string PROPERTY_TRANSACTION_CHECK_TIMES;
+  static const std::string PROPERTY_CHECK_IMMUNITY_TIME_IN_SECONDS;
+  static const std::string PROPERTY_INSTANCE_ID;
+
+  // sdk internal use only
+  static const std::string PROPERTY_ALREADY_COMPRESSED_FLAG;
+
+  static const std::string KEY_SEPARATOR;
+};
+
+}  // namespace rocketmq
+
+#endif  // __MQ_MESSAGE_CONST_H__
diff --git a/include/MQMessageExt.h b/include/MQMessageExt.h
index 8970282..f142045 100644
--- a/include/MQMessageExt.h
+++ b/include/MQMessageExt.h
@@ -14,104 +14,119 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef __MESSAGEEXT_H__
-#define __MESSAGEEXT_H__
+#ifndef __MQ_MESSAGE_EXT_H__
+#define __MQ_MESSAGE_EXT_H__
 
 #ifdef WIN32
-#include <Windows.h>
+// clang-format off
 #include <Winsock2.h>
+#include <Windows.h>
+// clang-format on
 #else
 #include <sys/socket.h>
 #endif
 
 #include "MQMessage.h"
-#include "RocketMQClient.h"
+#include "TopicFilterType.h"
 
 namespace rocketmq {
-//<!message extend class, which was generated on broker;
-//<!***************************************************************************
+
+class MQMessageExt;
+
+typedef MQMessageExt* MQMessageExtPtr;
+typedef std::shared_ptr<MQMessageExt> MQMessageExtPtr2;
+
+// message extend class, which was generated on broker
 class ROCKETMQCLIENT_API MQMessageExt : public MQMessage {
  public:
   MQMessageExt();
   MQMessageExt(int queueId,
-               int64 bornTimestamp,
+               int64_t bornTimestamp,
                sockaddr bornHost,
-               int64 storeTimestamp,
+               int64_t storeTimestamp,
                sockaddr storeHost,
                std::string msgId);
 
   virtual ~MQMessageExt();
 
-  static int parseTopicFilterType(int sysFlag);
+  static TopicFilterType parseTopicFilterType(int32_t sysFlag);
 
-  int getQueueId() const;
-  void setQueueId(int queueId);
+  int32_t getStoreSize() const;
+  void setStoreSize(int32_t storeSize);
 
-  int64 getBornTimestamp() const;
-  void setBornTimestamp(int64 bornTimestamp);
+  int32_t getBodyCRC() const;
+  void setBodyCRC(int32_t bodyCRC);
 
-  sockaddr getBornHost() const;
-  std::string getBornHostString() const;
-  std::string getBornHostNameString() const;
-  void setBornHost(const sockaddr& bornHost);
+  int32_t getQueueId() const;
+  void setQueueId(int32_t queueId);
 
-  int64 getStoreTimestamp() const;
-  void setStoreTimestamp(int64 storeTimestamp);
+  int64_t getQueueOffset() const;
+  void setQueueOffset(int64_t queueOffset);
 
-  sockaddr getStoreHost() const;
-  std::string getStoreHostString() const;
-  void setStoreHost(const sockaddr& storeHost);
+  int64_t getCommitLogOffset() const;
+  void setCommitLogOffset(int64_t physicOffset);
 
-  const std::string& getMsgId() const;
-  void setMsgId(const std::string& msgId);
+  int32_t getSysFlag() const;
+  void setSysFlag(int32_t sysFlag);
 
-  const std::string& getOffsetMsgId() const;
-  void setOffsetMsgId(const std::string& offsetMsgId);
+  int64_t getBornTimestamp() const;
+  void setBornTimestamp(int64_t bornTimestamp);
 
-  int getBodyCRC() const;
-  void setBodyCRC(int bodyCRC);
+  const sockaddr& getBornHost() const;
+  std::string getBornHostString() const;
+  void setBornHost(const sockaddr& bornHost);
 
-  int64 getQueueOffset() const;
-  void setQueueOffset(int64 queueOffset);
+  int64_t getStoreTimestamp() const;
+  void setStoreTimestamp(int64_t storeTimestamp);
 
-  int64 getCommitLogOffset() const;
-  void setCommitLogOffset(int64 physicOffset);
+  const sockaddr& getStoreHost() const;
+  std::string getStoreHostString() const;
+  void setStoreHost(const sockaddr& storeHost);
 
-  int getStoreSize() const;
-  void setStoreSize(int storeSize);
+  int32_t getReconsumeTimes() const;
+  void setReconsumeTimes(int32_t reconsumeTimes);
 
-  int getReconsumeTimes() const;
-  void setReconsumeTimes(int reconsumeTimes);
+  int64_t getPreparedTransactionOffset() const;
+  void setPreparedTransactionOffset(int64_t preparedTransactionOffset);
 
-  int64 getPreparedTransactionOffset() const;
-  void setPreparedTransactionOffset(int64 preparedTransactionOffset);
+  virtual const std::string& getMsgId() const;
+  virtual void setMsgId(const std::string& msgId);
 
-  std::string toString() const {
+  std::string toString() const override {
     std::stringstream ss;
     ss << "MessageExt [queueId=" << m_queueId << ", storeSize=" << m_storeSize << ", queueOffset=" << m_queueOffset
        << ", sysFlag=" << m_sysFlag << ", bornTimestamp=" << m_bornTimestamp << ", bornHost=" << getBornHostString()
-       << ", storeTimestamp=" << m_storeTimestamp << ", storeHost=" << getStoreHostString() << ", msgId=" << m_msgId
+       << ", storeTimestamp=" << m_storeTimestamp << ", storeHost=" << getStoreHostString() << ", msgId=" << getMsgId()
        << ", commitLogOffset=" << m_commitLogOffset << ", bodyCRC=" << m_bodyCRC
        << ", reconsumeTimes=" << m_reconsumeTimes << ", preparedTransactionOffset=" << m_preparedTransactionOffset
-       << ",  " << MQMessage::toString() << "]";
+       << ", toString()=" << MQMessage::toString() << "]";
     return ss.str();
   }
 
  private:
-  int64 m_queueOffset;
-  int64 m_commitLogOffset;
-  int64 m_bornTimestamp;
-  int64 m_storeTimestamp;
-  int64 m_preparedTransactionOffset;
-  int m_queueId;
-  int m_storeSize;
-  int m_bodyCRC;
-  int m_reconsumeTimes;
+  int32_t m_storeSize;
+  int32_t m_bodyCRC;
+  int32_t m_queueId;
+  int64_t m_queueOffset;
+  int64_t m_commitLogOffset;
+  int32_t m_sysFlag;
+  int64_t m_bornTimestamp;
   sockaddr m_bornHost;
+  int64_t m_storeTimestamp;
   sockaddr m_storeHost;
+  int32_t m_reconsumeTimes;
+  int64_t m_preparedTransactionOffset;
   std::string m_msgId;
-  std::string m_offsetMsgId;
 };
-//<!***************************************************************************
+
+class ROCKETMQCLIENT_API MQMessageClientExt : public MQMessageExt {
+  const std::string& getOffsetMsgId() const;
+  void setOffsetMsgId(const std::string& offsetMsgId);
+
+  const std::string& getMsgId() const override;
+  void setMsgId(const std::string& msgId) override;
+};
+
 }  // namespace rocketmq
-#endif
+
+#endif  // __MQ_MESSAGE_EXT_H__
diff --git a/include/MQMessageListener.h b/include/MQMessageListener.h
index dee7c7e..d7b700a 100644
--- a/include/MQMessageListener.h
+++ b/include/MQMessageListener.h
@@ -1,79 +1,85 @@
-/*
- * 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 __MESSAGELISTENER_H__
-#define __MESSAGELISTENER_H__
-
-#include <limits.h>
-#include "MQMessageExt.h"
-#include "MQMessageQueue.h"
-
-namespace rocketmq {
-//<!***************************************************************************
-enum ConsumeStatus {
-  // consume success, msg will be cleard from memory
-  CONSUME_SUCCESS,
-  // consume fail, but will be re-consume by call messageLisenter again
-  RECONSUME_LATER
-};
-
-/*enum ConsumeOrderlyStatus
-{*/
-/**
- * Success consumption
- */
-// SUCCESS,
-/**
- * Rollback consumption(only for binlog consumption)
- */
-// ROLLBACK,
-/**
- * Commit offset(only for binlog consumption)
- */
-// COMMIT,
-/**
- * Suspend current queue a moment
- */
-// SUSPEND_CURRENT_QUEUE_A_MOMENT
-/*};*/
-
-enum MessageListenerType { messageListenerDefaultly = 0, messageListenerOrderly = 1, messageListenerConcurrently = 2 };
-
-//<!***************************************************************************
-class ROCKETMQCLIENT_API MQMessageListener {
- public:
-  virtual ~MQMessageListener() {}
-  virtual ConsumeStatus consumeMessage(const std::vector<MQMessageExt>& msgs) = 0;
-  virtual MessageListenerType getMessageListenerType() { return messageListenerDefaultly; }
-};
-
-class ROCKETMQCLIENT_API MessageListenerOrderly : public MQMessageListener {
- public:
-  virtual ~MessageListenerOrderly() {}
-  virtual ConsumeStatus consumeMessage(const std::vector<MQMessageExt>& msgs) = 0;
-  virtual MessageListenerType getMessageListenerType() { return messageListenerOrderly; }
-};
-
-class ROCKETMQCLIENT_API MessageListenerConcurrently : public MQMessageListener {
- public:
-  virtual ~MessageListenerConcurrently() {}
-  virtual ConsumeStatus consumeMessage(const std::vector<MQMessageExt>& msgs) = 0;
-  virtual MessageListenerType getMessageListenerType() { return messageListenerConcurrently; }
-};
-
-//<!***************************************************************************
-}  // namespace rocketmq
-#endif
+/*
+ * 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 __MESSAGE_LISTENER_H__
+#define __MESSAGE_LISTENER_H__
+
+#include <limits.h>
+
+#include "MQMessageExt.h"
+
+namespace rocketmq {
+
+enum ConsumeStatus {
+  // consume success, msg will be cleard from memory
+  CONSUME_SUCCESS,
+  // consume fail, but will be re-consume by call messageLisenter again
+  RECONSUME_LATER
+};
+
+/*enum ConsumeOrderlyStatus
+{*/
+/**
+ * Success consumption
+ */
+// SUCCESS,
+/**
+ * Rollback consumption(only for binlog consumption)
+ */
+// ROLLBACK,
+/**
+ * Commit offset(only for binlog consumption)
+ */
+// COMMIT,
+/**
+ * Suspend current queue a moment
+ */
+// SUSPEND_CURRENT_QUEUE_A_MOMENT
+/*};*/
+
+enum MessageListenerType { messageListenerDefaultly = 0, messageListenerOrderly = 1, messageListenerConcurrently = 2 };
+
+class ROCKETMQCLIENT_API MQMessageListener {
+ public:
+  virtual ~MQMessageListener() = default;
+  virtual MessageListenerType getMessageListenerType() { return messageListenerDefaultly; }
+
+  virtual ConsumeStatus consumeMessage(const std::vector<MQMessageExtPtr2>& msgs) {
+    std::vector<MQMessageExtPtr> msgs2;
+    msgs2.reserve(msgs.size());
+    for (auto& msg : msgs) {
+      msgs2.push_back(msg.get());
+    }
+    return consumeMessage(msgs2);
+  }
+
+  // SDK will be responsible for the lifecycle of messages.
+  virtual ConsumeStatus consumeMessage(const std::vector<MQMessageExtPtr>& msgs) = 0;
+};
+
+class ROCKETMQCLIENT_API MessageListenerConcurrently : virtual public MQMessageListener {
+ public:
+  MessageListenerType getMessageListenerType() override final { return messageListenerConcurrently; }
+};
+
+class ROCKETMQCLIENT_API MessageListenerOrderly : virtual public MQMessageListener {
+ public:
+  MessageListenerType getMessageListenerType() override final { return messageListenerOrderly; }
+};
+
+}  // namespace rocketmq
+
+#endif  // __MESSAGE_LISTENER_H__
diff --git a/include/MQMessageQueue.h b/include/MQMessageQueue.h
index aa80035..a37cdf5 100644
--- a/include/MQMessageQueue.h
+++ b/include/MQMessageQueue.h
@@ -1,63 +1,64 @@
-/*
- * 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 __MQMESSAGEQUEUE_H__
-#define __MQMESSAGEQUEUE_H__
-
-#include <iomanip>
-#include <sstream>
-#include <string>
-#include "RocketMQClient.h"
-
-namespace rocketmq {
-//<!************************************************************************/
-//<!* MQ(T,B,ID);
-//<!************************************************************************/
-class ROCKETMQCLIENT_API MQMessageQueue {
- public:
-  MQMessageQueue();
-  MQMessageQueue(const std::string& topic, const std::string& brokerName, int queueId);
-  MQMessageQueue(const MQMessageQueue& other);
-  MQMessageQueue& operator=(const MQMessageQueue& other);
-
-  std::string getTopic() const;
-  void setTopic(const std::string& topic);
-
-  std::string getBrokerName() const;
-  void setBrokerName(const std::string& brokerName);
-
-  int getQueueId() const;
-  void setQueueId(int queueId);
-
-  bool operator==(const MQMessageQueue& mq) const;
-  bool operator<(const MQMessageQueue& mq) const;
-  int compareTo(const MQMessageQueue& mq) const;
-
-  const std::string toString() const {
-    std::stringstream ss;
-    ss << "MessageQueue [topic=" << m_topic << ", brokerName=" << m_brokerName << ", queueId=" << m_queueId << "]";
-
-    return ss.str();
-  }
-
- private:
-  std::string m_topic;
-  std::string m_brokerName;
-  int m_queueId;
-};
-//<!***************************************************************************
-}  // namespace rocketmq
-#endif
+/*
+ * 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 __MQ_MESSAGE_QUEUE_H__
+#define __MQ_MESSAGE_QUEUE_H__
+
+#include <sstream>
+#include <string>
+
+#include "RocketMQClient.h"
+
+namespace rocketmq {
+
+/**
+ * MQ(T,B,ID)
+ */
+class ROCKETMQCLIENT_API MQMessageQueue {
+ public:
+  MQMessageQueue();
+  MQMessageQueue(const std::string& topic, const std::string& brokerName, int queueId);
+  MQMessageQueue(const MQMessageQueue& other);
+  MQMessageQueue& operator=(const MQMessageQueue& other);
+
+  const std::string& getTopic() const;
+  void setTopic(const std::string& topic);
+
+  const std::string& getBrokerName() const;
+  void setBrokerName(const std::string& brokerName);
+
+  int getQueueId() const;
+  void setQueueId(int queueId);
+
+  bool operator==(const MQMessageQueue& mq) const;
+  bool operator<(const MQMessageQueue& mq) const;
+  int compareTo(const MQMessageQueue& mq) const;
+
+  std::string toString() const {
+    std::stringstream ss;
+    ss << "MessageQueue [topic=" << m_topic << ", brokerName=" << m_brokerName << ", queueId=" << m_queueId << "]";
+    return ss.str();
+  }
+
+ private:
+  std::string m_topic;
+  std::string m_brokerName;
+  int m_queueId;
+};
+
+}  // namespace rocketmq
+
+#endif  // __MQ_MESSAGE_QUEUE_H__
diff --git a/include/MQProducer.h b/include/MQProducer.h
index 03e6b19..36878d9 100644
--- a/include/MQProducer.h
+++ b/include/MQProducer.h
@@ -1,61 +1,81 @@
-/*
- * 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 __MQPRODUCER_H__
-#define __MQPRODUCER_H__
-
-#include "AsyncCallback.h"
-#include "MQClient.h"
-#include "MQMessageQueue.h"
-#include "MQSelector.h"
-#include "RocketMQClient.h"
-#include "SendResult.h"
-
-namespace rocketmq {
-//<!***************************************************************************
-class ROCKETMQCLIENT_API MQProducer : public MQClient {
- public:
-  MQProducer() {}
-  virtual ~MQProducer() {}
-  // if setted bActiveBroker, will search brokers with best service state
-  // firstly, then search brokers that had been sent failed by last time;
-  virtual SendResult send(MQMessage& msg, bool bSelectActiveBroker = false) = 0;
-  virtual SendResult send(MQMessage& msg, const MQMessageQueue& mq) = 0;
-  // strict order msg, if send failed on seleted MessageQueue, throw exception
-  // to up layer
-  virtual SendResult send(MQMessage& msg, MessageQueueSelector* selector, void* arg) = 0;
-  // non-strict order msg, if send failed on seleted MessageQueue, will auto
-  // retry others Broker queues with autoRetryTimes;
-  // if setted bActiveBroker, if send failed on seleted MessageQueue, , and then
-  // search brokers with best service state, lastly will search brokers that had
-  // been sent failed by last time;
-  virtual SendResult send(MQMessage& msg,
-                          MessageQueueSelector* selector,
-                          void* arg,
-                          int autoRetryTimes,
-                          bool bActiveBroker = false) = 0;
-  virtual void send(MQMessage& msg, SendCallback* sendCallback, bool bSelectActiveBroker = false) = 0;
-  virtual void send(MQMessage& msg, const MQMessageQueue& mq, SendCallback* sendCallback) = 0;
-  virtual void send(MQMessage& msg, MessageQueueSelector* selector, void* arg, SendCallback* sendCallback) = 0;
-  virtual SendResult send(std::vector<MQMessage>& msgs) = 0;
-  virtual SendResult send(std::vector<MQMessage>& msgs, const MQMessageQueue& mq) = 0;
-  virtual void sendOneway(MQMessage& msg, bool bSelectActiveBroker = false) = 0;
-  virtual void sendOneway(MQMessage& msg, const MQMessageQueue& mq) = 0;
-  virtual void sendOneway(MQMessage& msg, MessageQueueSelector* selector, void* arg) = 0;
-};
-//<!***************************************************************************
-}  // namespace rocketmq
-#endif
+/*
+ * 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 __MQ_PRODUCER_H__
+#define __MQ_PRODUCER_H__
+
+#include "MQSelector.h"
+#include "SendCallback.h"
+#include "SendResult.h"
+#include "TransactionSendResult.h"
+
+namespace rocketmq {
+
+/**
+ * MQ Producer API
+ */
+class ROCKETMQCLIENT_API MQProducer {
+ public:
+  virtual ~MQProducer() = default;
+
+ public:  // MQProducer
+  virtual void start() = 0;
+  virtual void shutdown() = 0;
+
+  // Sync
+  virtual SendResult send(MQMessagePtr msg) = 0;
+  virtual SendResult send(MQMessagePtr msg, long timeout) = 0;
+  virtual SendResult send(MQMessagePtr msg, const MQMessageQueue& mq) = 0;
+  virtual SendResult send(MQMessagePtr msg, const MQMessageQueue& mq, long timeout) = 0;
+
+  // Async
+  // TODO: replace MQMessagePtr by MQMessagePtr2(shared_ptr)
+  virtual void send(MQMessagePtr msg, SendCallback* sendCallback) noexcept = 0;
+  virtual void send(MQMessagePtr msg, SendCallback* sendCallback, long timeout) noexcept = 0;
+  virtual void send(MQMessagePtr msg, const MQMessageQueue& mq, SendCallback* sendCallback) noexcept = 0;
+  virtual void send(MQMessagePtr msg, const MQMessageQueue& mq, SendCallback* sendCallback, long timeout) noexcept = 0;
+
+  // Oneyway
+  virtual void sendOneway(MQMessagePtr msg) = 0;
+  virtual void sendOneway(MQMessagePtr msg, const MQMessageQueue& mq) = 0;
+
+  // Select
+  virtual SendResult send(MQMessagePtr msg, MessageQueueSelector* selector, void* arg) = 0;
+  virtual SendResult send(MQMessagePtr msg, MessageQueueSelector* selector, void* arg, long timeout) = 0;
+  virtual void send(MQMessagePtr msg,
+                    MessageQueueSelector* selector,
+                    void* arg,
+                    SendCallback* sendCallback) noexcept = 0;
+  virtual void send(MQMessagePtr msg,
+                    MessageQueueSelector* selector,
+                    void* arg,
+                    SendCallback* sendCallback,
+                    long timeout) noexcept = 0;
+  virtual void sendOneway(MQMessagePtr msg, MessageQueueSelector* selector, void* arg) = 0;
+
+  // Transaction
+  virtual TransactionSendResult sendMessageInTransaction(MQMessagePtr msg, void* arg) = 0;
+
+  // Batch
+  virtual SendResult send(std::vector<MQMessagePtr>& msgs) = 0;
+  virtual SendResult send(std::vector<MQMessagePtr>& msgs, long timeout) = 0;
+  virtual SendResult send(std::vector<MQMessagePtr>& msgs, const MQMessageQueue& mq) = 0;
+  virtual SendResult send(std::vector<MQMessagePtr>& msgs, const MQMessageQueue& mq, long timeout) = 0;
+};
+
+}  // namespace rocketmq
+
+#endif  // __MQ_PRODUCER_H__
diff --git a/include/MQPullConsumer.h b/include/MQPullConsumer.h
new file mode 100644
index 0000000..5571431
--- /dev/null
+++ b/include/MQPullConsumer.h
@@ -0,0 +1,103 @@
+/*
+ * 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 __MQ_PULL_CONSUMER_H__
+#define __MQ_PULL_CONSUMER_H__
+
+#include "MQConsumer.h"
+#include "MQueueListener.h"
+#include "PullCallback.h"
+
+namespace rocketmq {
+
+class ROCKETMQCLIENT_API MQPullConsumer : public MQConsumer {
+ public:
+  virtual void registerMessageQueueListener(const std::string& topic, MQueueListener* pListener) = 0;
+
+  /**
+   * pull msg from specified queue, if no msg in queue, return directly
+   *
+   * @param mq
+   *            specify the pulled queue
+   * @param subExpression
+   *            set filter expression for pulled msg, broker will filter msg actively
+   *            Now only OR operation is supported, eg: "tag1 || tag2 || tag3"
+   *            if subExpression is setted to "null" or "*" all msg will be subscribed
+   * @param offset
+   *            specify the started pull offset
+   * @param maxNums
+   *            specify max msg num by per pull
+   * @return
+   *            accroding to PullResult
+   */
+  virtual PullResult pull(const MQMessageQueue& mq, const std::string& subExpression, int64_t offset, int maxNums) = 0;
+
+  virtual void pull(const MQMessageQueue& mq,
+                    const std::string& subExpression,
+                    int64_t offset,
+                    int maxNums,
+                    PullCallback* pullCallback) = 0;
+
+  /**
+   * pull msg from specified queue, if no msg, broker will suspend the pull request 20s
+   *
+   * @param mq
+   *            specify the pulled queue
+   * @param subExpression
+   *            set filter expression for pulled msg, broker will filter msg actively
+   *            Now only OR operation is supported, eg: "tag1 || tag2 || tag3"
+   *            if subExpression is setted to "null" or "*" all msg will be subscribed
+   * @param offset
+   *            specify the started pull offset
+   * @param maxNums
+   *            specify max msg num by per pull
+   * @return
+   *            accroding to PullResult
+   */
+  virtual PullResult pullBlockIfNotFound(const MQMessageQueue& mq,
+                                         const std::string& subExpression,
+                                         int64_t offset,
+                                         int maxNums) = 0;
+
+  virtual void pullBlockIfNotFound(const MQMessageQueue& mq,
+                                   const std::string& subExpression,
+                                   int64_t offset,
+                                   int maxNums,
+                                   PullCallback* pullCallback) = 0;
+
+  virtual void updateConsumeOffset(const MQMessageQueue& mq, int64_t offset) = 0;
+
+  /**
+   * Fetch the offset
+   *
+   * @param mq
+   * @param fromStore
+   * @return
+   */
+  virtual int64_t fetchConsumeOffset(const MQMessageQueue& mq, bool fromStore) = 0;
+
+  /**
+   * Fetch the message queues according to the topic
+   *
+   * @param topic Message Topic
+   * @return
+   */
+  virtual void fetchMessageQueuesInBalance(const std::string& topic, std::vector<MQMessageQueue>& mqs) = 0;
+};
+
+}  // namespace rocketmq
+
+#endif  // __MQ_PULL_CONSUMER_H__
diff --git a/src/protocol/KVTable.h b/include/MQPushConsumer.h
similarity index 53%
copy from src/protocol/KVTable.h
copy to include/MQPushConsumer.h
index e9b6a53..76d5f93 100644
--- a/src/protocol/KVTable.h
+++ b/include/MQPushConsumer.h
@@ -14,31 +14,28 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#ifndef __MQ_PUSH_CONSUMER_H__
+#define __MQ_PUSH_CONSUMER_H__
 
-#ifndef __KVTABLE_H__
-#define __KVTABLE_H__
-#include <map>
-#include <string>
-#include "RemotingSerializable.h"
-
-using std::map;
-using std::string;
+#include "MQConsumer.h"
+#include "MQMessageListener.h"
 
 namespace rocketmq {
-//<!***************************************************************************
-class KVTable : public RemotingSerializable {
- public:
-  virtual ~KVTable() { m_table.clear(); }
-
-  void Encode(string& outData) {}
 
-  const map<string, string>& getTable() { return m_table; }
+class ROCKETMQCLIENT_API MQPushConsumer : public MQConsumer {
+ public:  // MQPushConsumer in Java
+  // [[deprecated]]
+  virtual void registerMessageListener(MQMessageListener* messageListener) = 0;
+  virtual void registerMessageListener(MessageListenerConcurrently* messageListener) = 0;
+  virtual void registerMessageListener(MessageListenerOrderly* messageListener) = 0;
 
-  void setTable(const map<string, string>& table) { m_table = table; }
+  virtual void subscribe(const std::string& topic, const std::string& subExpression) = 0;
+  // virtual void subscribe(const std::string& topic, MessageSelector* selector) = 0;
 
- private:
-  map<string, string> m_table;
+  virtual void suspend() = 0;
+  virtual void resume() = 0;
 };
+
 }  // namespace rocketmq
 
-#endif
+#endif  // __MQ_PUSH_CONSUMER_H__
diff --git a/include/MQSelector.h b/include/MQSelector.h
index bba5781..f5de654 100644
--- a/include/MQSelector.h
+++ b/include/MQSelector.h
@@ -1,32 +1,37 @@
-/*
- * 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 _MQSELECTOR_H_
-#define _MQSELECTOR_H_
-#include "MQMessage.h"
-#include "MQMessageQueue.h"
-#include "RocketMQClient.h"
-
-namespace rocketmq {
-//<!***************************************************************************
-class ROCKETMQCLIENT_API MessageQueueSelector {
- public:
-  virtual ~MessageQueueSelector() {}
-  virtual MQMessageQueue select(const std::vector<MQMessageQueue>& mqs, const MQMessage& msg, void* arg) = 0;
-};
-//<!***************************************************************************
-}  // namespace rocketmq
-#endif  //<! _MQSELECTOR_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 __MQ_SELECTOR_H__
+#define __MQ_SELECTOR_H__
+
+#include "MQMessage.h"
+#include "MQMessageQueue.h"
+
+namespace rocketmq {
+
+/**
+ * MQ Selector Interface
+ */
+class ROCKETMQCLIENT_API MessageQueueSelector {
+ public:
+  virtual ~MessageQueueSelector() = default;
+
+  virtual MQMessageQueue select(const std::vector<MQMessageQueue>& mqs, const MQMessage& msg, void* arg) = 0;
+};
+
+}  // namespace rocketmq
+
+#endif  // __MQ_SELECTOR_H__
diff --git a/include/MQueueListener.h b/include/MQueueListener.h
index eef9590..11842aa 100644
--- a/include/MQueueListener.h
+++ b/include/MQueueListener.h
@@ -1,34 +1,38 @@
-/*
- * 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 __MESSAGEQUEUELISTENER_H__
-#define __MESSAGEQUEUELISTENER_H__
-
-#include <vector>
-#include "RocketMQClient.h"
-
-namespace rocketmq {
-//<!***************************************************************************
-class ROCKETMQCLIENT_API MQueueListener {
- public:
-  virtual ~MQueueListener() {}
-  virtual void messageQueueChanged(const std::string& topic,
-                                   std::vector<MQMessageQueue>& mqAll,
-                                   std::vector<MQMessageQueue>& mqDivided) = 0;
-};
-//<!***************************************************************************
-}  // namespace rocketmq
-#endif
+/*
+ * 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 __MQ_LISTENER_H__
+#define __MQ_LISTENER_H__
+
+#include <string>
+#include <vector>
+
+#include "MQMessageQueue.h"
+
+namespace rocketmq {
+
+class ROCKETMQCLIENT_API MQueueListener {
+ public:
+  virtual ~MQueueListener() = default;
+
+  virtual void messageQueueChanged(const std::string& topic,
+                                   std::vector<MQMessageQueue>& mqAll,
+                                   std::vector<MQMessageQueue>& mqDivided) = 0;
+};
+
+}  // namespace rocketmq
+
+#endif  // __MQ_LISTENER_H__
diff --git a/src/common/TopAddressing.h b/include/PullCallback.h
old mode 100644
new mode 100755
similarity index 55%
copy from src/common/TopAddressing.h
copy to include/PullCallback.h
index a698862..16fe81e
--- a/src/common/TopAddressing.h
+++ b/include/PullCallback.h
@@ -14,34 +14,31 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef __TOPADDRESSING_H__
-#define __TOPADDRESSING_H__
+#ifndef __PULL_CALLBACK_H__
+#define __PULL_CALLBACK_H__
 
-#include <boost/thread/thread.hpp>
-#include <list>
-#include <map>
-#include <string>
-#include "Logging.h"
-#include "UtilAll.h"
+#include "MQClientException.h"
+#include "PullResult.h"
 
 namespace rocketmq {
-class TopAddressing {
- public:
-  TopAddressing(string unitName);
-  virtual ~TopAddressing();
 
+enum PullCallbackType { PULL_CALLBACK_TYPE_SIMPLE = 0, PULL_CALLBACK_TYPE_AUTO_DELETE = 1 };
+
+class ROCKETMQCLIENT_API PullCallback {
  public:
-  virtual string fetchNSAddr(const string& NSDomain);
+  virtual ~PullCallback() = default;
 
- private:
-  string clearNewLine(const string& str);
-  void updateNameServerAddressList(const string& adds);
-  int IsIPAddr(const char* sValue);
+  virtual void onSuccess(PullResult& pullResult) = 0;
+  virtual void onException(MQException& e) noexcept = 0;
 
- private:
-  boost::mutex m_addrLock;
-  list<string> m_addrs;
-  string m_unitName;
+  virtual PullCallbackType getPullCallbackType() const { return PULL_CALLBACK_TYPE_SIMPLE; }
 };
+
+class ROCKETMQCLIENT_API AutoDeletePullCallback : public PullCallback {
+ public:
+  PullCallbackType getPullCallbackType() const override final { return PULL_CALLBACK_TYPE_AUTO_DELETE; }
+};
+
 }  // namespace rocketmq
-#endif
+
+#endif  // __PULL_CALLBACK_H__
diff --git a/include/PullResult.h b/include/PullResult.h
index 61eedf0..d43fda2 100644
--- a/include/PullResult.h
+++ b/include/PullResult.h
@@ -1,68 +1,74 @@
-/*
- * 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 __PULLRESULT_H__
-#define __PULLRESULT_H__
-
-#include <sstream>
-#include "MQMessageExt.h"
-#include "RocketMQClient.h"
-
-namespace rocketmq {
-//<!***************************************************************************
-enum PullStatus {
-  FOUND,
-  NO_NEW_MSG,
-  NO_MATCHED_MSG,
-  OFFSET_ILLEGAL,
-  BROKER_TIMEOUT  // indicate pull request timeout or received NULL response
-};
-
-static const char* EnumStrings[] = {"FOUND", "NO_NEW_MSG", "NO_MATCHED_MSG", "OFFSET_ILLEGAL", "BROKER_TIMEOUT"};
-
-//<!***************************************************************************
-class ROCKETMQCLIENT_API PullResult {
- public:
-  PullResult();
-  PullResult(PullStatus status);
-  PullResult(PullStatus pullStatus, int64 nextBeginOffset, int64 minOffset, int64 maxOffset);
-
-  PullResult(PullStatus pullStatus,
-             int64 nextBeginOffset,
-             int64 minOffset,
-             int64 maxOffset,
-             const std::vector<MQMessageExt>& src);
-
-  virtual ~PullResult();
-
-  std::string toString() {
-    std::stringstream ss;
-    ss << "PullResult [ pullStatus=" << EnumStrings[pullStatus] << ", nextBeginOffset=" << nextBeginOffset
-       << ", minOffset=" << minOffset << ", maxOffset=" << maxOffset << ", msgFoundList=" << msgFoundList.size()
-       << " ]";
-    return ss.str();
-  }
-
- public:
-  PullStatus pullStatus;
-  int64 nextBeginOffset;
-  int64 minOffset;
-  int64 maxOffset;
-  std::vector<MQMessageExt> msgFoundList;
-};
-//<!***************************************************************************
-}  // namespace rocketmq
-#endif
+/*
+ * 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 __PULL_RESULT_H__
+#define __PULL_RESULT_H__
+
+#include <memory>
+#include <sstream>
+
+#include "MQMessageExt.h"
+
+namespace rocketmq {
+
+enum PullStatus {
+  FOUND,
+  NO_NEW_MSG,
+  NO_MATCHED_MSG,
+  OFFSET_ILLEGAL,
+  BROKER_TIMEOUT  // indicate pull request timeout or received NULL response
+};
+
+static const char* EnumStrings[] = {"FOUND", "NO_NEW_MSG", "NO_MATCHED_MSG", "OFFSET_ILLEGAL", "BROKER_TIMEOUT"};
+
+class ROCKETMQCLIENT_API PullResult {
+ public:
+  PullResult();
+  PullResult(PullStatus status);
+  PullResult(PullStatus pullStatus, int64_t nextBeginOffset, int64_t minOffset, int64_t maxOffset);
+
+  PullResult(PullStatus pullStatus,
+             int64_t nextBeginOffset,
+             int64_t minOffset,
+             int64_t maxOffset,
+             const std::vector<MQMessageExtPtr2>& src);
+  PullResult(PullStatus pullStatus,
+             int64_t nextBeginOffset,
+             int64_t minOffset,
+             int64_t maxOffset,
+             std::vector<MQMessageExtPtr2>&& src);
+
+  virtual ~PullResult();
+
+  std::string toString() const {
+    std::stringstream ss;
+    ss << "PullResult [ pullStatus=" << EnumStrings[pullStatus] << ", nextBeginOffset=" << nextBeginOffset
+       << ", minOffset=" << minOffset << ", maxOffset=" << maxOffset << ", msgFoundList=" << msgFoundList.size()
+       << " ]";
+    return ss.str();
+  }
+
+ public:
+  PullStatus pullStatus;
+  int64_t nextBeginOffset;
+  int64_t minOffset;
+  int64_t maxOffset;
+  std::vector<MQMessageExtPtr2> msgFoundList;
+};
+
+}  // namespace rocketmq
+
+#endif  // __PULL_RESULT_H__
diff --git a/include/QueryResult.h b/include/QueryResult.h
index b7c3697..958a499 100644
--- a/include/QueryResult.h
+++ b/include/QueryResult.h
@@ -1,42 +1,42 @@
-/*
- * 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 __QUERYRESULT_H__
-#define __QUERYRESULT_H__
-
-#include "MQMessageExt.h"
-#include "RocketMQClient.h"
-
-namespace rocketmq {
-//<!************************************************************************
-class ROCKETMQCLIENT_API QueryResult {
- public:
-  QueryResult(uint64 indexLastUpdateTimestamp, const std::vector<MQMessageExt*>& messageList) {
-    m_indexLastUpdateTimestamp = indexLastUpdateTimestamp;
-    m_messageList = messageList;
-  }
-
-  uint64 getIndexLastUpdateTimestamp() { return m_indexLastUpdateTimestamp; }
-
-  std::vector<MQMessageExt*>& getMessageList() { return m_messageList; }
-
- private:
-  uint64 m_indexLastUpdateTimestamp;
-  std::vector<MQMessageExt*> m_messageList;
-};
-//<!***************************************************************************
-}  // namespace rocketmq
-#endif
+/*
+ * 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 __QUERY_RESULT_H__
+#define __QUERY_RESULT_H__
+
+#include "MQMessageExt.h"
+
+namespace rocketmq {
+
+class ROCKETMQCLIENT_API QueryResult {
+ public:
+  QueryResult(uint64_t indexLastUpdateTimestamp, const std::vector<MQMessageExtPtr>& messageList) {
+    m_indexLastUpdateTimestamp = indexLastUpdateTimestamp;
+    m_messageList = messageList;
+  }
+
+  uint64_t getIndexLastUpdateTimestamp() { return m_indexLastUpdateTimestamp; }
+
+  std::vector<MQMessageExtPtr>& getMessageList() { return m_messageList; }
+
+ private:
+  uint64_t m_indexLastUpdateTimestamp;
+  std::vector<MQMessageExtPtr> m_messageList;
+};
+
+}  // namespace rocketmq
+
+#endif  // __QUERY_RESULT_H__
diff --git a/src/protocol/KVTable.h b/include/RPCHook.h
similarity index 59%
copy from src/protocol/KVTable.h
copy to include/RPCHook.h
index e9b6a53..5ee88b6 100644
--- a/src/protocol/KVTable.h
+++ b/include/RPCHook.h
@@ -14,31 +14,31 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#ifndef __RPC_HOOK_H__
+#define __RPC_HOOK_H__
 
-#ifndef __KVTABLE_H__
-#define __KVTABLE_H__
-#include <map>
+#include <memory>
 #include <string>
-#include "RemotingSerializable.h"
 
-using std::map;
-using std::string;
+#include "RemotingCommand.h"
 
 namespace rocketmq {
-//<!***************************************************************************
-class KVTable : public RemotingSerializable {
- public:
-  virtual ~KVTable() { m_table.clear(); }
-
-  void Encode(string& outData) {}
-
-  const map<string, string>& getTable() { return m_table; }
 
-  void setTable(const map<string, string>& table) { m_table = table; }
+class RPCHook;
+typedef std::shared_ptr<RPCHook> RPCHookPtr;
 
- private:
-  map<string, string> m_table;
+class ROCKETMQCLIENT_API RPCHook {
+ public:
+  RPCHook() = default;
+  virtual ~RPCHook() = default;
+
+  virtual void doBeforeRequest(const std::string& remoteAddr, RemotingCommand& request, bool toSent) = 0;
+  virtual void doAfterResponse(const std::string& remoteAddr,
+                               RemotingCommand& request,
+                               RemotingCommand* response,
+                               bool toSent) = 0;
 };
+
 }  // namespace rocketmq
 
-#endif
+#endif  // __RPC_HOOK_H__
diff --git a/include/RemotingCommand.h b/include/RemotingCommand.h
new file mode 100644
index 0000000..e204445
--- /dev/null
+++ b/include/RemotingCommand.h
@@ -0,0 +1,127 @@
+/*
+ * 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 __REMOTING_COMMAND_H__
+#define __REMOTING_COMMAND_H__
+
+#include <map>
+#include <memory>
+#include <typeindex>
+
+#include "CommandCustomHeader.h"
+#include "MQClientException.h"
+
+namespace rocketmq {
+
+class MemoryBlock;
+typedef MemoryBlock* MemoryBlockPtr;
+typedef std::shared_ptr<MemoryBlock> MemoryBlockPtr2;
+
+class ROCKETMQCLIENT_API RemotingCommand {
+ public:
+  static int32_t createNewRequestId();
+
+ public:
+  RemotingCommand() : m_code(0) {}
+  RemotingCommand(int32_t code, CommandCustomHeader* customHeader = nullptr);
+  RemotingCommand(int32_t code,
+                  const std::string& language,
+                  int32_t version,
+                  int32_t opaque,
+                  int32_t flag,
+                  const std::string& remark,
+                  CommandCustomHeader* customHeader);
+  RemotingCommand(RemotingCommand&& command);
+
+  virtual ~RemotingCommand();
+
+  int32_t getCode() const;
+  void setCode(int32_t code);
+
+  int32_t getVersion() const;
+
+  int32_t getOpaque() const;
+  void setOpaque(int32_t opaque);
+
+  int32_t getFlag() const;
+
+  const std::string& getRemark() const;
+  void setRemark(const std::string& mark);
+
+  bool isResponseType();
+  void markResponseType();
+
+  bool isOnewayRPC();
+  void markOnewayRPC();
+
+  void addExtField(const std::string& key, const std::string& value);
+
+  CommandCustomHeader* readCustomHeader() const;
+
+  MemoryBlockPtr2 getBody();
+  void setBody(MemoryBlock* body);
+  void setBody(MemoryBlockPtr2 body);
+  void setBody(const std::string& body);
+
+ public:
+  MemoryBlockPtr encode();
+
+  template <class H>
+  H* decodeCommandCustomHeader(bool useCache);
+
+  template <class H>
+  H* decodeCommandCustomHeader();
+
+  static RemotingCommand* Decode(MemoryBlockPtr2& package);
+
+  std::string toString() const;
+
+ private:
+  int32_t m_code;
+  std::string m_language;
+  int32_t m_version;
+  int32_t m_opaque;
+  int32_t m_flag;
+  std::string m_remark;
+  std::map<std::string, std::string> m_extFields;
+  std::unique_ptr<CommandCustomHeader> m_customHeader;  // transient
+
+  MemoryBlockPtr2 m_body;  // transient
+};
+
+template <class H>
+H* RemotingCommand::decodeCommandCustomHeader(bool useCache) {
+  auto* cache = m_customHeader.get();
+  if (cache != nullptr && useCache && std::type_index(typeid(*cache)) == std::type_index(typeid(H))) {
+    return static_cast<H*>(m_customHeader.get());
+  }
+  return decodeCommandCustomHeader<H>();
+}
+
+template <class H>
+H* RemotingCommand::decodeCommandCustomHeader() {
+  try {
+    H* header = H::Decode(m_extFields);
+    m_customHeader.reset(header);
+    return header;
+  } catch (std::exception& e) {
+    THROW_MQEXCEPTION(RemotingCommandException, e.what(), -1);
+  }
+}
+
+}  // namespace rocketmq
+
+#endif  // __REMOTING_COMMAND_H__
diff --git a/include/RocketMQClient.h b/include/RocketMQClient.h
index 26ae379..09be801 100644
--- a/include/RocketMQClient.h
+++ b/include/RocketMQClient.h
@@ -1,55 +1,76 @@
-/*
- * 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 __ROCKETMQCLIENT_H__
-#define __ROCKETMQCLIENT_H__
-
-#ifdef WIN32
-#ifdef ROCKETMQCLIENT_EXPORTS
-#ifdef _WINDLL
-#define ROCKETMQCLIENT_API __declspec(dllexport)
-#else
-#define ROCKETMQCLIENT_API
-#endif
-#else
-#ifdef ROCKETMQCLIENT_IMPORT
-#define ROCKETMQCLIENT_API __declspec(dllimport)
-#else
-#define ROCKETMQCLIENT_API
-#endif
-#endif
-#else
-#define ROCKETMQCLIENT_API
-#endif
-
-/** A platform-independent 8-bit signed integer type. */
-typedef signed char int8;
-/** A platform-independent 8-bit unsigned integer type. */
-typedef unsigned char uint8;
-/** A platform-independent 16-bit signed integer type. */
-typedef signed short int16;
-/** A platform-independent 16-bit unsigned integer type. */
-typedef unsigned short uint16;
-/** A platform-independent 32-bit signed integer type. */
-typedef signed int int32;
-/** A platform-independent 32-bit unsigned integer type. */
-typedef unsigned int uint32;
-/** A platform-independent 64-bit integer type. */
-typedef long long int64;
-/** A platform-independent 64-bit unsigned integer type. */
-typedef unsigned long long uint64;
-
-#endif
+/*
+ * 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_CLIENT_H__
+#define __ROCKETMQ_CLIENT_H__
+
+#include <cstdint>
+
+#ifdef WIN32
+#ifdef ROCKETMQCLIENT_EXPORTS
+#ifdef _WINDLL
+#define ROCKETMQCLIENT_API __declspec(dllexport)
+#else  // _WINDLL
+#define ROCKETMQCLIENT_API
+#endif  // _WINDLL
+#else   // ROCKETMQCLIENT_EXPORTS
+#ifdef ROCKETMQCLIENT_IMPORT
+#define ROCKETMQCLIENT_API __declspec(dllimport)
+#else  // ROCKETMQCLIENT_IMPORT
+#define ROCKETMQCLIENT_API
+#endif  // ROCKETMQCLIENT_IMPORT
+#endif  // ROCKETMQCLIENT_EXPORTS
+#else   // WIN32
+#define ROCKETMQCLIENT_API
+#endif  // WIN32
+
+/** A platform-independent 8-bit signed integer type. */
+typedef int8_t int8;
+
+/** A platform-independent 8-bit unsigned integer type. */
+typedef uint8_t uint8;
+
+/** A platform-independent 16-bit signed integer type. */
+typedef int16_t int16;
+
+/** A platform-independent 16-bit unsigned integer type. */
+typedef uint16_t uint16;
+
+/** A platform-independent 32-bit signed integer type. */
+typedef int32_t int32;
+
+/** A platform-independent 32-bit unsigned integer type. */
+typedef uint32_t uint32;
+
+/** A platform-independent 64-bit integer type. */
+typedef int64_t int64;
+
+/** A platform-independent 64-bit unsigned integer type. */
+typedef uint64_t uint64;
+
+#ifdef WIN32
+#define SIZET_FMT "%lu"
+#else
+#define SIZET_FMT "%zu"
+#endif
+
+#ifdef WIN32
+#define FILE_SEPARATOR "\\"
+#else
+#define FILE_SEPARATOR "/"
+#endif
+
+#endif  // __ROCKETMQ_CLIENT_H__
diff --git a/include/SendMessageHook.h b/include/SendCallback.h
old mode 100644
new mode 100755
similarity index 53%
copy from include/SendMessageHook.h
copy to include/SendCallback.h
index 1af0e92..7370250
--- a/include/SendMessageHook.h
+++ b/include/SendCallback.h
@@ -1,47 +1,45 @@
-/*
- * 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 __SENDMESSAGEHOOK_H__
-#define __SENDMESSAGEHOOK_H__
-
-#include "MQClientException.h"
-#include "MQMessage.h"
-#include "RocketMQClient.h"
-
-namespace rocketmq {
-//<!***************************************************************************
-class ROCKETMQCLIENT_API SendMessageContext {
- public:
-  string producerGroup;
-  MQMessage msg;
-  MQMessageQueue mq;
-  string brokerAddr;
-  int communicationMode;
-  SendResult sendResult;
-  MQException* pException;
-  void* pArg;
-};
-
-class ROCKETMQCLIENT_API SendMessageHook {
- public:
-  virtual ~SendMessageHook() {}
-  virtual string hookName() = 0;
-  virtual void sendMessageBefore(const SendMessageContext& context) = 0;
-  virtual void sendMessageAfter(const SendMessageContext& context) = 0;
-};
-//<!***************************************************************************
-}  // namespace rocketmq
-#endif
+/*
+ * 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 __SEND_CALLBACK_H__
+#define __SEND_CALLBACK_H__
+
+#include "MQClientException.h"
+#include "SendResult.h"
+
+namespace rocketmq {
+
+enum SendCallbackType { SEND_CALLBACK_TYPE_SIMPLE = 0, SEND_CALLBACK_TYPE_ATUO_DELETE = 1 };
+
+class ROCKETMQCLIENT_API SendCallback {
+ public:
+  virtual ~SendCallback() = default;
+
+  virtual void onSuccess(SendResult& sendResult) = 0;
+  virtual void onException(MQException& e) noexcept = 0;
+
+  virtual SendCallbackType getSendCallbackType() const { return SEND_CALLBACK_TYPE_SIMPLE; }
+};
+
+// async SendCallback will be deleted automatically by rocketmq cpp after invoke callback interface
+class ROCKETMQCLIENT_API AutoDeleteSendCallback : public SendCallback {
+ public:
+  SendCallbackType getSendCallbackType() const override final { return SEND_CALLBACK_TYPE_ATUO_DELETE; }
+};
+
+}  // namespace rocketmq
+
+#endif  // __SEND_CALLBACK_H__
diff --git a/include/SendMessageHook.h b/include/SendMessageHook.h
index 1af0e92..5152889 100644
--- a/include/SendMessageHook.h
+++ b/include/SendMessageHook.h
@@ -1,47 +1,47 @@
-/*
- * 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 __SENDMESSAGEHOOK_H__
-#define __SENDMESSAGEHOOK_H__
-
-#include "MQClientException.h"
-#include "MQMessage.h"
-#include "RocketMQClient.h"
-
-namespace rocketmq {
-//<!***************************************************************************
-class ROCKETMQCLIENT_API SendMessageContext {
- public:
-  string producerGroup;
-  MQMessage msg;
-  MQMessageQueue mq;
-  string brokerAddr;
-  int communicationMode;
-  SendResult sendResult;
-  MQException* pException;
-  void* pArg;
-};
-
-class ROCKETMQCLIENT_API SendMessageHook {
- public:
-  virtual ~SendMessageHook() {}
-  virtual string hookName() = 0;
-  virtual void sendMessageBefore(const SendMessageContext& context) = 0;
-  virtual void sendMessageAfter(const SendMessageContext& context) = 0;
-};
-//<!***************************************************************************
-}  // namespace rocketmq
-#endif
+// /*
+//  * 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 __SEND_MESSAGE_HOOK_H__
+// #define __SEND_MESSAGE_HOOK_H__
+
+// #include "MQMessage.h"
+
+// namespace rocketmq {
+
+// class ROCKETMQCLIENT_API SendMessageContext {
+//  public:
+//   std::string producerGroup;
+//   MQMessage msg;
+//   MQMessageQueue mq;
+//   string brokerAddr;
+//   int communicationMode;
+//   SendResult sendResult;
+//   MQException* pException;
+//   void* pArg;
+// };
+
+// class ROCKETMQCLIENT_API SendMessageHook {
+//  public:
+//   virtual ~SendMessageHook() = default;
+
+//   virtual std::string hookName() = 0;
+//   virtual void sendMessageBefore(const SendMessageContext& context) = 0;
+//   virtual void sendMessageAfter(const SendMessageContext& context) = 0;
+// };
+
+// }  // namespace rocketmq
+
+// #endif  // __SEND_MESSAGE_HOOK_H__
diff --git a/include/SendResult.h b/include/SendResult.h
index 870d03b..1a713ba 100644
--- a/include/SendResult.h
+++ b/include/SendResult.h
@@ -1,64 +1,63 @@
-/*
- * 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 __SENDRESULT_H__
-#define __SENDRESULT_H__
-
-#include "MQMessageQueue.h"
-#include "RocketMQClient.h"
-
-namespace rocketmq {
-//<!***************************************************************************
-//<!all to Master;
-enum SendStatus { SEND_OK, SEND_FLUSH_DISK_TIMEOUT, SEND_FLUSH_SLAVE_TIMEOUT, SEND_SLAVE_NOT_AVAILABLE };
-
-//<!***************************************************************************
-class ROCKETMQCLIENT_API SendResult {
- public:
-  SendResult();
-  SendResult(const SendStatus& sendStatus,
-             const std::string& msgId,
-             const std::string& offsetMsgId,
-             const MQMessageQueue& messageQueue,
-             int64 queueOffset);
-
-  virtual ~SendResult();
-  SendResult(const SendResult& other);
-  SendResult& operator=(const SendResult& other);
-
-  void setTransactionId(const std::string& id) { m_transactionId = id; }
-
-  std::string getTransactionId() { return m_transactionId; }
-
-  const std::string& getMsgId() const;
-  const std::string& getOffsetMsgId() const;
-  SendStatus getSendStatus() const;
-  MQMessageQueue getMessageQueue() const;
-  int64 getQueueOffset() const;
-  std::string toString() const;
-
- private:
-  SendStatus m_sendStatus;
-  std::string m_msgId;
-  std::string m_offsetMsgId;
-  MQMessageQueue m_messageQueue;
-  int64 m_queueOffset;
-  std::string m_transactionId;
-};
-
-//<!***************************************************************************
-}  // namespace rocketmq
-#endif
+/*
+ * 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 __SEND_RESULT_H__
+#define __SEND_RESULT_H__
+
+#include "MQMessageQueue.h"
+
+namespace rocketmq {
+
+// all to Master;
+enum SendStatus { SEND_OK, SEND_FLUSH_DISK_TIMEOUT, SEND_FLUSH_SLAVE_TIMEOUT, SEND_SLAVE_NOT_AVAILABLE };
+
+class ROCKETMQCLIENT_API SendResult {
+ public:
+  SendResult();
+  SendResult(const SendStatus& sendStatus,
+             const std::string& msgId,
+             const std::string& offsetMsgId,
+             const MQMessageQueue& messageQueue,
+             int64_t queueOffset);
+
+  SendResult(const SendResult& other);
+  SendResult& operator=(const SendResult& other);
+
+  virtual ~SendResult();
+
+  SendStatus getSendStatus() const;
+  const std::string& getMsgId() const;
+  const std::string& getOffsetMsgId() const;
+  const MQMessageQueue& getMessageQueue() const;
+  int64_t getQueueOffset() const;
+
+  const std::string& getTransactionId() const { return m_transactionId; }
+  void setTransactionId(const std::string& id) { m_transactionId = id; }
+
+  std::string toString() const;
+
+ private:
+  SendStatus m_sendStatus;
+  std::string m_msgId;
+  std::string m_offsetMsgId;
+  MQMessageQueue m_messageQueue;
+  int64_t m_queueOffset;
+  std::string m_transactionId;
+};
+
+}  // namespace rocketmq
+
+#endif  // __SEND_RESULT_H__
diff --git a/include/SessionCredentials.h b/include/SessionCredentials.h
index e035160..5feea08 100644
--- a/include/SessionCredentials.h
+++ b/include/SessionCredentials.h
@@ -14,15 +14,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#ifndef __SESSION_CREDENTIALS_H__
+#define __SESSION_CREDENTIALS_H__
 
-#ifndef __SESSIONCREDENTIALS_H__
-#define __SESSIONCREDENTIALS_H__
+#include <string>
 
 #include "RocketMQClient.h"
 
 namespace rocketmq {
 
-class SessionCredentials {
+class ROCKETMQCLIENT_API SessionCredentials {
  public:
   static const std::string AccessKey;
   static const std::string SecretKey;
@@ -30,44 +31,37 @@ class SessionCredentials {
   static const std::string SignatureMethod;
   static const std::string ONSChannelKey;
 
-  SessionCredentials(std::string input_accessKey, std::string input_secretKey, const std::string& input_authChannel)
-      : accessKey(input_accessKey), secretKey(input_secretKey), authChannel(input_authChannel) {}
-  SessionCredentials() : authChannel("ALIYUN") {}
-  ~SessionCredentials() {}
+  SessionCredentials() : authChannel_("ALIYUN") {}
+  SessionCredentials(const std::string& accessKey, const std::string& secretKey, const std::string& authChannel)
+      : accessKey_(accessKey), secretKey_(secretKey), authChannel_(authChannel) {}
 
-  std::string getAccessKey() const { return accessKey; }
+  ~SessionCredentials() = default;
 
-  void setAccessKey(std::string input_accessKey) { accessKey = input_accessKey; }
+  const std::string& getAccessKey() const { return accessKey_; }
+  void setAccessKey(const std::string& accessKey) { accessKey_ = accessKey; }
 
-  std::string getSecretKey() const { return secretKey; }
+  const std::string& getSecretKey() const { return secretKey_; }
+  void setSecretKey(const std::string& secretKey) { secretKey_ = secretKey; }
 
-  void setSecretKey(std::string input_secretKey) { secretKey = input_secretKey; }
+  const std::string& getSignature() const { return signature_; }
+  void setSignature(const std::string& signature) { signature_ = signature; }
 
-  std::string getSignature() const { return signature; }
+  const std::string& getSignatureMethod() const { return signatureMethod_; }
+  void setSignatureMethod(const std::string& signatureMethod) { signatureMethod_ = signatureMethod; }
 
-  void setSignature(std::string input_signature) { signature = input_signature; }
+  const std::string& getAuthChannel() const { return authChannel_; }
+  void setAuthChannel(const std::string& channel) { authChannel_ = channel; }
 
-  std::string getSignatureMethod() const { return signatureMethod; }
-
-  void setSignatureMethod(std::string input_signatureMethod) { signatureMethod = input_signatureMethod; }
-
-  std::string getAuthChannel() const { return authChannel; }
-
-  void setAuthChannel(std::string input_channel) { authChannel = input_channel; }
-
-  bool isValid() const {
-    if (accessKey.empty() || secretKey.empty() || authChannel.empty())
-      return false;
-
-    return true;
-  }
+  bool isValid() const { return !accessKey_.empty() && !secretKey_.empty() && !authChannel_.empty(); }
 
  private:
-  std::string accessKey;
-  std::string secretKey;
-  std::string signature;
-  std::string signatureMethod;
-  std::string authChannel;
+  std::string accessKey_;
+  std::string secretKey_;
+  std::string signature_;
+  std::string signatureMethod_;
+  std::string authChannel_;
 };
+
 }  // namespace rocketmq
-#endif
+
+#endif  // __SESSION_CREDENTIALS_H__
diff --git a/src/common/TopicFilterType.h b/include/TopicFilterType.h
similarity index 79%
rename from src/common/TopicFilterType.h
rename to include/TopicFilterType.h
index 9055003..9f57a42 100644
--- a/src/common/TopicFilterType.h
+++ b/include/TopicFilterType.h
@@ -14,11 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef __TOPICFILTERTYPE_H__
-#define __TOPICFILTERTYPE_H__
+#ifndef __TOPIC_FILTER_TYPE_H__
+#define __TOPIC_FILTER_TYPE_H__
 
 namespace rocketmq {
-//<!***************************************************************************
+
 enum TopicFilterType {
   /**
    * each msg could only have one tag
@@ -29,6 +29,7 @@ enum TopicFilterType {
    */
   MULTI_TAG
 };
-//<!***************************************************************************
-}  //<!end namespace;
-#endif
+
+}  // namespace rocketmq
+
+#endif  // __TOPIC_FILTER_TYPE_H__
diff --git a/include/TransactionListener.h b/include/TransactionListener.h
index 6756e96..3af087c 100644
--- a/include/TransactionListener.h
+++ b/include/TransactionListener.h
@@ -14,18 +14,18 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#ifndef __TRANSACTION_LISTENER_H__
+#define __TRANSACTION_LISTENER_H__
 
-#ifndef __TRANSACTIONLISTENER_H__
-#define __TRANSACTIONLISTENER_H__
-
-#include "MQMessage.h"
 #include "MQMessageExt.h"
 #include "TransactionSendResult.h"
 
 namespace rocketmq {
+
 class ROCKETMQCLIENT_API TransactionListener {
  public:
-  virtual ~TransactionListener() {}
+  virtual ~TransactionListener() = default;
+
   /**
    * When send transactional prepare(half) message succeed, this method will be invoked to execute local transaction.
    *
@@ -44,5 +44,7 @@ class ROCKETMQCLIENT_API TransactionListener {
    */
   virtual LocalTransactionState checkLocalTransaction(const MQMessageExt& msg) = 0;
 };
+
 }  // namespace rocketmq
-#endif
+
+#endif  // __TRANSACTION_LISTENER_H__
diff --git a/include/TransactionMQProducer.h b/include/TransactionMQProducer.h
index fcd9a7c..97ce077 100644
--- a/include/TransactionMQProducer.h
+++ b/include/TransactionMQProducer.h
@@ -14,61 +14,41 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#ifndef __TRANSACTION_MQ_PRODUCER_H__
+#define __TRANSACTION_MQ_PRODUCER_H__
 
-#ifndef __TRANSACTIONMQPRODUCER_H__
-#define __TRANSACTIONMQPRODUCER_H__
-
-#include <boost/asio.hpp>
-#include <boost/asio/io_service.hpp>
-#include <boost/bind.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
-#include <boost/weak_ptr.hpp>
-#include <memory>
-#include <string>
 #include "DefaultMQProducer.h"
-#include "MQMessageExt.h"
 #include "TransactionListener.h"
-#include "TransactionSendResult.h"
 
 namespace rocketmq {
 
-class ROCKETMQCLIENT_API TransactionMQProducer : public DefaultMQProducer {
+class ROCKETMQCLIENT_API TransactionMQProducerConfig {
  public:
-  TransactionMQProducer(const std::string& producerGroup)
-      : DefaultMQProducer(producerGroup), m_thread_num(1), m_ioServiceWork(m_ioService) {}
-  virtual ~TransactionMQProducer() {}
-  void start();
-  void shutdown();
-  std::shared_ptr<TransactionListener> getTransactionListener() { return m_transactionListener; }
-  void setTransactionListener(TransactionListener* listener) { m_transactionListener.reset(listener); }
-  TransactionSendResult sendMessageInTransaction(MQMessage& msg, void* arg);
-  void checkTransactionState(const std::string& addr,
-                             const MQMessageExt& message,
-                             long tranStateTableOffset,
-                             long commitLogOffset,
-                             const std::string& msgId,
-                             const std::string& transactionId,
-                             const std::string& offsetMsgId);
+  TransactionMQProducerConfig();
+  virtual ~TransactionMQProducerConfig() = default;
 
- private:
-  void initTransactionEnv();
-  void destroyTransactionEnv();
-  void endTransaction(SendResult& sendResult, LocalTransactionState& localTransactionState);
-  void checkTransactionStateImpl(const std::string& addr,
-                                 const MQMessageExt& message,
-                                 long tranStateTableOffset,
-                                 long commitLogOffset,
-                                 const std::string& msgId,
-                                 const std::string& transactionId,
-                                 const std::string& offsetMsgId);
+ public:  // TransactionMQProducerConfig
+  TransactionListener* getTransactionListener() const { return m_transactionListener; }
+  void setTransactionListener(TransactionListener* transactionListener) { m_transactionListener = transactionListener; }
 
- private:
-  std::shared_ptr<TransactionListener> m_transactionListener;
-  int m_thread_num;
-  boost::thread_group m_threadpool;
-  boost::asio::io_service m_ioService;
-  boost::asio::io_service::work m_ioServiceWork;
+ protected:
+  TransactionListener* m_transactionListener;
 };
+
+class ROCKETMQCLIENT_API TransactionMQProducer : public DefaultMQProducer, public TransactionMQProducerConfig {
+ public:
+  TransactionMQProducer(const std::string& groupname);
+  TransactionMQProducer(const std::string& groupname, RPCHookPtr rpcHook);
+  virtual ~TransactionMQProducer();
+
+ public:  // MQProducer
+  void start() override;
+  void shutdown() override;
+
+  // Transaction
+  TransactionSendResult sendMessageInTransaction(MQMessagePtr msg, void* arg) override;
+};
+
 }  // namespace rocketmq
 
-#endif
+#endif  // __TRANSACTION_MQ_PRODUCER_H__
diff --git a/include/TransactionSendResult.h b/include/TransactionSendResult.h
index 0bb1e48..03d626f 100644
--- a/include/TransactionSendResult.h
+++ b/include/TransactionSendResult.h
@@ -14,9 +14,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-#ifndef __TRANSACTIONSENDRESULT_H__
-#define __TRANSACTIONSENDRESULT_H__
+#ifndef __TRANSACTION_SEND_RESULT_H__
+#define __TRANSACTION_SEND_RESULT_H__
 
 #include "SendResult.h"
 
@@ -26,14 +25,7 @@ enum LocalTransactionState { COMMIT_MESSAGE, ROLLBACK_MESSAGE, UNKNOWN };
 
 class ROCKETMQCLIENT_API TransactionSendResult : public SendResult {
  public:
-  TransactionSendResult() {}
-
-  TransactionSendResult(const SendStatus& sendStatus,
-                        const std::string& msgId,
-                        const std::string& offsetMsgId,
-                        const MQMessageQueue& messageQueue,
-                        int64 queueOffset)
-      : SendResult(sendStatus, msgId, offsetMsgId, messageQueue, queueOffset) {}
+  TransactionSendResult(const SendResult& sendResult) : SendResult(sendResult), m_localTransactionState(UNKNOWN) {}
 
   LocalTransactionState getLocalTransactionState() { return m_localTransactionState; }
 
@@ -44,5 +36,7 @@ class ROCKETMQCLIENT_API TransactionSendResult : public SendResult {
  private:
   LocalTransactionState m_localTransactionState;
 };
+
 }  // namespace rocketmq
-#endif
\ No newline at end of file
+
+#endif  // __TRANSACTION_SEND_RESULT_H__
diff --git a/include/CBatchMessage.h b/include/c/CBatchMessage.h
similarity index 92%
rename from include/CBatchMessage.h
rename to include/c/CBatchMessage.h
index b9a0e9d..1b4da7e 100644
--- a/include/CBatchMessage.h
+++ b/include/c/CBatchMessage.h
@@ -14,9 +14,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#ifndef __C_BATCH_MESSAGE_H__
+#define __C_BATCH_MESSAGE_H__
 
-#ifndef __C_BATCHMESSAGE_H__
-#define __C_BATCHMESSAGE_H__
 #include "CCommon.h"
 #include "CMessage.h"
 
@@ -33,4 +33,5 @@ ROCKETMQCLIENT_API int DestroyBatchMessage(CBatchMessage* batchMsg);
 #ifdef __cplusplus
 }
 #endif
-#endif  //__C_BATCHMESSAGE_H__
+
+#endif  // __C_BATCH_MESSAGE_H__
diff --git a/include/CCommon.h b/include/c/CCommon.h
similarity index 94%
rename from include/CCommon.h
rename to include/c/CCommon.h
index 0fbcbda..167f645 100644
--- a/include/CCommon.h
+++ b/include/c/CCommon.h
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 #ifndef __C_COMMON_H__
 #define __C_COMMON_H__
 
@@ -25,11 +24,11 @@ extern "C" {
 #define MAX_MESSAGE_ID_LENGTH 256
 #define MAX_TOPIC_LENGTH 512
 #define MAX_BROKER_NAME_ID_LENGTH 256
+
 typedef enum _CStatus_ {
-  // Success
-  OK = 0,
-  // Failed, null pointer value
-  NULL_POINTER = 1,
+  OK = 0,  // Success
+
+  NULL_POINTER = 1,  // Failed, null pointer value
   MALLOC_FAILED = 2,
   PRODUCER_ERROR_CODE_START = 10,
   PRODUCER_START_FAILED = 10,
@@ -48,7 +47,6 @@ typedef enum _CStatus_ {
   PULLCONSUMER_FETCH_MQ_FAILED = 31,
   PULLCONSUMER_FETCH_MESSAGE_FAILED = 32,
 
-  Not_Support = 500,
   NOT_SUPPORT_NOW = -1
 } CStatus;
 
@@ -85,4 +83,5 @@ typedef enum _CMessageModel_ { BROADCASTING, CLUSTERING } CMessageModel;
 #ifdef __cplusplus
 }
 #endif
-#endif  //__C_COMMON_H__
+
+#endif  // __C_COMMON_H__
diff --git a/include/CErrorMessage.h b/include/c/CErrorMessage.h
similarity index 91%
rename from include/CErrorMessage.h
rename to include/c/CErrorMessage.h
index 7d11b56..928950c 100644
--- a/include/CErrorMessage.h
+++ b/include/c/CErrorMessage.h
@@ -14,9 +14,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-#ifndef __CERROR_MESSAGE_H__
-#define __CERROR_MESSAGE_H__
+#ifndef __C_ERROR_MESSAGE_H__
+#define __C_ERROR_MESSAGE_H__
 
 #include "CCommon.h"
 
@@ -29,4 +28,5 @@ ROCKETMQCLIENT_API const char* GetLatestErrorMessage();  // Return the last erro
 #ifdef __cplusplus
 }
 #endif
-#endif  //__CERROR_MESSAGE_H__
+
+#endif  // __C_ERROR_MESSAGE_H__
diff --git a/include/CMQException.h b/include/c/CMQException.h
similarity index 99%
rename from include/CMQException.h
rename to include/c/CMQException.h
index 4bdf3d1..7e2f498 100644
--- a/include/CMQException.h
+++ b/include/c/CMQException.h
@@ -16,6 +16,7 @@
  */
 #ifndef __C_MQEXCPTION_H__
 #define __C_MQEXCPTION_H__
+
 #include "CCommon.h"
 
 #ifdef __cplusplus
@@ -25,16 +26,17 @@ extern "C" {
 #define MAX_EXEPTION_MSG_LENGTH 512
 #define MAX_EXEPTION_FILE_LENGTH 256
 #define MAX_EXEPTION_TYPE_LENGTH 128
+
 typedef struct _CMQException_ {
   int error;
   int line;
   char file[MAX_EXEPTION_FILE_LENGTH];
   char msg[MAX_EXEPTION_MSG_LENGTH];
   char type[MAX_EXEPTION_TYPE_LENGTH];
-
 } CMQException;
 
 #ifdef __cplusplus
 }
 #endif
+
 #endif
diff --git a/include/CMessage.h b/include/c/CMessage.h
similarity index 98%
rename from include/CMessage.h
rename to include/c/CMessage.h
index be46435..37feda7 100644
--- a/include/CMessage.h
+++ b/include/c/CMessage.h
@@ -14,9 +14,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 #ifndef __C_MESSAGE_H__
 #define __C_MESSAGE_H__
+
 #include "CCommon.h"
 
 #ifdef __cplusplus
@@ -45,4 +45,5 @@ ROCKETMQCLIENT_API int GetOriginDelayTimeLevel(CMessage* msg);
 #ifdef __cplusplus
 }
 #endif
-#endif  //__C_MESSAGE_H__
+
+#endif  // __C_MESSAGE_H__
diff --git a/include/CMessageExt.h b/include/c/CMessageExt.h
similarity index 98%
rename from include/CMessageExt.h
rename to include/c/CMessageExt.h
index 42d35de..17c0cee 100644
--- a/include/CMessageExt.h
+++ b/include/c/CMessageExt.h
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 #ifndef __C_MESSAGE_EXT_H__
 #define __C_MESSAGE_EXT_H__
 
@@ -46,4 +45,5 @@ ROCKETMQCLIENT_API long long GetMessagePreparedTransactionOffset(CMessageExt* ms
 #ifdef __cplusplus
 }
 #endif
-#endif  //__C_MESSAGE_EXT_H__
+
+#endif  // __C_MESSAGE_EXT_H__
diff --git a/include/CMessageQueue.h b/include/c/CMessageQueue.h
similarity index 97%
rename from include/CMessageQueue.h
rename to include/c/CMessageQueue.h
index 859f71f..bd6da37 100644
--- a/include/CMessageQueue.h
+++ b/include/c/CMessageQueue.h
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 #ifndef __C_MESSAGE_QUEUE_H__
 #define __C_MESSAGE_QUEUE_H__
 
@@ -33,4 +32,5 @@ typedef struct _CMessageQueue_ {
 #ifdef __cplusplus
 }
 #endif
-#endif  //__C_MESSAGE_H__
+
+#endif  // __C_MESSAGE_H__
diff --git a/include/CProducer.h b/include/c/CProducer.h
similarity index 99%
rename from include/CProducer.h
rename to include/c/CProducer.h
index 09b23ba..b70e28e 100644
--- a/include/CProducer.h
+++ b/include/c/CProducer.h
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 #ifndef __C_PRODUCER_H__
 #define __C_PRODUCER_H__
 
@@ -36,6 +35,7 @@ typedef void (*CSendSuccessCallback)(CSendResult result);
 typedef void (*CSendExceptionCallback)(CMQException e);
 typedef void (*COnSendSuccessCallback)(CSendResult result, CMessage* msg, void* userData);
 typedef void (*COnSendExceptionCallback)(CMQException e, CMessage* msg, void* userData);
+
 typedef CTransactionStatus (*CLocalTransactionCheckerCallback)(CProducer* producer, CMessageExt* msg, void* data);
 typedef CTransactionStatus (*CLocalTransactionExecutorCallback)(CProducer* producer, CMessage* msg, void* data);
 
@@ -101,7 +101,9 @@ ROCKETMQCLIENT_API int SendMessageTransaction(CProducer* producer,
                                               CLocalTransactionExecutorCallback callback,
                                               void* userData,
                                               CSendResult* result);
+
 #ifdef __cplusplus
 }
 #endif
-#endif  //__C_PRODUCER_H__
\ No newline at end of file
+
+#endif  // __C_PRODUCER_H__
diff --git a/include/CPullConsumer.h b/include/c/CPullConsumer.h
similarity index 98%
rename from include/CPullConsumer.h
rename to include/c/CPullConsumer.h
index ec96005..41ebbb9 100644
--- a/include/CPullConsumer.h
+++ b/include/c/CPullConsumer.h
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 #ifndef __C_PULL_CONSUMER_H__
 #define __C_PULL_CONSUMER_H__
 
@@ -58,4 +57,5 @@ ROCKETMQCLIENT_API int ReleasePullResult(CPullResult pullResult);
 #ifdef __cplusplus
 }
 #endif
-#endif  //__C_PUSH_CONSUMER_H__
+
+#endif  // __C_PUSH_CONSUMER_H__
diff --git a/include/CPullResult.h b/include/c/CPullResult.h
similarity index 97%
rename from include/CPullResult.h
rename to include/c/CPullResult.h
index 3c5aaac..2f58030 100644
--- a/include/CPullResult.h
+++ b/include/c/CPullResult.h
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 #ifndef __C_PULL_RESULT_H__
 #define __C_PULL_RESULT_H__
 
@@ -24,6 +23,7 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
+
 typedef enum E_CPullStatus {
   E_FOUND,
   E_NO_NEW_MSG,
@@ -45,4 +45,5 @@ typedef struct _CPullResult_ {
 #ifdef __cplusplus
 }
 #endif
-#endif  //__C_PULL_RESULT_H__
+
+#endif  // __C_PULL_RESULT_H__
diff --git a/include/CPushConsumer.h b/include/c/CPushConsumer.h
similarity index 99%
rename from include/CPushConsumer.h
rename to include/c/CPushConsumer.h
index 4880d0f..3754879 100644
--- a/include/CPushConsumer.h
+++ b/include/c/CPushConsumer.h
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 #ifndef __C_PUSH_CONSUMER_H__
 #define __C_PUSH_CONSUMER_H__
 
@@ -62,4 +61,5 @@ ROCKETMQCLIENT_API int SetPushConsumerMaxCacheMessageSizeInMb(CPushConsumer* con
 #ifdef __cplusplus
 }
 #endif
-#endif  //__C_PUSH_CONSUMER_H__
+
+#endif  // __C_PUSH_CONSUMER_H__
diff --git a/include/CSendResult.h b/include/c/CSendResult.h
similarity index 97%
rename from include/CSendResult.h
rename to include/c/CSendResult.h
index 78f21c8..3ac2fcd 100644
--- a/include/CSendResult.h
+++ b/include/c/CSendResult.h
@@ -14,11 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 #ifndef __C_SEND_RESULT_H__
 #define __C_SEND_RESULT_H__
 
 #include "CCommon.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -39,4 +39,5 @@ typedef struct _SendResult_ {
 #ifdef __cplusplus
 }
 #endif
-#endif  //__C_PRODUCER_H__
+
+#endif  // __C_PRODUCER_H__
diff --git a/include/CTransactionStatus.h b/include/c/CTransactionStatus.h
similarity index 96%
rename from include/CTransactionStatus.h
rename to include/c/CTransactionStatus.h
index 435b841..f0bff3c 100644
--- a/include/CTransactionStatus.h
+++ b/include/c/CTransactionStatus.h
@@ -14,13 +14,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 #ifndef __C_TRANSACTION_STATUS_H__
 #define __C_TRANSACTION_STATUS_H__
 
 #ifdef __cplusplus
 extern "C" {
 #endif
+
 typedef enum E_CTransactionStatus {
   E_COMMIT_TRANSACTION = 0,
   E_ROLLBACK_TRANSACTION = 1,
@@ -30,4 +30,5 @@ typedef enum E_CTransactionStatus {
 #ifdef __cplusplus
 }
 #endif
-#endif  //__C_TRANSACTION_STATUS_H__
\ No newline at end of file
+
+#endif  // __C_TRANSACTION_STATUS_H__
diff --git a/libs/signature/CMakeLists.txt b/libs/signature/CMakeLists.txt
index 0348e48..6a2aa1f 100755
--- a/libs/signature/CMakeLists.txt
+++ b/libs/signature/CMakeLists.txt
@@ -18,12 +18,12 @@ project(signature)
 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
 set(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/lib)
 
-aux_source_directory(src/ DIR_LIB_SRCS)
+aux_source_directory(src/  DIR_LIB_SRCS)
 
 add_library(Signature STATIC ${DIR_LIB_SRCS})
 target_link_libraries(Signature ${deplibs})
 set_target_properties(Signature PROPERTIES OUTPUT_NAME "Signature")
 
 # install
-install(TARGETS Signature DESTINATION lib)
+install (TARGETS   Signature             DESTINATION lib)
 #install (DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION include/rocketmq)
diff --git a/libs/signature/include/spas_client.h b/libs/signature/include/spas_client.h
index 7bf6aae..d8262fa 100644
--- a/libs/signature/include/spas_client.h
+++ b/libs/signature/include/spas_client.h
@@ -28,14 +28,10 @@ extern "C" {
 namespace rocketmqSignature {
 #endif
 
-#define SPAS_MAX_KEY_LEN 128 /* max access_key/secret_key length */
-#define SPAS_MAX_PATH 256    /* max credential file path length */
-#define SPAS_ACCESS_KEY_TAG                        \
-  "accessKey" /* access_key tag in credential file \
-                 */
-#define SPAS_SECRET_KEY_TAG                                                        \
-  "secretKey"                                 /* secret_key tag in credential file \
-                                                 */
+#define SPAS_MAX_KEY_LEN 128                  /* max access_key/secret_key length */
+#define SPAS_MAX_PATH 256                     /* max credential file path length */
+#define SPAS_ACCESS_KEY_TAG "accessKey"       /* access_key tag in credential file */
+#define SPAS_SECRET_KEY_TAG "secretKey"       /* secret_key tag in credential file */
 #define SPAS_CREDENTIAL_ENV "SPAS_CREDENTIAL" /* credential file environment variable */
 
 typedef enum {
diff --git a/project/CMakeLists.txt b/project/CMakeLists.txt
index 60b5d0d..074d55f 100755
--- a/project/CMakeLists.txt
+++ b/project/CMakeLists.txt
@@ -16,24 +16,23 @@
 # source files
 project(rocketmq-client)
 
-file(GLOB_RECURSE SRC_FILES ${CMAKE_SOURCE_DIR}/src/*)
-list(REMOVE_ITEM SRC_FILES ${CMAKE_SOURCE_DIR}/src/dllmain.cpp)
+file(GLOB_RECURSE SRC_FILES ${PROJECT_SOURCE_DIR}/../src/*.c*)
+list(REMOVE_ITEM SRC_FILES ${PROJECT_SOURCE_DIR}/../src/dllmain.cpp)
 
 # subdirs
 SET(SUB_DIRS)
-file(GLOB children ${CMAKE_SOURCE_DIR}/src/*)
+file(GLOB children ${PROJECT_SOURCE_DIR}/../src/*)
 FOREACH (child ${children})
     IF (IS_DIRECTORY ${child})
         LIST(APPEND SUB_DIRS ${child})
     ENDIF ()
 ENDFOREACH ()
-LIST(APPEND SUB_DIRS ${CMAKE_SOURCE_DIR}/src)
+LIST(APPEND SUB_DIRS ${PROJECT_SOURCE_DIR}/../src)
 
-include_directories(${CMAKE_SOURCE_DIR}/include)
 include_directories(${SUB_DIRS})
 
 # libs_directories
-file(GLOB LIB_DIRS ${CMAKE_SOURCE_DIR}/libs/*)
+file(GLOB LIB_DIRS ${PROJECT_SOURCE_DIR}/../libs/*)
 foreach (dir ${LIB_DIRS})
     if (IS_DIRECTORY ${dir})
         set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH};${dir})
@@ -43,32 +42,45 @@ endforeach ()
 
 # static
 if (BUILD_ROCKETMQ_STATIC)
-    add_library(rocketmq_static STATIC ${SRC_FILES})
-    set_target_properties(rocketmq_static PROPERTIES OUTPUT_NAME "rocketmq")
-    add_dependencies(rocketmq_static Signature)
-    target_link_libraries(rocketmq_static Signature)
-    target_link_libraries(rocketmq_static ${JSONCPP_LIBRARIES})
-    target_link_libraries(rocketmq_static ${LIBEVENT_LIBRARIES})
-    target_link_libraries(rocketmq_static ${Boost_LIBRARIES})
-    target_link_libraries(rocketmq_static ${deplibs})
+    add_library(rocketmq_static STATIC
+            ${SRC_FILES})
+    target_include_directories(rocketmq_static
+            PUBLIC ${PROJECT_SOURCE_DIR}/../include)
+    if (spdlog_FOUND)
+        target_link_libraries(rocketmq_static
+                PUBLIC ${deplibs} Signature ${JSONCPP_LIBRARIES} ${LIBEVENT_LIBRARIES} spdlog::spdlog)
+    else (spdlog_FOUND)
+        target_link_libraries(rocketmq_static
+                PUBLIC ${deplibs} Signature ${JSONCPP_LIBRARIES} ${LIBEVENT_LIBRARIES})
+    endif (spdlog_FOUND)
+    # set_target_properties(rocketmq_static
+    #         PROPERTIES OUTPUT_NAME "rocketmq")
+
+    include(BundleStaticLibrary)
+    bundle_static_library(rocketmq_static rocketmq)
 endif ()
 
 # shared
 if (BUILD_ROCKETMQ_SHARED)
-    set(CMAKE_SHARED_LINKER_FLAGS "-DBOOST_ALL_DYN_LINK -shared ")
-    add_library(rocketmq_shared SHARED ${SRC_FILES})
-    set_target_properties(rocketmq_shared PROPERTIES OUTPUT_NAME "rocketmq")
-    add_dependencies(rocketmq_shared Signature)
-    target_link_libraries(rocketmq_shared Signature)
-    target_link_libraries(rocketmq_shared ${JSONCPP_LIBRARIES})
-    target_link_libraries(rocketmq_shared ${LIBEVENT_LIBRARIES})
-    target_link_libraries(rocketmq_shared ${Boost_LIBRARIES})
-    target_link_libraries(rocketmq_shared ${deplibs})
+    add_library(rocketmq_shared SHARED
+            ${SRC_FILES})
+    target_include_directories(rocketmq_shared
+            PUBLIC ${PROJECT_SOURCE_DIR}/../include)
+    if (spdlog_FOUND)
+        target_link_libraries(rocketmq_shared
+                PUBLIC ${deplibs} Signature ${JSONCPP_LIBRARIES} ${LIBEVENT_LIBRARIES} spdlog::spdlog)
+    else (spdlog_FOUND)
+        target_link_libraries(rocketmq_shared
+                PUBLIC ${deplibs} Signature ${JSONCPP_LIBRARIES} ${LIBEVENT_LIBRARIES})
+    endif (spdlog_FOUND)
+    set_target_properties(rocketmq_shared
+            PROPERTIES OUTPUT_NAME "rocketmq")
 endif ()
 
 # install
 if (BUILD_ROCKETMQ_STATIC)
     install(TARGETS rocketmq_static DESTINATION lib)
+    install(FILES ${LIBRARY_OUTPUT_PATH}/${CMAKE_STATIC_LIBRARY_PREFIX}rocketmq${CMAKE_STATIC_LIBRARY_SUFFIX} DESTINATION lib)
 endif ()
 if (BUILD_ROCKETMQ_SHARED)
     install(TARGETS rocketmq_shared DESTINATION lib)
diff --git a/src/ClientRemotingProcessor.cpp b/src/ClientRemotingProcessor.cpp
new file mode 100644
index 0000000..a998947
--- /dev/null
+++ b/src/ClientRemotingProcessor.cpp
@@ -0,0 +1,158 @@
+/*
+ * 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 "ClientRemotingProcessor.h"
+
+#include "CommandHeader.h"
+#include "ConsumerRunningInfo.h"
+#include "MQDecoder.h"
+#include "MQProtos.h"
+
+namespace rocketmq {
+
+ClientRemotingProcessor::ClientRemotingProcessor(MQClientInstance* mqClientFactory)
+    : m_mqClientFactory(mqClientFactory) {}
+
+ClientRemotingProcessor::~ClientRemotingProcessor() = default;
+
+RemotingCommand* ClientRemotingProcessor::processRequest(const std::string& addr, RemotingCommand* request) {
+  LOG_DEBUG("request Command received:processRequest, addr:%s, code:%d", addr.data(), request->getCode());
+  switch (request->getCode()) {
+    case CHECK_TRANSACTION_STATE:
+      return checkTransactionState(addr, request);
+      break;
+    case NOTIFY_CONSUMER_IDS_CHANGED:
+      return notifyConsumerIdsChanged(request);
+      break;
+    case RESET_CONSUMER_CLIENT_OFFSET:  // oneWayRPC
+      return resetOffset(request);
+    case GET_CONSUMER_STATUS_FROM_CLIENT:
+      // return getConsumeStatus( request);
+      break;
+    case GET_CONSUMER_RUNNING_INFO:
+      return getConsumerRunningInfo(addr, request);
+      break;
+    case CONSUME_MESSAGE_DIRECTLY:
+      // return consumeMessageDirectly( request);
+      break;
+    default:
+      break;
+  }
+  return nullptr;
+}
+
+RemotingCommand* ClientRemotingProcessor::resetOffset(RemotingCommand* request) {
+  auto* responseHeader = request->decodeCommandCustomHeader<ResetOffsetRequestHeader>();
+  auto requestBody = request->getBody();
+  if (requestBody != nullptr && requestBody->getSize() > 0) {
+    std::unique_ptr<ResetOffsetBody> body(ResetOffsetBody::Decode(*requestBody));
+    if (body != nullptr) {
+      m_mqClientFactory->resetOffset(responseHeader->getGroup(), responseHeader->getTopic(), body->getOffsetTable());
+    } else {
+      LOG_ERROR("resetOffset failed as received data could not be unserialized");
+    }
+  }
+  return nullptr;  // as resetOffset is oneWayRPC, do not need return any response
+}
+
+ResetOffsetBody* ResetOffsetBody::Decode(MemoryBlock& mem) {
+  Json::Value root = RemotingSerializable::fromJson(mem);
+  Json::Value qds = root["offsetTable"];
+  std::unique_ptr<ResetOffsetBody> body(new ResetOffsetBody());
+  for (unsigned int i = 0; i < qds.size(); i++) {
+    Json::Value qd = qds[i];
+    MQMessageQueue mq(qd["brokerName"].asString(), qd["topic"].asString(), qd["queueId"].asInt());
+    int64_t offset = qd["offset"].asInt64();
+    body->setOffsetTable(mq, offset);
+  }
+  return body.release();
+}
+
+std::map<MQMessageQueue, int64_t> ResetOffsetBody::getOffsetTable() {
+  return m_offsetTable;
+}
+
+void ResetOffsetBody::setOffsetTable(const MQMessageQueue& mq, int64_t offset) {
+  m_offsetTable[mq] = offset;
+}
+
+RemotingCommand* ClientRemotingProcessor::getConsumerRunningInfo(const std::string& addr, RemotingCommand* request) {
+  auto* requestHeader = request->decodeCommandCustomHeader<GetConsumerRunningInfoRequestHeader>();
+  LOG_INFO("getConsumerRunningInfo:%s", requestHeader->getConsumerGroup().c_str());
+
+  RemotingCommand* response =
+      new RemotingCommand(request->getCode(), "CPP", request->getVersion(), request->getOpaque(), request->getFlag(),
+                          request->getRemark(), nullptr);
+
+  std::unique_ptr<ConsumerRunningInfo> runningInfo(
+      m_mqClientFactory->consumerRunningInfo(requestHeader->getConsumerGroup()));
+  if (runningInfo != nullptr) {
+    if (requestHeader->isJstackEnable()) {
+      /*string jstack = UtilAll::jstack();
+       consumerRunningInfo->setJstack(jstack);*/
+    }
+    response->setCode(SUCCESS_VALUE);
+    std::string body = runningInfo->encode();
+    response->setBody(body);
+  } else {
+    response->setCode(SYSTEM_ERROR);
+    response->setRemark("The Consumer Group not exist in this consumer");
+  }
+
+  return response;
+}
+
+RemotingCommand* ClientRemotingProcessor::notifyConsumerIdsChanged(RemotingCommand* request) {
+  auto* requestHeader = request->decodeCommandCustomHeader<NotifyConsumerIdsChangedRequestHeader>();
+  LOG_INFO("notifyConsumerIdsChanged:%s", requestHeader->getConsumerGroup().c_str());
+  m_mqClientFactory->rebalanceImmediately();
+  return nullptr;
+}
+
+RemotingCommand* ClientRemotingProcessor::checkTransactionState(const std::string& addr, RemotingCommand* request) {
+  auto* requestHeader = request->decodeCommandCustomHeader<CheckTransactionStateRequestHeader>();
+  assert(requestHeader != nullptr);
+
+  auto requestBody = request->getBody();
+  if (requestBody != nullptr && requestBody->getSize() > 0) {
+    MQMessageExtPtr2 messageExt = MQDecoder::decode(*requestBody);
+    if (messageExt != nullptr) {
+      const auto& transactionId = messageExt->getProperty(MQMessageConst::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX);
+      if (!transactionId.empty()) {
+        messageExt->setTransactionId(transactionId);
+      }
+      const auto& group = messageExt->getProperty(MQMessageConst::PROPERTY_PRODUCER_GROUP);
+      if (!group.empty()) {
+        auto* producer = m_mqClientFactory->selectProducer(group);
+        if (producer != nullptr) {
+          producer->checkTransactionState(addr, messageExt, requestHeader);
+        } else {
+          LOG_DEBUG_NEW("checkTransactionState, pick producer by group[{}] failed", group);
+        }
+      } else {
+        LOG_WARN_NEW("checkTransactionState, pick producer group failed");
+      }
+    } else {
+      LOG_WARN_NEW("checkTransactionState, decode message failed");
+    }
+  } else {
+    LOG_ERROR_NEW("checkTransactionState, request body is empty, request header: {}", requestHeader->toString());
+  }
+
+  return nullptr;
+}
+
+}  // namespace rocketmq
diff --git a/src/ClientRemotingProcessor.h b/src/ClientRemotingProcessor.h
new file mode 100644
index 0000000..efcb5fc
--- /dev/null
+++ b/src/ClientRemotingProcessor.h
@@ -0,0 +1,55 @@
+/*
+ * 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 __CLIENT_REMOTING_PROCESSOR_H__
+#define __CLIENT_REMOTING_PROCESSOR_H__
+
+#include "MQClientInstance.h"
+#include "MQMessageQueue.h"
+#include "RequestProcessor.h"
+
+namespace rocketmq {
+
+class ClientRemotingProcessor : public RequestProcessor {
+ public:
+  ClientRemotingProcessor(MQClientInstance* mqClientFactory);
+  virtual ~ClientRemotingProcessor();
+
+  RemotingCommand* processRequest(const std::string& addr, RemotingCommand* request) override;
+
+  RemotingCommand* resetOffset(RemotingCommand* request);
+  RemotingCommand* getConsumerRunningInfo(const std::string& addr, RemotingCommand* request);
+  RemotingCommand* notifyConsumerIdsChanged(RemotingCommand* request);
+  RemotingCommand* checkTransactionState(const std::string& addr, RemotingCommand* request);
+
+ private:
+  MQClientInstance* m_mqClientFactory;
+};
+
+class ResetOffsetBody {
+ public:
+  static ResetOffsetBody* Decode(MemoryBlock& mem);
+
+  std::map<MQMessageQueue, int64_t> getOffsetTable();
+  void setOffsetTable(const MQMessageQueue& mq, int64_t offset);
+
+ private:
+  std::map<MQMessageQueue, int64_t> m_offsetTable;
+};
+
+}  // namespace rocketmq
+
+#endif  // __CLIENT_REMOTING_PROCESSOR_H__
diff --git a/src/MQAdminImpl.cpp b/src/MQAdminImpl.cpp
new file mode 100644
index 0000000..ea0651f
--- /dev/null
+++ b/src/MQAdminImpl.cpp
@@ -0,0 +1,136 @@
+/*
+ * 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 "MQAdminImpl.h"
+
+#include "MQClientAPIImpl.h"
+#include "MQClientInstance.h"
+#include "TopicPublishInfo.h"
+
+namespace rocketmq {
+
+void MQAdminImpl::createTopic(const std::string& key, const std::string& newTopic, int queueNum) {}
+
+void MQAdminImpl::fetchSubscribeMessageQueues(const std::string& topic, std::vector<MQMessageQueue>& mqs) {
+  try {
+    TopicRouteDataPtr topicRouteData(
+        m_mqClientFactory->getMQClientAPIImpl()->getTopicRouteInfoFromNameServer(topic, 1000 * 3));
+    if (topicRouteData != nullptr) {
+      mqs = m_mqClientFactory->topicRouteData2TopicSubscribeInfo(topic, topicRouteData);
+      if (!mqs.empty()) {
+        return;
+      } else {
+        THROW_MQEXCEPTION(MQClientException,
+                          "Can not find Message Queue for this topic, " + topic + " Namesrv return empty", -1);
+      }
+    }
+  } catch (const std::exception& e) {
+    THROW_MQEXCEPTION(MQClientException, "Can not find Message Queue for this topic, " + topic, -1);
+  }
+
+  THROW_MQEXCEPTION(MQClientException, "Unknown why, Can not find Message Queue for this topic, " + topic, -1);
+}
+
+int64_t MQAdminImpl::searchOffset(const MQMessageQueue& mq, int64_t timestamp) {
+  std::string brokerAddr = m_mqClientFactory->findBrokerAddressInPublish(mq.getBrokerName());
+  if (brokerAddr.empty()) {
+    m_mqClientFactory->updateTopicRouteInfoFromNameServer(mq.getTopic());
+    brokerAddr = m_mqClientFactory->findBrokerAddressInPublish(mq.getBrokerName());
+  }
+
+  if (!brokerAddr.empty()) {
+    try {
+      return m_mqClientFactory->getMQClientAPIImpl()->searchOffset(brokerAddr, mq.getTopic(), mq.getQueueId(),
+                                                                   timestamp, 1000 * 3);
+    } catch (MQException& e) {
+      THROW_MQEXCEPTION(MQClientException, "Invoke Broker exception", -1);
+    }
+  }
+  THROW_MQEXCEPTION(MQClientException, "The broker is not exist", -1);
+}
+
+int64_t MQAdminImpl::maxOffset(const MQMessageQueue& mq) {
+  std::string brokerAddr = m_mqClientFactory->findBrokerAddressInPublish(mq.getBrokerName());
+  if (brokerAddr.empty()) {
+    m_mqClientFactory->updateTopicRouteInfoFromNameServer(mq.getTopic());
+    brokerAddr = m_mqClientFactory->findBrokerAddressInPublish(mq.getBrokerName());
+  }
+
+  if (!brokerAddr.empty()) {
+    try {
+      return m_mqClientFactory->getMQClientAPIImpl()->getMaxOffset(brokerAddr, mq.getTopic(), mq.getQueueId(),
+                                                                   1000 * 3);
+    } catch (MQException& e) {
+      THROW_MQEXCEPTION(MQClientException, "Invoke Broker exception", -1);
+    }
+  }
+  THROW_MQEXCEPTION(MQClientException, "The broker is not exist", -1);
+}
+
+int64_t MQAdminImpl::minOffset(const MQMessageQueue& mq) {
+  std::string brokerAddr = m_mqClientFactory->findBrokerAddressInPublish(mq.getBrokerName());
+  if (brokerAddr.empty()) {
+    m_mqClientFactory->updateTopicRouteInfoFromNameServer(mq.getTopic());
+    brokerAddr = m_mqClientFactory->findBrokerAddressInPublish(mq.getBrokerName());
+  }
+
+  if (!brokerAddr.empty()) {
+    try {
+      return m_mqClientFactory->getMQClientAPIImpl()->getMinOffset(brokerAddr, mq.getTopic(), mq.getQueueId(),
+                                                                   1000 * 3);
+    } catch (const std::exception& e) {
+      THROW_MQEXCEPTION(MQClientException, "Invoke Broker[" + brokerAddr + "] exception", -1);
+    }
+  }
+
+  THROW_MQEXCEPTION(MQClientException, "The broker[" + mq.getBrokerName() + "] not exist", -1);
+}
+
+int64_t MQAdminImpl::earliestMsgStoreTime(const MQMessageQueue& mq) {
+  std::string brokerAddr = m_mqClientFactory->findBrokerAddressInPublish(mq.getBrokerName());
+  if (brokerAddr.empty()) {
+    m_mqClientFactory->updateTopicRouteInfoFromNameServer(mq.getTopic());
+    brokerAddr = m_mqClientFactory->findBrokerAddressInPublish(mq.getBrokerName());
+  }
+
+  if (!brokerAddr.empty()) {
+    try {
+      return m_mqClientFactory->getMQClientAPIImpl()->getEarliestMsgStoretime(brokerAddr, mq.getTopic(),
+                                                                              mq.getQueueId(), 1000 * 3);
+    } catch (MQException& e) {
+      THROW_MQEXCEPTION(MQClientException, "Invoke Broker exception", -1);
+    }
+  }
+  THROW_MQEXCEPTION(MQClientException, "The broker is not exist", -1);
+}
+
+MQMessageExtPtr MQAdminImpl::viewMessage(const std::string& msgId) {
+  try {
+    return nullptr;
+  } catch (MQException& e) {
+    THROW_MQEXCEPTION(MQClientException, "message id illegal", -1);
+  }
+}
+
+QueryResult MQAdminImpl::queryMessage(const std::string& topic,
+                                      const std::string& key,
+                                      int maxNum,
+                                      int64_t begin,
+                                      int64_t end) {
+  THROW_MQEXCEPTION(MQClientException, "queryMessage", -1);
+}
+
+}  // namespace rocketmq
diff --git a/src/MQAdminImpl.h b/src/MQAdminImpl.h
new file mode 100644
index 0000000..244d9a3
--- /dev/null
+++ b/src/MQAdminImpl.h
@@ -0,0 +1,52 @@
+/*
+ * 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 __MQ_ADMIN_IMPL_H___
+#define __MQ_ADMIN_IMPL_H___
+
+#include <string>
+#include <vector>
+
+#include "MQClientInstance.h"
+#include "MQMessageExt.h"
+#include "MQMessageQueue.h"
+#include "QueryResult.h"
+
+namespace rocketmq {
+
+class MQAdminImpl {
+ public:
+  MQAdminImpl(MQClientInstance* mqClientFactory) : m_mqClientFactory(mqClientFactory) {}
+
+  void createTopic(const std::string& key, const std::string& newTopic, int queueNum);
+
+  void fetchSubscribeMessageQueues(const std::string& topic, std::vector<MQMessageQueue>& mqs);
+
+  int64_t searchOffset(const MQMessageQueue& mq, int64_t timestamp);
+  int64_t maxOffset(const MQMessageQueue& mq);
+  int64_t minOffset(const MQMessageQueue& mq);
+  int64_t earliestMsgStoreTime(const MQMessageQueue& mqClientFactory);
+
+  MQMessageExtPtr viewMessage(const std::string& msgId);
+  QueryResult queryMessage(const std::string& topic, const std::string& key, int maxNum, int64_t begin, int64_t end);
+
+ private:
+  MQClientInstance* m_mqClientFactory;
+};
+
+}  // namespace rocketmq
+
+#endif  // __MQ_ADMIN_IMPL_H___
diff --git a/src/MQClientAPIImpl.cpp b/src/MQClientAPIImpl.cpp
index f2829a9..22d937a 100644
--- a/src/MQClientAPIImpl.cpp
+++ b/src/MQClientAPIImpl.cpp
@@ -14,537 +14,262 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 #include "MQClientAPIImpl.h"
-#include <assert.h>
-#include <boost/filesystem.hpp>
-#include <boost/filesystem/fstream.hpp>
-#include <fstream>
-#include "CommunicationMode.h"
-#include "Logging.h"
-#include "MQDecoder.h"
-#include "PullResultExt.h"
 
-namespace rocketmq {
-//<!************************************************************************
-MQClientAPIImpl::MQClientAPIImpl(const string& mqClientId,
-                                 ClientRemotingProcessor* clientRemotingProcessor,
-                                 int pullThreadNum,
-                                 uint64_t tcpConnectTimeout,
-                                 uint64_t tcpTransportTryLockTimeout,
-                                 string unitName)
-    : m_firstFetchNameSrv(true), m_mqClientId(mqClientId) {
-  m_pRemotingClient.reset(new TcpRemotingClient(pullThreadNum, tcpConnectTimeout, tcpTransportTryLockTimeout));
-  m_pRemotingClient->registerProcessor(CHECK_TRANSACTION_STATE, clientRemotingProcessor);
-  m_pRemotingClient->registerProcessor(RESET_CONSUMER_CLIENT_OFFSET, clientRemotingProcessor);
-  m_pRemotingClient->registerProcessor(GET_CONSUMER_STATUS_FROM_CLIENT, clientRemotingProcessor);
-  m_pRemotingClient->registerProcessor(GET_CONSUMER_RUNNING_INFO, clientRemotingProcessor);
-  m_pRemotingClient->registerProcessor(NOTIFY_CONSUMER_IDS_CHANGED, clientRemotingProcessor);
-  m_pRemotingClient->registerProcessor(CONSUME_MESSAGE_DIRECTLY, clientRemotingProcessor);
-
-  m_topAddressing.reset(new TopAddressing(unitName));
-}
-
-MQClientAPIImpl::~MQClientAPIImpl() {
-  m_pRemotingClient = NULL;
-  m_topAddressing = NULL;
-}
-
-void MQClientAPIImpl::stopAllTcpTransportThread() {
-  m_pRemotingClient->stopAllTcpTransportThread();
-}
-
-bool MQClientAPIImpl::writeDataToFile(string filename, string data, bool isSync) {
-  if (data.size() == 0)
-    return false;
-
-  FILE* pFd = fopen(filename.c_str(), "w+");
-  if (NULL == pFd) {
-    LOG_ERROR("fopen failed, filename:%s", filename.c_str());
-    return false;
-  }
+#include <cassert>
+#include <cstring>
+#include <typeindex>
 
-  int byte_write = 0;
-  int byte_left = data.size();
-  const char* pData = data.c_str();
-  while (byte_left > 0) {
-    byte_write = fwrite(pData, sizeof(char), byte_left, pFd);
-    if (byte_write == byte_left) {
-      if (ferror(pFd)) {
-        LOG_ERROR("write data fail, data len:" SIZET_FMT ", file:%s, msg:%s", data.size(), filename.c_str(),
-                  strerror(errno));
-        fclose(pFd);
-        return false;
-      }
-    }
-    byte_left -= byte_write;
-    pData += byte_write;
-  }
-  pData = NULL;
+#include "ClientRemotingProcessor.h"
+#include "MQClientInstance.h"
+#include "MessageBatch.h"
+#include "MessageClientIDSetter.h"
+#include "PullCallbackWrap.h"
+#include "PullResultExt.h"
+#include "SendCallbackWrap.h"
+#include "TcpRemotingClient.h"
 
-  if (isSync) {
-    LOG_INFO("fsync with filename:%s", filename.c_str());
-    fflush(pFd);
-  }
-  fclose(pFd);
+namespace rocketmq {
 
-  return true;
+MQClientAPIImpl::MQClientAPIImpl(ClientRemotingProcessor* clientRemotingProcessor,
+                                 std::shared_ptr<RPCHook> rpcHook,
+                                 const MQClientConfig* clientConfig)
+    : m_remotingClient(new TcpRemotingClient(clientConfig->getTcpTransportWorkerThreadNum(),
+                                             clientConfig->getTcpTransportConnectTimeout(),
+                                             clientConfig->getTcpTransportTryLockTimeout())) {
+  m_remotingClient->registerRPCHook(rpcHook);
+  m_remotingClient->registerProcessor(CHECK_TRANSACTION_STATE, clientRemotingProcessor);
+  m_remotingClient->registerProcessor(RESET_CONSUMER_CLIENT_OFFSET, clientRemotingProcessor);
+  m_remotingClient->registerProcessor(GET_CONSUMER_STATUS_FROM_CLIENT, clientRemotingProcessor);
+  m_remotingClient->registerProcessor(GET_CONSUMER_RUNNING_INFO, clientRemotingProcessor);
+  m_remotingClient->registerProcessor(NOTIFY_CONSUMER_IDS_CHANGED, clientRemotingProcessor);
+  m_remotingClient->registerProcessor(CONSUME_MESSAGE_DIRECTLY, clientRemotingProcessor);
 }
 
-string MQClientAPIImpl::fetchNameServerAddr(const string& NSDomain) {
-  try {
-    string homeDir(UtilAll::getHomeDirectory());
-    string storePath = homeDir + "/logs/rocketmq-cpp/snapshot";
-
-    boost::filesystem::path dir(storePath);
-    boost::system::error_code ec;
-    if (!boost::filesystem::exists(dir, ec)) {
-      if (!boost::filesystem::create_directory(dir, ec)) {
-        LOG_ERROR("create data dir:%s error", storePath.c_str());
-        return "";
-      }
-    }
-    string file(storePath);
-    string fileBak(storePath);
-    vector<string> ret_;
-    int retSize = UtilAll::Split(ret_, m_mqClientId, "@");
-    if (retSize == 2) {
-      file.append("/nameserver_addr-").append(ret_[retSize - 1]);
-    } else {
-      LOG_ERROR("split mqClientId:%s fail", m_mqClientId.c_str());
-      file.append("/nameserver_addr-DEFAULT");
-    }
-    boost::filesystem::path snapshot_file(file);
-    fileBak.append("/nameserver_addr.bak");
-    const string addrs = m_topAddressing->fetchNSAddr(NSDomain);
-    if (addrs.empty()) {
-      if (m_nameSrvAddr.empty()) {
-        LOG_INFO("Load the name server snapshot local file:%s", file.c_str());
-        if (boost::filesystem::exists(snapshot_file)) {
-          ifstream snapshot_file(file, ios::binary);
-          istreambuf_iterator<char> beg(snapshot_file), end;
-          string filecontent(beg, end);
-          updateNameServerAddr(filecontent);
-          m_nameSrvAddr = filecontent;
-        } else {
-          LOG_WARN("The name server snapshot local file not exists");
-        }
-      }
-    } else {
-      if (m_firstFetchNameSrv == true) {
-        // it is the first time, so need to create the name server snapshot
-        // local file
-        m_firstFetchNameSrv = false;
-      }
-      if (addrs.compare(m_nameSrvAddr) != 0) {
-        LOG_INFO("name server address changed, old: %s, new: %s", m_nameSrvAddr.c_str(), addrs.c_str());
-        updateNameServerAddr(addrs);
-        m_nameSrvAddr = addrs;
-      } else {
-        if (!m_firstFetchNameSrv)
-          return m_nameSrvAddr;
-      }
-      // update the snapshot local file if nameSrv changes or
-      // m_firstFetchNameSrv==true
-      if (writeDataToFile(fileBak, addrs, true)) {
-        if (!UtilAll::ReplaceFile(fileBak, file))
-          LOG_ERROR("could not rename bak file:%s", strerror(errno));
-      }
-    }
+MQClientAPIImpl::~MQClientAPIImpl() = default;
 
-    if (!boost::filesystem::exists(snapshot_file)) {
-      // the name server snapshot local file maybe deleted by force, create it
-      if (writeDataToFile(fileBak, m_nameSrvAddr, true)) {
-        if (!UtilAll::ReplaceFile(fileBak, file))
-          LOG_ERROR("could not rename bak file:%s", strerror(errno));
-      }
-    }
-  } catch (...) {
-  }
-  return m_nameSrvAddr;
+void MQClientAPIImpl::start() {
+  m_remotingClient->start();
 }
 
-void MQClientAPIImpl::updateNameServerAddr(const string& addrs) {
-  if (m_pRemotingClient != NULL)
-    m_pRemotingClient->updateNameServerAddressList(addrs);
+void MQClientAPIImpl::shutdown() {
+  m_remotingClient->shutdown();
 }
 
-void MQClientAPIImpl::callSignatureBeforeRequest(const string& addr,
-                                                 RemotingCommand& request,
-                                                 const SessionCredentials& session_credentials) {
-  ClientRPCHook rpcHook(session_credentials);
-  rpcHook.doBeforeRequest(addr, request);
+void MQClientAPIImpl::updateNameServerAddr(const std::string& addrs) {
+  if (m_remotingClient != nullptr) {
+    m_remotingClient->updateNameServerAddressList(addrs);
+  }
 }
 
-// Note: all request rules: throw exception if got broker error response,
-// exclude getTopicRouteInfoFromNameServer and unregisterClient
-void MQClientAPIImpl::createTopic(const string& addr,
-                                  const string& defaultTopic,
-                                  TopicConfig topicConfig,
-                                  const SessionCredentials& sessionCredentials) {
-  string topicWithProjectGroup = topicConfig.getTopicName();
+void MQClientAPIImpl::createTopic(const std::string& addr, const std::string& defaultTopic, TopicConfig topicConfig) {
   CreateTopicRequestHeader* requestHeader = new CreateTopicRequestHeader();
-  requestHeader->topic = (topicWithProjectGroup);
-  requestHeader->defaultTopic = (defaultTopic);
-  requestHeader->readQueueNums = (topicConfig.getReadQueueNums());
-  requestHeader->writeQueueNums = (topicConfig.getWriteQueueNums());
-  requestHeader->perm = (topicConfig.getPerm());
-  requestHeader->topicFilterType = (topicConfig.getTopicFilterType());
+  requestHeader->topic = topicConfig.getTopicName();
+  requestHeader->defaultTopic = defaultTopic;
+  requestHeader->readQueueNums = topicConfig.getReadQueueNums();
+  requestHeader->writeQueueNums = topicConfig.getWriteQueueNums();
+  requestHeader->perm = topicConfig.getPerm();
+  requestHeader->topicFilterType = topicConfig.getTopicFilterType();
 
   RemotingCommand request(UPDATE_AND_CREATE_TOPIC, requestHeader);
-  callSignatureBeforeRequest(addr, request, sessionCredentials);
-  request.Encode();
 
-  unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request));
-
-  if (response) {
-    switch (response->getCode()) {
-      case SUCCESS_VALUE:
-        return;
-      default:
-        break;
+  std::unique_ptr<RemotingCommand> response(m_remotingClient->invokeSync(addr, request));
+  assert(response != nullptr);
+  switch (response->getCode()) {
+    case SUCCESS_VALUE: {
+      return;
     }
-    THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
+    default:
+      break;
   }
-  THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
+
+  THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
 }
 
-void MQClientAPIImpl::endTransactionOneway(std::string addr,
-                                           EndTransactionRequestHeader* requestHeader,
-                                           std::string remark,
-                                           const SessionCredentials& sessionCredentials) {
-  RemotingCommand request(END_TRANSACTION, requestHeader);
-  request.setRemark(remark);
-  callSignatureBeforeRequest(addr, request, sessionCredentials);
-  request.Encode();
-  m_pRemotingClient->invokeOneway(addr, request);
-  return;
-}
-
-SendResult MQClientAPIImpl::sendMessage(const string& addr,
-                                        const string& brokerName,
-                                        const MQMessage& msg,
-                                        SendMessageRequestHeader* pRequestHeader,
-                                        int timeoutMillis,
-                                        int maxRetrySendTimes,
-                                        int communicationMode,
-                                        SendCallback* pSendCallback,
-                                        const SessionCredentials& sessionCredentials) {
-  // RemotingCommand request(SEND_MESSAGE, pRequestHeader);
-  // Using MQ V2 Protocol to end messages.
-  SendMessageRequestHeaderV2* pRequestHeaderV2 = new SendMessageRequestHeaderV2(*pRequestHeader);
-  RemotingCommand request(SEND_MESSAGE_V2, pRequestHeaderV2);
-  delete pRequestHeader;  // delete to avoid memory leak.
-  string body = msg.getBody();
-  request.SetBody(body.c_str(), body.length());
-  request.setMsgBody(body);
-  callSignatureBeforeRequest(addr, request, sessionCredentials);
-  request.Encode();
+SendResult* MQClientAPIImpl::sendMessage(const std::string& addr,
+                                         const std::string& brokerName,
+                                         const MQMessagePtr msg,
+                                         std::unique_ptr<SendMessageRequestHeader> requestHeader,
+                                         int timeoutMillis,
+                                         CommunicationMode communicationMode,
+                                         DefaultMQProducerImplPtr producer) {
+  return sendMessage(addr, brokerName, msg, std::move(requestHeader), timeoutMillis, communicationMode, nullptr,
+                     nullptr, nullptr, 0, producer);
+}
+
+SendResult* MQClientAPIImpl::sendMessage(const std::string& addr,
+                                         const std::string& brokerName,
+                                         const MQMessagePtr msg,
+                                         std::unique_ptr<SendMessageRequestHeader> requestHeader,
+                                         int timeoutMillis,
+                                         CommunicationMode communicationMode,
+                                         SendCallback* sendCallback,
+                                         TopicPublishInfoPtr topicPublishInfo,
+                                         MQClientInstancePtr instance,
+                                         int retryTimesWhenSendFailed,
+                                         DefaultMQProducerImplPtr producer) {
+  int code = SEND_MESSAGE;
+  std::unique_ptr<CommandCustomHeader> header;
+
+  if (msg->isBatch()) {
+    code = SEND_BATCH_MESSAGE;
+    header.reset(SendMessageRequestHeaderV2::createSendMessageRequestHeaderV2(requestHeader.get()));
+  } else {
+    header = std::move(requestHeader);
+  }
+
+  RemotingCommand request(code, header.release());
+  request.setBody(msg->getBody());
 
   switch (communicationMode) {
     case ComMode_ONEWAY:
-      m_pRemotingClient->invokeOneway(addr, request);
-      break;
+      m_remotingClient->invokeOneway(addr, request);
+      return nullptr;
     case ComMode_ASYNC:
-      sendMessageAsync(addr, brokerName, msg, request, pSendCallback, timeoutMillis, maxRetrySendTimes, 1);
-      break;
+      sendMessageAsync(addr, brokerName, msg, std::move(request), sendCallback, topicPublishInfo, instance,
+                       timeoutMillis, retryTimesWhenSendFailed, producer);
+      return nullptr;
     case ComMode_SYNC:
       return sendMessageSync(addr, brokerName, msg, request, timeoutMillis);
     default:
+      assert(false);
       break;
   }
-  return SendResult();
-}
-
-void MQClientAPIImpl::sendHeartbeat(const string& addr,
-                                    HeartbeatData* pHeartbeatData,
-                                    const SessionCredentials& sessionCredentials) {
-  RemotingCommand request(HEART_BEAT, NULL);
 
-  string body;
-  pHeartbeatData->Encode(body);
-  request.SetBody(body.data(), body.length());
-  request.setMsgBody(body);
-  callSignatureBeforeRequest(addr, request, sessionCredentials);
-  request.Encode();
-
-  if (m_pRemotingClient->invokeHeartBeat(addr, request)) {
-    LOG_DEBUG("sendHeartbeat to broker:%s success", addr.c_str());
-  } else {
-    LOG_WARN("sendHeartbeat to broker:%s failed", addr.c_str());
-  }
+  return nullptr;
 }
 
-void MQClientAPIImpl::unregisterClient(const string& addr,
-                                       const string& clientID,
-                                       const string& producerGroup,
-                                       const string& consumerGroup,
-                                       const SessionCredentials& sessionCredentials) {
-  LOG_INFO("unregisterClient to broker:%s", addr.c_str());
-  RemotingCommand request(UNREGISTER_CLIENT, new UnregisterClientRequestHeader(clientID, producerGroup, consumerGroup));
-  callSignatureBeforeRequest(addr, request, sessionCredentials);
-  request.Encode();
+void MQClientAPIImpl::sendMessageAsync(const std::string& addr,
+                                       const std::string& brokerName,
+                                       const MQMessagePtr msg,
+                                       RemotingCommand&& request,
+                                       SendCallback* sendCallback,
+                                       TopicPublishInfoPtr topicPublishInfo,
+                                       MQClientInstancePtr instance,
+                                       int64_t timeoutMillis,
+                                       int retryTimesWhenSendFailed,
+                                       DefaultMQProducerImplPtr producer) throw(RemotingException) {
+  // delete in future
+  auto cbw = new SendCallbackWrap(addr, brokerName, msg, std::forward<RemotingCommand>(request), sendCallback,
+                                  topicPublishInfo, instance, retryTimesWhenSendFailed, 0, producer);
 
-  unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request));
-
-  if (response) {
-    switch (response->getCode()) {
-      case SUCCESS_VALUE:
-        LOG_INFO("unregisterClient to:%s success", addr.c_str());
-        return;
-      default:
-        break;
-    }
-    LOG_WARN("unregisterClient fail:%s,%d", response->getRemark().c_str(), response->getCode());
+  try {
+    sendMessageAsyncImpl(cbw, timeoutMillis);
+  } catch (RemotingException& e) {
+    deleteAndZero(cbw);
+    throw e;
   }
 }
 
-// return NULL if got no response or error response
-TopicRouteData* MQClientAPIImpl::getTopicRouteInfoFromNameServer(const string& topic,
-                                                                 int timeoutMillis,
-                                                                 const SessionCredentials& sessionCredentials) {
-  RemotingCommand request(GET_ROUTEINTO_BY_TOPIC, new GetRouteInfoRequestHeader(topic));
-  callSignatureBeforeRequest("", request, sessionCredentials);
-  request.Encode();
-
-  unique_ptr<RemotingCommand> pResponse(m_pRemotingClient->invokeSync("", request, timeoutMillis));
-
-  if (pResponse != NULL) {
-    if (((*(pResponse->GetBody())).getSize() == 0) || ((*(pResponse->GetBody())).getData() != NULL)) {
-      switch (pResponse->getCode()) {
-        case SUCCESS_VALUE: {
-          const MemoryBlock* pbody = pResponse->GetBody();
-          if (pbody->getSize()) {
-            TopicRouteData* topicRoute = TopicRouteData::Decode(pbody);
-            return topicRoute;
-          }
-        }
-        case TOPIC_NOT_EXIST: {
-          LOG_WARN("Get topic[%s] route failed [TOPIC_NOT_EXIST].", topic.c_str());
-          return NULL;
-        }
-        default:
-          break;
-      }
-      LOG_WARN("%s,%d", pResponse->getRemark().c_str(), pResponse->getCode());
-      return NULL;
-    }
-  }
-  LOG_WARN("Get topic[%s] route failed [Null Response].", topic.c_str());
-  return NULL;
-}
-
-TopicList* MQClientAPIImpl::getTopicListFromNameServer(const SessionCredentials& sessionCredentials) {
-  RemotingCommand request(GET_ALL_TOPIC_LIST_FROM_NAMESERVER, NULL);
-  callSignatureBeforeRequest("", request, sessionCredentials);
-  request.Encode();
-
-  unique_ptr<RemotingCommand> pResponse(m_pRemotingClient->invokeSync("", request));
-  if (pResponse != NULL) {
-    if (((*(pResponse->GetBody())).getSize() == 0) || ((*(pResponse->GetBody())).getData() != NULL)) {
-      switch (pResponse->getCode()) {
-        case SUCCESS_VALUE: {
-          const MemoryBlock* pbody = pResponse->GetBody();
-          if (pbody->getSize()) {
-            TopicList* topicList = TopicList::Decode(pbody);
-            return topicList;
-          }
-        }
-        default:
-          break;
-      }
-
-      THROW_MQEXCEPTION(MQClientException, pResponse->getRemark(), pResponse->getCode());
-    }
-  }
-  return NULL;
+void MQClientAPIImpl::sendMessageAsyncImpl(SendCallbackWrap* cbw, int64_t timeoutMillis) throw(RemotingException) {
+  const auto& addr = cbw->getAddr();
+  auto& request = cbw->getRemotingCommand();
+  m_remotingClient->invokeAsync(addr, request, cbw, timeoutMillis);
 }
 
-int MQClientAPIImpl::wipeWritePermOfBroker(const string& namesrvAddr, const string& brokerName, int timeoutMillis) {
-  return 0;
+SendResult* MQClientAPIImpl::sendMessageSync(const std::string& addr,
+                                             const std::string& brokerName,
+                                             const MQMessagePtr msg,
+                                             RemotingCommand& request,
+                                             int timeoutMillis) {
+  // block until response
+  std::unique_ptr<RemotingCommand> response(m_remotingClient->invokeSync(addr, request, timeoutMillis));
+  assert(response != nullptr);
+  return processSendResponse(brokerName, msg, response.get());
 }
 
-void MQClientAPIImpl::deleteTopicInBroker(const string& addr, const string& topic, int timeoutMillis) {}
-
-void MQClientAPIImpl::deleteTopicInNameServer(const string& addr, const string& topic, int timeoutMillis) {}
-
-void MQClientAPIImpl::deleteSubscriptionGroup(const string& addr, const string& groupName, int timeoutMillis) {}
-
-string MQClientAPIImpl::getKVConfigByValue(const string& projectNamespace,
-                                           const string& projectGroup,
-                                           int timeoutMillis) {
-  return "";
-}
+SendResult* MQClientAPIImpl::processSendResponse(const std::string& brokerName,
+                                                 const MQMessagePtr msg,
+                                                 RemotingCommand* response) {
+  SendStatus sendStatus = SEND_OK;
+  switch (response->getCode()) {
+    case FLUSH_DISK_TIMEOUT:
+      sendStatus = SEND_FLUSH_DISK_TIMEOUT;
+      break;
+    case FLUSH_SLAVE_TIMEOUT:
+      sendStatus = SEND_FLUSH_SLAVE_TIMEOUT;
+      break;
+    case SLAVE_NOT_AVAILABLE:
+      sendStatus = SEND_SLAVE_NOT_AVAILABLE;
+      break;
+    case SUCCESS_VALUE:
+      sendStatus = SEND_OK;
+      break;
+    default:
+      THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
+      return nullptr;
+  }
 
-KVTable MQClientAPIImpl::getKVListByNamespace(const string& projectNamespace, int timeoutMillis) {
-  return KVTable();
-}
+  auto* responseHeader = response->decodeCommandCustomHeader<SendMessageResponseHeader>();
+  assert(responseHeader != nullptr);
 
-void MQClientAPIImpl::deleteKVConfigByValue(const string& projectNamespace,
-                                            const string& projectGroup,
-                                            int timeoutMillis) {}
+  MQMessageQueue messageQueue(msg->getTopic(), brokerName, responseHeader->queueId);
 
-SendResult MQClientAPIImpl::sendMessageSync(const string& addr,
-                                            const string& brokerName,
-                                            const MQMessage& msg,
-                                            RemotingCommand& request,
-                                            int timeoutMillis) {
-  //<!block util response;
-  unique_ptr<RemotingCommand> pResponse(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
-  if (pResponse != NULL) {
-    try {
-      SendResult result = processSendResponse(brokerName, msg, pResponse.get());
-      LOG_DEBUG("sendMessageSync success:%s to addr:%s,brokername:%s, send status:%d", msg.toString().c_str(),
-                addr.c_str(), brokerName.c_str(), (int)result.getSendStatus());
-      return result;
-    } catch (...) {
-      LOG_ERROR("send error");
-    }
-  }
-  THROW_MQEXCEPTION(MQClientException, "response is null", -1);
-}
+  std::string uniqMsgId = MessageClientIDSetter::getUniqID(*msg);
 
-void MQClientAPIImpl::sendMessageAsync(const string& addr,
-                                       const string& brokerName,
-                                       const MQMessage& msg,
-                                       RemotingCommand& request,
-                                       SendCallback* pSendCallback,
-                                       int64 timeoutMilliseconds,
-                                       int maxRetryTimes,
-                                       int retrySendTimes) {
-  int64 begin_time = UtilAll::currentTimeMillis();
-  //<!delete in future;
-  AsyncCallbackWrap* cbw = new SendCallbackWrap(brokerName, msg, pSendCallback, this);
-
-  LOG_DEBUG("sendMessageAsync request:%s, timeout:%lld, maxRetryTimes:%d retrySendTimes:%d", request.ToString().data(),
-            timeoutMilliseconds, maxRetryTimes, retrySendTimes);
-
-  if (m_pRemotingClient->invokeAsync(addr, request, cbw, timeoutMilliseconds, maxRetryTimes, retrySendTimes) == false) {
-    LOG_WARN("invokeAsync failed to addr:%s,topic:%s, timeout:%lld, maxRetryTimes:%d, retrySendTimes:%d", addr.c_str(),
-             msg.getTopic().data(), timeoutMilliseconds, maxRetryTimes, retrySendTimes);
-    // when getTcp return false, need consider retrySendTimes
-    int retry_time = retrySendTimes + 1;
-    int64 time_out = timeoutMilliseconds - (UtilAll::currentTimeMillis() - begin_time);
-    while (retry_time < maxRetryTimes && time_out > 0) {
-      begin_time = UtilAll::currentTimeMillis();
-      if (m_pRemotingClient->invokeAsync(addr, request, cbw, time_out, maxRetryTimes, retry_time) == false) {
-        retry_time += 1;
-        time_out = time_out - (UtilAll::currentTimeMillis() - begin_time);
-        LOG_WARN("invokeAsync retry failed to addr:%s,topic:%s, timeout:%lld, maxRetryTimes:%d, retrySendTimes:%d",
-                 addr.c_str(), msg.getTopic().data(), time_out, maxRetryTimes, retry_time);
-        continue;
-      } else {
-        return;  // invokeAsync success
+  // MessageBatch
+  if (msg->isBatch()) {
+    const auto& messages = static_cast<const MessageBatch*>(msg)->getMessages();
+    uniqMsgId.clear();
+    uniqMsgId.reserve(33 * messages.size());
+    for (const auto& message : messages) {
+      if (!uniqMsgId.empty()) {
+        uniqMsgId.append(",");
       }
+      uniqMsgId.append(MessageClientIDSetter::getUniqID(*message));
     }
+  }
 
-    LOG_ERROR("sendMessageAsync failed to addr:%s,topic:%s, timeout:%lld, maxRetryTimes:%d, retrySendTimes:%d",
-              addr.c_str(), msg.getTopic().data(), time_out, maxRetryTimes, retrySendTimes);
+  SendResult* sendResult =
+      new SendResult(sendStatus, uniqMsgId, responseHeader->msgId, messageQueue, responseHeader->queueOffset);
+  sendResult->setTransactionId(responseHeader->transactionId);
 
-    if (cbw) {
-      cbw->onException();
-      deleteAndZero(cbw);
-    } else {
-      THROW_MQEXCEPTION(MQClientException, "sendMessageAsync failed", -1);
-    }
-  }
+  return sendResult;
 }
 
-PullResult* MQClientAPIImpl::pullMessage(const string& addr,
-                                         PullMessageRequestHeader* pRequestHeader,
+PullResult* MQClientAPIImpl::pullMessage(const std::string& addr,
+                                         PullMessageRequestHeader* requestHeader,
                                          int timeoutMillis,
-                                         int communicationMode,
-                                         PullCallback* pullCallback,
-                                         void* pArg,
-                                         const SessionCredentials& sessionCredentials) {
-  RemotingCommand request(PULL_MESSAGE, pRequestHeader);
-  callSignatureBeforeRequest(addr, request, sessionCredentials);
-  request.Encode();
+                                         CommunicationMode communicationMode,
+                                         PullCallback* pullCallback) {
+  RemotingCommand request(PULL_MESSAGE, requestHeader);
 
   switch (communicationMode) {
-    case ComMode_ONEWAY:
-      break;
     case ComMode_ASYNC:
-      pullMessageAsync(addr, request, timeoutMillis, pullCallback, pArg);
-      break;
+      pullMessageAsync(addr, request, timeoutMillis, pullCallback);
+      return nullptr;
     case ComMode_SYNC:
       return pullMessageSync(addr, request, timeoutMillis);
     default:
-      break;
+      assert(false);
+      return nullptr;
   }
-
-  return NULL;
 }
 
-void MQClientAPIImpl::pullMessageAsync(const string& addr,
+void MQClientAPIImpl::pullMessageAsync(const std::string& addr,
                                        RemotingCommand& request,
                                        int timeoutMillis,
-                                       PullCallback* pullCallback,
-                                       void* pArg) {
-  //<!delete in future;
-  AsyncCallbackWrap* cbw = new PullCallbackWarp(pullCallback, this, pArg);
-  if (m_pRemotingClient->invokeAsync(addr, request, cbw, timeoutMillis) == false) {
-    LOG_ERROR("pullMessageAsync failed of addr:%s, mq:%s", addr.c_str(),
-              static_cast<AsyncArg*>(pArg)->mq.toString().data());
-    deleteAndZero(cbw);
-    THROW_MQEXCEPTION(MQClientException, "pullMessageAsync failed", -1);
-  }
-}
+                                       PullCallback* pullCallback) {
+  // delete in future
+  auto* cbw = new PullCallbackWrap(pullCallback, this);
 
-PullResult* MQClientAPIImpl::pullMessageSync(const string& addr, RemotingCommand& request, int timeoutMillis) {
-  unique_ptr<RemotingCommand> pResponse(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
-  if (pResponse != NULL) {
-    if (((*(pResponse->GetBody())).getSize() == 0) || ((*(pResponse->GetBody())).getData() != NULL)) {
-      try {
-        PullResult* pullResult = processPullResponse(pResponse.get());  // pullMessage will handle
-                                                                        // exception from
-                                                                        // processPullResponse
-        return pullResult;
-      } catch (MQException& e) {
-        LOG_ERROR(e.what());
-        return NULL;
-      }
-    }
+  try {
+    m_remotingClient->invokeAsync(addr, request, cbw, timeoutMillis);
+  } catch (RemotingException& e) {
+    deleteAndZero(cbw);
+    throw e;
   }
-  return NULL;
 }
 
-SendResult MQClientAPIImpl::processSendResponse(const string& brokerName,
-                                                const MQMessage& msg,
-                                                RemotingCommand* pResponse) {
-  SendStatus sendStatus = SEND_OK;
-  int res = 0;
-  switch (pResponse->getCode()) {
-    case FLUSH_DISK_TIMEOUT:
-      sendStatus = SEND_FLUSH_DISK_TIMEOUT;
-      break;
-    case FLUSH_SLAVE_TIMEOUT:
-      sendStatus = SEND_FLUSH_SLAVE_TIMEOUT;
-      break;
-    case SLAVE_NOT_AVAILABLE:
-      sendStatus = SEND_SLAVE_NOT_AVAILABLE;
-      break;
-    case SUCCESS_VALUE:
-      sendStatus = SEND_OK;
-      break;
-    default:
-      res = -1;
-      break;
-  }
-  if (res == 0) {
-    SendMessageResponseHeader* responseHeader = (SendMessageResponseHeader*)pResponse->getCommandHeader();
-    MQMessageQueue messageQueue(msg.getTopic(), brokerName, responseHeader->queueId);
-    string unique_msgId = msg.getProperty(MQMessage::PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX);
-    return SendResult(sendStatus, unique_msgId, responseHeader->msgId, messageQueue, responseHeader->queueOffset);
-  }
-  LOG_ERROR("processSendResponse error remark:%s, error code:%d", (pResponse->getRemark()).c_str(),
-            pResponse->getCode());
-  THROW_MQEXCEPTION(MQClientException, pResponse->getRemark(), pResponse->getCode());
+PullResult* MQClientAPIImpl::pullMessageSync(const std::string& addr, RemotingCommand& request, int timeoutMillis) {
+  std::unique_ptr<RemotingCommand> response(m_remotingClient->invokeSync(addr, request, timeoutMillis));
+  assert(response != nullptr);
+  return processPullResponse(response.get());
 }
 
-PullResult* MQClientAPIImpl::processPullResponse(RemotingCommand* pResponse) {
+PullResult* MQClientAPIImpl::processPullResponse(RemotingCommand* response) {
   PullStatus pullStatus = NO_NEW_MSG;
-  switch (pResponse->getCode()) {
+  switch (response->getCode()) {
     case SUCCESS_VALUE:
       pullStatus = FOUND;
       break;
@@ -558,375 +283,406 @@ PullResult* MQClientAPIImpl::processPullResponse(RemotingCommand* pResponse) {
       pullStatus = OFFSET_ILLEGAL;
       break;
     default:
-      THROW_MQEXCEPTION(MQBrokerException, pResponse->getRemark(), pResponse->getCode());
-      break;
+      THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
   }
 
-  PullMessageResponseHeader* responseHeader = static_cast<PullMessageResponseHeader*>(pResponse->getCommandHeader());
+  // return of decodeCommandCustomHeader is non-null
+  auto* responseHeader = response->decodeCommandCustomHeader<PullMessageResponseHeader>();
+  assert(responseHeader != nullptr);
 
-  if (!responseHeader) {
-    LOG_ERROR("processPullResponse:responseHeader is NULL");
-    THROW_MQEXCEPTION(MQClientException, "processPullResponse:responseHeader is NULL", -1);
-  }
-  //<!get body,delete outsite;
-  MemoryBlock bodyFromResponse = *(pResponse->GetBody());  // response data judgement had been done outside
-                                                           // of processPullResponse
-  if (bodyFromResponse.getSize() == 0) {
-    if (pullStatus != FOUND) {
-      return new PullResultExt(pullStatus, responseHeader->nextBeginOffset, responseHeader->minOffset,
-                               responseHeader->maxOffset, (int)responseHeader->suggestWhichBrokerId);
-    } else {
-      THROW_MQEXCEPTION(MQClientException, "memoryBody size is 0, but pullStatus equals found", -1);
-    }
-  } else {
-    return new PullResultExt(pullStatus, responseHeader->nextBeginOffset, responseHeader->minOffset,
-                             responseHeader->maxOffset, (int)responseHeader->suggestWhichBrokerId, bodyFromResponse);
-  }
+  return new PullResultExt(pullStatus, responseHeader->nextBeginOffset, responseHeader->minOffset,
+                           responseHeader->maxOffset, (int)responseHeader->suggestWhichBrokerId, response->getBody());
 }
 
-//<!***************************************************************************
-int64 MQClientAPIImpl::getMinOffset(const string& addr,
-                                    const string& topic,
-                                    int queueId,
-                                    int timeoutMillis,
-                                    const SessionCredentials& sessionCredentials) {
-  GetMinOffsetRequestHeader* pRequestHeader = new GetMinOffsetRequestHeader();
-  pRequestHeader->topic = topic;
-  pRequestHeader->queueId = queueId;
-
-  RemotingCommand request(GET_MIN_OFFSET, pRequestHeader);
-  callSignatureBeforeRequest(addr, request, sessionCredentials);
-  request.Encode();
-
-  unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
+MQMessageExtPtr MQClientAPIImpl::viewMessage(const std::string& addr, int64_t phyoffset, int timeoutMillis) {
+  ViewMessageRequestHeader* requestHeader = new ViewMessageRequestHeader();
+  requestHeader->offset = phyoffset;
 
-  if (response) {
-    switch (response->getCode()) {
-      case SUCCESS_VALUE: {
-        GetMinOffsetResponseHeader* responseHeader = (GetMinOffsetResponseHeader*)response->getCommandHeader();
+  RemotingCommand request(VIEW_MESSAGE_BY_ID, requestHeader);
 
-        int64 offset = responseHeader->offset;
-        return offset;
-      }
-      default:
-        break;
+  std::unique_ptr<RemotingCommand> response(m_remotingClient->invokeSync(addr, request, timeoutMillis));
+  assert(response != nullptr);
+  switch (response->getCode()) {
+    case SUCCESS_VALUE: {
+      // TODO: ...
     }
-    THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
+    default:
+      break;
   }
-  THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
+
+  THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
 }
 
-int64 MQClientAPIImpl::getMaxOffset(const string& addr,
-                                    const string& topic,
-                                    int queueId,
-                                    int timeoutMillis,
-                                    const SessionCredentials& sessionCredentials) {
-  GetMaxOffsetRequestHeader* pRequestHeader = new GetMaxOffsetRequestHeader();
-  pRequestHeader->topic = topic;
-  pRequestHeader->queueId = queueId;
+int64_t MQClientAPIImpl::searchOffset(const std::string& addr,
+                                      const std::string& topic,
+                                      int queueId,
+                                      uint64_t timestamp,
+                                      int timeoutMillis) {
+  SearchOffsetRequestHeader* requestHeader = new SearchOffsetRequestHeader();
+  requestHeader->topic = topic;
+  requestHeader->queueId = queueId;
+  requestHeader->timestamp = timestamp;
 
-  RemotingCommand request(GET_MAX_OFFSET, pRequestHeader);
-  callSignatureBeforeRequest(addr, request, sessionCredentials);
-  request.Encode();
+  RemotingCommand request(SEARCH_OFFSET_BY_TIMESTAMP, requestHeader);
 
-  unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
+  std::unique_ptr<RemotingCommand> response(m_remotingClient->invokeSync(addr, request, timeoutMillis));
+  assert(response != nullptr);
+  switch (response->getCode()) {
+    case SUCCESS_VALUE: {
+      auto* responseHeader = response->decodeCommandCustomHeader<SearchOffsetResponseHeader>();
+      assert(responseHeader != nullptr);
+      return responseHeader->offset;
+    }
+    default:
+      break;
+  }
 
-  if (response) {
-    switch (response->getCode()) {
-      case SUCCESS_VALUE: {
-        GetMaxOffsetResponseHeader* responseHeader = (GetMaxOffsetResponseHeader*)response->getCommandHeader();
+  THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
+}
 
-        int64 offset = responseHeader->offset;
-        return offset;
-      }
-      default:
-        break;
+int64_t MQClientAPIImpl::getMaxOffset(const std::string& addr,
+                                      const std::string& topic,
+                                      int queueId,
+                                      int timeoutMillis) {
+  GetMaxOffsetRequestHeader* requestHeader = new GetMaxOffsetRequestHeader();
+  requestHeader->topic = topic;
+  requestHeader->queueId = queueId;
+
+  RemotingCommand request(GET_MAX_OFFSET, requestHeader);
+
+  std::unique_ptr<RemotingCommand> response(m_remotingClient->invokeSync(addr, request, timeoutMillis));
+  assert(response != nullptr);
+  switch (response->getCode()) {
+    case SUCCESS_VALUE: {
+      auto* responseHeader = response->decodeCommandCustomHeader<GetMaxOffsetResponseHeader>(GET_MAX_OFFSET);
+      return responseHeader->offset;
     }
-    THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
+    default:
+      break;
   }
-  THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
+
+  THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
 }
 
-int64 MQClientAPIImpl::searchOffset(const string& addr,
-                                    const string& topic,
-                                    int queueId,
-                                    uint64_t timestamp,
-                                    int timeoutMillis,
-                                    const SessionCredentials& sessionCredentials) {
-  SearchOffsetRequestHeader* pRequestHeader = new SearchOffsetRequestHeader();
-  pRequestHeader->topic = topic;
-  pRequestHeader->queueId = queueId;
-  pRequestHeader->timestamp = timestamp;
+int64_t MQClientAPIImpl::getMinOffset(const std::string& addr,
+                                      const std::string& topic,
+                                      int queueId,
+                                      int timeoutMillis) {
+  GetMinOffsetRequestHeader* requestHeader = new GetMinOffsetRequestHeader();
+  requestHeader->topic = topic;
+  requestHeader->queueId = queueId;
 
-  RemotingCommand request(SEARCH_OFFSET_BY_TIMESTAMP, pRequestHeader);
-  callSignatureBeforeRequest(addr, request, sessionCredentials);
-  request.Encode();
+  RemotingCommand request(GET_MIN_OFFSET, requestHeader);
 
-  unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
+  std::unique_ptr<RemotingCommand> response(m_remotingClient->invokeSync(addr, request, timeoutMillis));
+  assert(response != nullptr);
+  switch (response->getCode()) {
+    case SUCCESS_VALUE: {
+      auto* responseHeader = response->decodeCommandCustomHeader<GetMinOffsetResponseHeader>();
+      assert(responseHeader != nullptr);
+      return responseHeader->offset;
+    }
+    default:
+      break;
+  }
 
-  if (response) {
-    switch (response->getCode()) {
-      case SUCCESS_VALUE: {
-        SearchOffsetResponseHeader* responseHeader = (SearchOffsetResponseHeader*)response->getCommandHeader();
+  THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
+}
 
-        int64 offset = responseHeader->offset;
-        return offset;
-      }
-      default:
-        break;
+int64_t MQClientAPIImpl::getEarliestMsgStoretime(const std::string& addr,
+                                                 const std::string& topic,
+                                                 int queueId,
+                                                 int timeoutMillis) {
+  GetEarliestMsgStoretimeRequestHeader* requestHeader = new GetEarliestMsgStoretimeRequestHeader();
+  requestHeader->topic = topic;
+  requestHeader->queueId = queueId;
+
+  RemotingCommand request(GET_EARLIEST_MSG_STORETIME, requestHeader);
+
+  std::unique_ptr<RemotingCommand> response(m_remotingClient->invokeSync(addr, request, timeoutMillis));
+  assert(response != nullptr);
+  switch (response->getCode()) {
+    case SUCCESS_VALUE: {
+      auto* responseHeader = response->decodeCommandCustomHeader<GetEarliestMsgStoretimeResponseHeader>();
+      assert(responseHeader != nullptr);
+      return responseHeader->timestamp;
     }
-    THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
+    default:
+      break;
   }
-  THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
-}
 
-MQMessageExt* MQClientAPIImpl::viewMessage(const string& addr,
-                                           int64 phyoffset,
-                                           int timeoutMillis,
-                                           const SessionCredentials& sessionCredentials) {
-  ViewMessageRequestHeader* pRequestHeader = new ViewMessageRequestHeader();
-  pRequestHeader->offset = phyoffset;
+  THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
+}
 
-  RemotingCommand request(VIEW_MESSAGE_BY_ID, pRequestHeader);
-  callSignatureBeforeRequest(addr, request, sessionCredentials);
-  request.Encode();
+void MQClientAPIImpl::getConsumerIdListByGroup(const std::string& addr,
+                                               const std::string& consumerGroup,
+                                               std::vector<std::string>& cids,
+                                               int timeoutMillis) {
+  GetConsumerListByGroupRequestHeader* requestHeader = new GetConsumerListByGroupRequestHeader();
+  requestHeader->consumerGroup = consumerGroup;
 
-  unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
+  RemotingCommand request(GET_CONSUMER_LIST_BY_GROUP, requestHeader);
 
-  if (response) {
-    switch (response->getCode()) {
-      case SUCCESS_VALUE: {
+  std::unique_ptr<RemotingCommand> response(m_remotingClient->invokeSync(addr, request, timeoutMillis));
+  assert(response != nullptr);
+  switch (response->getCode()) {
+    case SUCCESS_VALUE: {
+      auto responseBody = response->getBody();
+      if (responseBody != nullptr && responseBody->getSize() > 0) {
+        std::unique_ptr<GetConsumerListByGroupResponseBody> body(
+            GetConsumerListByGroupResponseBody::Decode(*responseBody));
+        cids = body->consumerIdList;
+        return;
       }
-      default:
-        break;
     }
-    THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
+    default:
+      break;
   }
-  THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
+
+  THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
 }
 
-int64 MQClientAPIImpl::getEarliestMsgStoretime(const string& addr,
-                                               const string& topic,
-                                               int queueId,
-                                               int timeoutMillis,
-                                               const SessionCredentials& sessionCredentials) {
-  GetEarliestMsgStoretimeRequestHeader* pRequestHeader = new GetEarliestMsgStoretimeRequestHeader();
-  pRequestHeader->topic = topic;
-  pRequestHeader->queueId = queueId;
+int64_t MQClientAPIImpl::queryConsumerOffset(const std::string& addr,
+                                             QueryConsumerOffsetRequestHeader* requestHeader,
+                                             int timeoutMillis) {
+  RemotingCommand request(QUERY_CONSUMER_OFFSET, requestHeader);
 
-  RemotingCommand request(GET_EARLIEST_MSG_STORETIME, pRequestHeader);
-  callSignatureBeforeRequest(addr, request, sessionCredentials);
-  request.Encode();
+  std::unique_ptr<RemotingCommand> response(m_remotingClient->invokeSync(addr, request, timeoutMillis));
+  assert(response != nullptr);
+  switch (response->getCode()) {
+    case SUCCESS_VALUE: {
+      auto* responseHeader = response->decodeCommandCustomHeader<QueryConsumerOffsetResponseHeader>();
+      assert(responseHeader != nullptr);
+      return responseHeader->offset;
+    }
+    default:
+      break;
+  }
 
-  unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
+  THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
+}
 
-  if (response) {
-    switch (response->getCode()) {
-      case SUCCESS_VALUE: {
-        GetEarliestMsgStoretimeResponseHeader* responseHeader =
-            (GetEarliestMsgStoretimeResponseHeader*)response->getCommandHeader();
+void MQClientAPIImpl::updateConsumerOffset(const std::string& addr,
+                                           UpdateConsumerOffsetRequestHeader* requestHeader,
+                                           int timeoutMillis) {
+  RemotingCommand request(UPDATE_CONSUMER_OFFSET, requestHeader);
 
-        int64 timestamp = responseHeader->timestamp;
-        return timestamp;
-      }
-      default:
-        break;
-    }
-    THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
-  }
-  THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
-}
-
-void MQClientAPIImpl::getConsumerIdListByGroup(const string& addr,
-                                               const string& consumerGroup,
-                                               vector<string>& cids,
-                                               int timeoutMillis,
-                                               const SessionCredentials& sessionCredentials) {
-  GetConsumerListByGroupRequestHeader* pRequestHeader = new GetConsumerListByGroupRequestHeader();
-  pRequestHeader->consumerGroup = consumerGroup;
-
-  RemotingCommand request(GET_CONSUMER_LIST_BY_GROUP, pRequestHeader);
-  callSignatureBeforeRequest(addr, request, sessionCredentials);
-  request.Encode();
-
-  unique_ptr<RemotingCommand> pResponse(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
-
-  if (pResponse != NULL) {
-    if ((pResponse->GetBody()->getSize() == 0) || (pResponse->GetBody()->getData() != NULL)) {
-      switch (pResponse->getCode()) {
-        case SUCCESS_VALUE: {
-          const MemoryBlock* pbody = pResponse->GetBody();
-          if (pbody->getSize()) {
-            GetConsumerListByGroupResponseBody::Decode(pbody, cids);
-            return;
-          }
-        }
-        default:
-          break;
-      }
-      THROW_MQEXCEPTION(MQBrokerException, pResponse->getRemark(), pResponse->getCode());
+  std::unique_ptr<RemotingCommand> response(m_remotingClient->invokeSync(addr, request, timeoutMillis));
+  assert(response != nullptr);
+  switch (response->getCode()) {
+    case SUCCESS_VALUE: {
+      return;
     }
+    default:
+      break;
   }
-  THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
+
+  THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
 }
 
-int64 MQClientAPIImpl::queryConsumerOffset(const string& addr,
-                                           QueryConsumerOffsetRequestHeader* pRequestHeader,
-                                           int timeoutMillis,
-                                           const SessionCredentials& sessionCredentials) {
-  RemotingCommand request(QUERY_CONSUMER_OFFSET, pRequestHeader);
-  callSignatureBeforeRequest(addr, request, sessionCredentials);
-  request.Encode();
+void MQClientAPIImpl::updateConsumerOffsetOneway(const std::string& addr,
+                                                 UpdateConsumerOffsetRequestHeader* requestHeader,
+                                                 int timeoutMillis) {
+  RemotingCommand request(UPDATE_CONSUMER_OFFSET, requestHeader);
 
-  unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
+  m_remotingClient->invokeOneway(addr, request);
+}
 
-  if (response) {
-    switch (response->getCode()) {
-      case SUCCESS_VALUE: {
-        QueryConsumerOffsetResponseHeader* responseHeader =
-            (QueryConsumerOffsetResponseHeader*)response->getCommandHeader();
-        int64 consumerOffset = responseHeader->offset;
-        return consumerOffset;
-      }
-      default:
-        break;
+void MQClientAPIImpl::sendHearbeat(const std::string& addr, HeartbeatData* heartbeatData) {
+  RemotingCommand request(HEART_BEAT, nullptr);
+  request.setBody(heartbeatData->encode());
+
+  std::unique_ptr<RemotingCommand> response(m_remotingClient->invokeSync(addr, request));
+  assert(response != nullptr);
+  switch (response->getCode()) {
+    case SUCCESS_VALUE: {
+      LOG_INFO("sendheartbeat to broker:%s success", addr.c_str());
+      return;
     }
-    THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
+    default:
+      break;
   }
-  THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
-  return -1;
-}
 
-void MQClientAPIImpl::updateConsumerOffset(const string& addr,
-                                           UpdateConsumerOffsetRequestHeader* pRequestHeader,
-                                           int timeoutMillis,
-                                           const SessionCredentials& sessionCredentials) {
-  RemotingCommand request(UPDATE_CONSUMER_OFFSET, pRequestHeader);
-  callSignatureBeforeRequest(addr, request, sessionCredentials);
-  request.Encode();
+  THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
+}
 
-  unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
+void MQClientAPIImpl::unregisterClient(const std::string& addr,
+                                       const std::string& clientID,
+                                       const std::string& producerGroup,
+                                       const std::string& consumerGroup) {
+  LOG_INFO("unregisterClient to broker:%s", addr.c_str());
+  RemotingCommand request(UNREGISTER_CLIENT, new UnregisterClientRequestHeader(clientID, producerGroup, consumerGroup));
 
-  if (response) {
-    switch (response->getCode()) {
-      case SUCCESS_VALUE: {
-        return;
-      }
-      default:
-        break;
-    }
-    THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
+  std::unique_ptr<RemotingCommand> response(m_remotingClient->invokeSync(addr, request));
+  assert(response != nullptr);
+  switch (response->getCode()) {
+    case SUCCESS_VALUE:
+      LOG_INFO("unregisterClient to:%s success", addr.c_str());
+      return;
+    default:
+      break;
   }
-  THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
+
+  LOG_WARN("unregisterClient fail:%s, %d", response->getRemark().c_str(), response->getCode());
+  THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
 }
 
-void MQClientAPIImpl::updateConsumerOffsetOneway(const string& addr,
-                                                 UpdateConsumerOffsetRequestHeader* pRequestHeader,
-                                                 int timeoutMillis,
-                                                 const SessionCredentials& sessionCredentials) {
-  RemotingCommand request(UPDATE_CONSUMER_OFFSET, pRequestHeader);
-  callSignatureBeforeRequest(addr, request, sessionCredentials);
-  request.Encode();
+void MQClientAPIImpl::endTransactionOneway(const std::string& addr,
+                                           EndTransactionRequestHeader* requestHeader,
+                                           const std::string& remark) {
+  RemotingCommand request(END_TRANSACTION, requestHeader);
+  request.setRemark(remark);
 
-  m_pRemotingClient->invokeOneway(addr, request);
+  m_remotingClient->invokeOneway(addr, request);
 }
 
-void MQClientAPIImpl::consumerSendMessageBack(const string addr,
+void MQClientAPIImpl::consumerSendMessageBack(const std::string& addr,
                                               MQMessageExt& msg,
-                                              const string& consumerGroup,
+                                              const std::string& consumerGroup,
                                               int delayLevel,
                                               int timeoutMillis,
-                                              int maxReconsumeTimes,
-                                              const SessionCredentials& sessionCredentials) {
-  ConsumerSendMsgBackRequestHeader* pRequestHeader = new ConsumerSendMsgBackRequestHeader();
-  pRequestHeader->group = consumerGroup;
-  pRequestHeader->offset = msg.getCommitLogOffset();
-  pRequestHeader->delayLevel = delayLevel;
-  pRequestHeader->unitMode = false;
-  pRequestHeader->originTopic = msg.getTopic();
-  pRequestHeader->originMsgId = msg.getMsgId();
-  pRequestHeader->maxReconsumeTimes = maxReconsumeTimes;
-
-  // string addr = socketAddress2IPPort(msg.getStoreHost());
-  RemotingCommand request(CONSUMER_SEND_MSG_BACK, pRequestHeader);
-  callSignatureBeforeRequest(addr, request, sessionCredentials);
-  request.Encode();
-
-  unique_ptr<RemotingCommand> response(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
-
-  if (response) {
-    switch (response->getCode()) {
-      case SUCCESS_VALUE: {
-        return;
-      }
-      default:
-        break;
+                                              int maxConsumeRetryTimes) {
+  ConsumerSendMsgBackRequestHeader* requestHeader = new ConsumerSendMsgBackRequestHeader();
+  requestHeader->group = consumerGroup;
+  requestHeader->originTopic = msg.getTopic();
+  requestHeader->offset = msg.getCommitLogOffset();
+  requestHeader->delayLevel = delayLevel;
+  requestHeader->originMsgId = msg.getMsgId();
+  requestHeader->maxReconsumeTimes = maxConsumeRetryTimes;
+
+  RemotingCommand request(CONSUMER_SEND_MSG_BACK, requestHeader);
+
+  std::unique_ptr<RemotingCommand> response(m_remotingClient->invokeSync(addr, request, timeoutMillis));
+  assert(response != nullptr);
+  switch (response->getCode()) {
+    case SUCCESS_VALUE: {
+      return;
     }
-    THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
+    default:
+      break;
   }
-  THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
+
+  THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
 }
 
-void MQClientAPIImpl::lockBatchMQ(const string& addr,
+void MQClientAPIImpl::lockBatchMQ(const std::string& addr,
                                   LockBatchRequestBody* requestBody,
-                                  vector<MQMessageQueue>& mqs,
-                                  int timeoutMillis,
-                                  const SessionCredentials& sessionCredentials) {
-  RemotingCommand request(LOCK_BATCH_MQ, NULL);
-  string body;
-  requestBody->Encode(body);
-  request.SetBody(body.data(), body.length());
-  request.setMsgBody(body);
-  callSignatureBeforeRequest(addr, request, sessionCredentials);
-  request.Encode();
-
-  unique_ptr<RemotingCommand> pResponse(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
-
-  if (pResponse != NULL) {
-    if (((*(pResponse->GetBody())).getSize() == 0) || ((*(pResponse->GetBody())).getData() != NULL)) {
-      switch (pResponse->getCode()) {
-        case SUCCESS_VALUE: {
-          const MemoryBlock* pbody = pResponse->GetBody();
-          if (pbody->getSize()) {
-            LockBatchResponseBody::Decode(pbody, mqs);
-          }
-          return;
-        } break;
-        default:
-          break;
+                                  std::vector<MQMessageQueue>& mqs,
+                                  int timeoutMillis) {
+  RemotingCommand request(LOCK_BATCH_MQ, nullptr);
+  request.setBody(requestBody->encode());
+
+  std::unique_ptr<RemotingCommand> response(m_remotingClient->invokeSync(addr, request, timeoutMillis));
+  assert(response != nullptr);
+  switch (response->getCode()) {
+    case SUCCESS_VALUE: {
+      auto requestBody = response->getBody();
+      if (requestBody != nullptr && requestBody->getSize() > 0) {
+        std::unique_ptr<LockBatchResponseBody> body(LockBatchResponseBody::Decode(*requestBody));
+        mqs = body->getLockOKMQSet();
+      } else {
+        mqs.clear();
       }
-      THROW_MQEXCEPTION(MQBrokerException, pResponse->getRemark(), pResponse->getCode());
-    }
+      return;
+    } break;
+    default:
+      break;
   }
-  THROW_MQEXCEPTION(MQBrokerException, "response is null", -1);
+
+  THROW_MQEXCEPTION(MQBrokerException, response->getRemark(), response->getCode());
 }
 
-void MQClientAPIImpl::unlockBatchMQ(const string& addr,
+void MQClientAPIImpl::unlockBatchMQ(const std::string& addr,
                                     UnlockBatchRequestBody* requestBody,
                                     int timeoutMillis,
-                                    const SessionCredentials& sessionCredentials) {
-  RemotingCommand request(UNLOCK_BATCH_MQ, NULL);
-  string body;
-  requestBody->Encode(body);
-  request.SetBody(body.data(), body.length());
-  request.setMsgBody(body);
-  callSignatureBeforeRequest(addr, request, sessionCredentials);
-  request.Encode();
-
-  unique_ptr<RemotingCommand> pResponse(m_pRemotingClient->invokeSync(addr, request, timeoutMillis));
-
-  if (pResponse != NULL) {
-    switch (pResponse->getCode()) {
+                                    bool oneway) {
+  RemotingCommand request(UNLOCK_BATCH_MQ, nullptr);
+  request.setBody(requestBody->encode());
+
+  if (oneway) {
+    m_remotingClient->invokeOneway(addr, request);
+  } else {
+    std::unique_ptr<RemotingCommand> response(m_remotingClient->invokeSync(addr, request, timeoutMillis));
+    assert(response != nullptr);
+    switch (response->getCode()) {
... 38753 lines suppressed ...