概述

最近项目消息队列服务选用了rabbitmq,server端用的C++开发的,于是需要开发rabbitmq的c++客户端,国际惯例先百度了一圈,然后github搜了一圈,竟然发现排名靠前的需要付费才能使用,尼玛这都拿出来骗钱(愤青了),于是产生了写个客户端给大家使用的念头。

我的应用场景是这样的生产者是用java写的(java别说了,一搜一大堆,改个服务器地址就能用),服务端作为消费者,老本行用的C++开发的,只需写个c++的rabbitmq客户端嵌入到我的server里就行,所有的消费者监听的一个队列,无需指定routing key和exchange,任何一个消费者消费到数据就行(我的服务端是个集群)。话不多说上代码。

实现

我的环境是Linux centos7.2

amqpclient.cpp源码如下:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h> #include "amqp_tcp_socket.h"
#include "amqp.h"
#include "amqp_framing.h"
#include "utils.h"
#include "platform_utils.h"
#include "amqpclient.h" /*
* 构造函数
* hostname,port,user,pwd,vhost
*/ AmqpClient::AmqpClient(const char* hostname, const int port, const char* user,
const char* pwd, const char* vhost, const char* queuename)
{
if((hostname != NULL) || (port != 0) || (user != NULL)
|| (pwd != NULL) || (vhost != NULL) || (queuename != NULL))
{
strcpy(this->m_hostname, hostname);
this->m_port = port;
strcpy(this->m_user, user);
strcpy(this->m_pwd, pwd);
strcpy(this->m_vhost, vhost);
strcpy(this->m_queuename, queuename);
}
} bool AmqpClient::ConnectRabbitmq()
{
amqp_socket_t *socket ;
amqp_rpc_reply_t reply ;
int status; conn = amqp_new_connection();
socket = amqp_tcp_socket_new(conn);
if(!socket)
{
printf("amqp new socket error\n");
return 0;
}
status = amqp_socket_open(socket, m_hostname, m_port);
if(status)
{
printf("amqp open socket error\n");
return 0;
}
reply = amqp_login(conn, m_vhost, 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, m_user, m_pwd);
if (reply.reply_type == AMQP_RESPONSE_SERVER_EXCEPTION)
{
printf("amqp login error\n");
return 0;
}
amqp_channel_open(conn, 1);
reply = amqp_get_rpc_reply(conn);
if(reply.reply_type == AMQP_RESPONSE_SERVER_EXCEPTION)
{
printf("ConnectRabbitmq::amqp get rpc_reply error\n");
return 0;
}
} bool AmqpClient::StartConsumer()
{
amqp_rpc_reply_t reply ;
//自动回复ACK
amqp_basic_consume(conn, 1, amqp_cstring_bytes(m_queuename), amqp_empty_bytes, 0, 1, 0, amqp_empty_table);
reply = amqp_get_rpc_reply(conn);
if(reply.reply_type == AMQP_RESPONSE_SERVER_EXCEPTION)
{
printf("StartConsumer::amqp get rpc_reply error\n");
return false;
}
{
for (;;)
{
amqp_rpc_reply_t res;
amqp_envelope_t envelope; amqp_maybe_release_buffers(conn); res = amqp_consume_message(conn, &envelope, NULL, 0); if (AMQP_RESPONSE_NORMAL != res.reply_type) {
break;
} printf("Delivery %u, exchange %.*s routingkey %.*s\n",
(unsigned) envelope.delivery_tag,
(int) envelope.exchange.len, (char *) envelope.exchange.bytes,
(int) envelope.routing_key.len, (char *) envelope.routing_key.bytes); if (envelope.message.properties._flags & AMQP_BASIC_CONTENT_TYPE_FLAG) {
printf("Content-type: %.*s\n",
(int) envelope.message.properties.content_type.len,
(char *) envelope.message.properties.content_type.bytes);
}
printf("----\n"); amqp_dump(envelope.message.body.bytes, envelope.message.body.len); amqp_destroy_envelope(&envelope);
}
}
} void AmqpClient::CloseConnect()
{
amqp_rpc_reply_t reply ;
amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS);
amqp_connection_close(conn, AMQP_REPLY_SUCCESS);
amqp_destroy_connection(conn);
}

amqpclient.h源码如下:

#ifndef _AMQPCLIENT_H
#define _AMQPCLIENT_H #include "amqp.h" class AmqpClient
{
public:
AmqpClient(const char* hostname, const int port, const char* user, const char* pwd,
const char* vhost, const char* queuename);
bool ConnectRabbitmq();
bool StartConsumer();
void CloseConnect();
private:
amqp_connection_state_t conn = NULL;
char m_hostname[128];
int m_port;
char m_user[128];
char m_pwd[128];
char m_vhost[128];
char m_queuename[128];
}; #endif

main.cpp源码如下:

#include <stdio.h>
#include "amqpclient.h" int main()
{
const char* hostname = "192.168.12.20";
const int port = 5672;
const char* user = "woniu201";
const char* pwd = "woniu201";
const char* vhost = "/";
const char* queuename = "queuename001"; AmqpClient amqpClient(hostname, port, user, pwd, vhost, queuename);
amqpClient.ConnectRabbitmq();
printf("connect rabbitmq succ, is consuming!\n");
amqpClient.StartConsumer(); return 1;
}

Makefile文件:

EXE=rabbitmq_consumer
SUBDIR=src #CXXFLAGS:编译选项, LDFLAGS:链接选项
CXXFLAGS +=
LDFLAGS += -L/usr/local/lib -lrabbitmq CXX_SOURCES =$(foreach dir,$(SUBDIR), $(wildcard $(dir)/*.cpp))
CXX_OBJECTS=$(patsubst %.cpp, %.o, $(CXX_SOURCES))
DEP_FILES =$(patsubst %.o, %.d, $(CXX_OBJECTS)) $(EXE): $(CXX_OBJECTS)
g++ $(CXX_OBJECTS) -o $(EXE) $(LDFLAGS) %.o: %.cpp
g++ -c $(CXXFLAGS) -MMD $< -o $@ -include $(DEP_FILES) clean:
rm -rf $(CXX_OBJECTS) $(DEP_FILES) $(EXE) test:
echo $(CXX_OBJECTS) initlib:
ln -s lib/librabbitmq.so.4.2.0 /usr/local/lib/librabbitmq.so
ln -s lib/librabbitmq.so.4.2.0 /usr/lib64/librabbitmq.so.4

这里用到了librabbitmq.so.4动态库,make前先执行make initlib指令,会把所用的librabbitmq.so库放到系统环境中。

make完后会生产rabbitmq_consumer可执行文件,./rabbitmq_consumer执行。

测试结果如下:

如果到这里还有问题可以直接下载我的源码或者留言交流:http://download.csdn.net/detail/woniu211111/9911075

没有下载积分的,可以关注下面公众号,回复"107"获取源码

欢迎加群交流:C/C++开发交流

Rabbitmq C++客户端 Rabbitmq Client的更多相关文章

  1. RabbitMQ C#客户端自动重连

    重要参考文章来源:http://gigi.nullneuron.net/gigilabs/resilient-connections-with-rabbitmq-net-client/ 参考代码:ht ...

  2. C#基于RabbitMQ实现客户端之间消息通讯实战演练

    一.背景介绍和描述 MQ消息队列已经逐渐成为企业IT系统内部通信的核心手段.它具有低耦合.可靠投递.广播.流量控制.最终一致性等一系列功能,成为异步RPC的主要手段之一.何时需要消息队列?当你需要使用 ...

  3. RabbitMQ JAVA客户端调用例子

    1.安装erlang 下载地址:http://www.erlang.org/downloads 设置ERLANG环境变量 2.安装RabbitMQ 下载地址: http://www.rabbitmq. ...

  4. RabbitMQ GUI客户端工具(RabbitMQ Assistant)

    RabbitMQ GUI客户端工具(RabbitMQ Assistant) 平时用控制台或者网页进行管理不免有点不方便,尤其在读取消息的时候不支持过滤和批量发送消息,在此推荐一个漂亮的GUI客户端工具 ...

  5. RabbitMQ交换机、RabbitMQ整合springCloud

    目标 1.交换机 2.RabbitMQ整合springCloud 交换机 蓝色区域===生产者 红色区域===Server:又称Broker,接受客户端的连接,实现AMQP实体服务 绿色区域===消费 ...

  6. .Net RabbitMQ实战指南——RabbitMQ相关概念介绍

    什么是消息中间件 消息(Message)是指在应用间传送的数据.消息可以非常简单,比如只包含文本字符串.JSON等,也可以很复杂,比如内嵌对象. 消息队列中间件(Message Queue Middl ...

  7. RabbitMQ入门到进阶(Spring整合RabbitMQ&SpringBoot整合RabbitMQ)

    1.MQ简介 MQ 全称为 Message Queue,是在消息的传输过程中保存消息的容器.多用于分布式系统 之间进行通信. 2.为什么要用 MQ 1.流量消峰 没使用MQ 使用了MQ 2.应用解耦 ...

  8. .NET文件并发与RabbitMQ(初探RabbitMQ)

    本文版权归博客园和作者吴双本人共同所有.欢迎转载,转载和爬虫请注明原文地址:http://www.cnblogs.com/tdws/p/5860668.html 想必MQ这两个字母对于各位前辈们和老司 ...

  9. 基于 IdentityServer3 实现 OAuth 2.0 授权服务【客户端模式(Client Credentials Grant)】

    github:https://github.com/IdentityServer/IdentityServer3/ documentation:https://identityserver.githu ...

随机推荐

  1. CSS子选择器与后代选择器的区别

    p > span{ color:blue; } <p> 嵌套使用<span>css好牛逼!</span><span>是啊<b>也影响孙 ...

  2. GitHub的SSH免密连接

    1.进入当前用户的家目录 $ cd ~ 2.删除.ssh 目录 $ rm -rvf .ssh 3.运行命令生成.ssh 密钥目录 $ ssh-keygen -t rsa -C [GitHub邮箱] [ ...

  3. 爬虫前提——正则表达式语法以及在Python中的使用

    正则表达式是用来处理字符串的强大工具,他并不是某种编程云. 正则表达式拥有独立的承受力引擎,不管什么编程语言,正则表达式的语法都是一样的. 正则表达式的匹配过程 1.一次拿出表达式和文本中的字符比较. ...

  4. AxB Proplem(大数乘法)

    描述 Redraiment碰到了一个难题,需要请你来帮忙:给你两个整数,请你计算A × B. 输入 数据的第一行是整数T(1 ≤ T ≤ 20),代表测试数据的组数. 接着有T组数据,每组数据只有一行 ...

  5. Alpha项目冲刺! Day3-产出

    各个成员今日完成的任务 林恩:任务分工,博客撰写,完善设置等模块 杨长元:安卓本地数据库基本建立 李震:完成注册页面 胡彤:完善服务端 寇永明:画图,学习 王浩:画图,学习 李杰:画图,学习 各个成员 ...

  6. Cesium的Property机制总结

    前言 Cesium官方教程中有一篇叫<空间数据可视化>(Visualizing Spatial Data).该文文末简单提到了Cesium的Property机制,然后话锋一转,宣告此教程的 ...

  7. 咏南中间件新增MORMOT插件功能

    咏南中间件新增MORMOT插件功能 咏南中间件支持DATASNAP和MORMOT两种通讯框架. 原来已经支持DATASNAP插件,现在又增加了MORMOT插件,已经支持DATASNAP和MORMOT两 ...

  8. Java-编程规范与代码风格

    阿里巴巴 Java 开发手册 https://github.com/alibaba/p3c https://developer.aliyun.com/special/tech-java 唯品会规范 J ...

  9. PhpStorm 增加Swoole智能提示

    下载https://github.com/eaglewu/swoole-ide-helper的源码 git clone https://github.com/eaglewu/swoole-ide-he ...

  10. SVG-变换

    transform变换 translate平移 <svg width="200" height="50"> <rect x="0&q ...