ZeroMQ号称是“史上最快的消息队列”,基于c语言开发的,实时流处理sorm的task之间的通信就是用的zeroMQ。
ZeroMQ可以简化网络开发。该通信模块用于微服务内部通信十分简单,高效。是理想的微服务内部的RPC通信工具。
SEED_CZMQ--|
|
|---include----|
| |---seed_bp_czmq_api.h----->对外接口头文件,用于调用
| |
|
|---src--------|
| |----seed_czmq_client.h----->客户端模块内部实现的头文件
| |----seed_czmq_server.h----->服务端模块内部实现的头文件
| |----seed_czmq_client.cpp----->服务端模块内部实现的源代码
| |----seed_czmq_server.cpp---服务端模块内部实现的源代码
| |----seed_bp_czmq_api.cpp---对外接口的具体实现
|
|
|
|----mk--------|
| |-----CMakefile----->编译文件(支持windows linux 跨平台编译)
|
|---exlib------|----linux--->boost linux库
| |----windows--->boost windows库
| |----windows--->boost windows库
|
|--------->README--工程说明文件
3.SEED_CZMQ库说明:
SEED_CZMQ 是基于ZEROMQ开发的RPC通信模块。用于微服务之间通信。是SEED_CLOUD微服务框架的重要模块。
4.代码说明:
/*
@filename: seed_bp_czmq_api.h
@comment: zeromq interface
*/
#ifndef SEED_BP_SEED_BP_CZMQ_API_H
#define SEED_BP_SEED_BP_CZMQ_API_H
#include
#include
#include
#include
enum CmqType{
CZMQ_PAIR=0,
CZMQ_REQ,
CZMQ_REP,
CZMQ_PUB,
CZMQ_SUB,
CZMQ_DELAR,
CZMQ_ROUTER,
TYEP_INVALID
};
enum CmqStats{
CZMQ_START=0,
CZMQ_STOP=1,
CZMQ_INVALID
};
struct SEED_API SeedNode
{
typedef SD_ULONG32 (*message_call_back)(void* msg);
std::string m_net_path;
void* m_inserver = nullptr;
void* m_inclient = nullptr;
void* m_net = nullptr;
void* m_scontrol = nullptr;
void* m_icontrol = nullptr;
SD_ULONG32 m_uid=0;
SD_ULONG32 m_stats=CZMQ_STOP;
SD_ULONG32 m_type=0;
SD_LONG32 m_timeout=-1;
std::string m_id;
message_call_back m_callback = nullptr;
};
class SEED_API SeedCZMQLog{
public:
static void set_log_callback(log_callback logfunc, SD_ULONG32 logID) {
s_logfunc = logfunc;
s_logID = logID;
return;
}
static void log(IN SD_ULONG32 level, const char* filename, SD_ULONG32 lineid, const char* fmt, ...) {
va_list vArgList;
va_start(vArgList, fmt);
if (SeedCZMQLog::s_logfunc)
{
SeedCZMQLog::s_logfunc(s_logID, level, filename, lineid, fmt, vArgList);
}
va_end(vArgList);
return;
}
private:
static log_callback s_logfunc ;
static unsigned int s_logID ;
};
class SEED_API SeedZmqBase{
public:
virtual SD_ULONG32 ZmqStart() = 0;
virtual SD_ULONG32 ZmqStop() = 0;
virtual SD_ULONG32 ZmqSend() = 0;
virtual SD_ULONG32 ZmqReset() = 0;
virtual SD_ULONG32 CreatePool() = 0;
virtual SD_ULONG32 ZmqSetBeOpt() = 0;
virtual SD_ULONG32 ZmqSetAfOpt() = 0;
virtual SD_ULONG32 ZmqInit(std::string adress,SD_ULONG32 ultype) = 0;
};
class SEED_API SeedCzmqFactory{
public:
SD_ULONG32 CreateServer(IN std::string adress,IN SD_ULONG32 ultype, OUT SD_ULONG32 & id);
SD_ULONG32 CreateClient(IN std::string adress,IN SD_ULONG32 ultype, OUT SD_ULONG32 & id);
private:
SD_ULONG32 m_sadapter = 0;
SD_ULONG32 m_cadapter = 0;
std::map<SD_ULONG32,SeedZmqBase*> m_servers;
std::map<SD_ULONG32,SeedZmqBase*> m_clients;
};
#endif //SEED_BP_SEED_BP_CZMQ_API_H
/*
@filename: seed_bp_czmq_api.cpp
@comment: zeromq interface
*/
#include
SD_ULONG32 SeedCzmqFactory::CreateServer(std::string adress, SD_ULONG32 ultype, SD_ULONG32 &id) {
return 0;
}
SD_ULONG32 SeedCzmqFactory::CreateClient(std::string adress, SD_ULONG32 ultype, SD_ULONG32 &id) {
return 0;
}
/*
@filename: seed_czmq_client.h
@comment:
log example
*/
#ifndef SEED_BP_SEED_CZMQ_CLIENT_H
#define SEED_BP_SEED_CZMQ_CLIENT_H
#include
#include
class SeedCzmqClient : public SeedZmqBase {
unsigned int ZmqStart() override;
unsigned int ZmqStop() override;
unsigned int ZmqSend() override;
unsigned int CreatePool() override;
unsigned int ZmqReset() override;
unsigned int ZmqInit(std::string adress, SD_ULONG32 ultype) override;
unsigned int ZmqSetBeOpt() override;
unsigned int ZmqSetAfOpt() override;
private:
SeedNode m_node;
};
#define SEED_ZMQC_LOG0(level,message) if(1){ SeedCZMQLog::log(level,__FILE__,__LINE__,message);}
#define SEED_ZMQC_LOG1(level,fmt,v1) if(1){SeedCZMQLog::log(level,__FILE__,__LINE__,fmt,v1);}
#define SEED_ZMQC_LOG2(level,message,v1,v2) if(1){SeedCZMQLog::log(level,__FILE__,__LINE__,message,v1,v2);}
#endif //SEED_BP_SEED_CZMQ_CLIENT_H
/*
@filename: seed_czmq_client.cpp
@comment:
log example
*/
#include "seed_czmq_client.h"
unsigned int SeedCzmqClient::ZmqStart() {
return this->CreatePool();
}
unsigned int SeedCzmqClient::ZmqStop() {
SD_ULONG32 ulret =ERROR_BASE_SUCCEED;
if (m_node.m_stats == CZMQ_STOP){
SEED_ZMQC_LOG1(SD_LOG_INFO,"CZMQ alread stop [%s]", m_node.m_net_path.c_str());
return ulret;
}
zmsg_t * msg = zmsg_new();
if(msg != nullptr){
zmsg_pushstr(msg,"SEED_QUIT");
SD_LONG32 ret = zmsg_send(&msg,m_node.m_icontrol);
if(ret != -1){
return ERROR_BASE_FALT;
}
zmsg_destroy(&msg);
}
return ulret;
}
unsigned int SeedCzmqClient::ZmqSend() {
return 0;
}
unsigned int SeedCzmqClient::ZmqReset() {
this->ZmqStop();
BP_Sleep(3);
this->ZmqStart();
return 0;}
unsigned int SeedCzmqClient::CreatePool() {
SD_ULONG32 ulret = ERROR_BASE_SUCCEED;
if(m_node.m_inclient == nullptr ||
m_node.m_net == nullptr ||
m_node.m_inserver == nullptr ||
m_node.m_icontrol == nullptr ||
m_node.m_scontrol == nullptr)
{
SEED_ZMQC_LOG0(SD_LOG_INFO, "Fail create ZMQ Poll...");
return ERROR_BASE_FALT;
}
while (true){
zmq_pollitem_t items[] = {
{zsock_resolve(m_node.m_inserver),0,ZMQ_POLLIN,0},
{zsock_resolve(m_node.m_scontrol),0,ZMQ_POLLIN,0},
{zsock_resolve(m_node.m_net),0,ZMQ_POLLIN,0}
};
m_node.m_type = CZMQ_START;
zmq_poll(items,2,m_node.m_timeout);
if (items[0].revents & ZMQ_POLLIN){
zmsg_t * data = zmsg_recv(m_node.m_inserver);
if (data == nullptr){
break;
}
zmsg_send(&data,m_node.m_net);
zmsg_destroy(&data);
data = nullptr;
}
if (items[1].revents & ZMQ_POLLIN){
zmsg_t * data = zmsg_recv(m_node.m_scontrol);
if (data == nullptr){
break;
}
if(zmsg_size(data) != 1){
zmsg_destroy(&data);
break;
}
zframe_t * frame = zmsg_next(data);
if (std::string("SEED_QUIT") == std::string((char*)zframe_data(frame),zframe_size(frame))){
zmsg_destroy(&data);
data = nullptr;
break;
}
zmsg_destroy(&data);
data = nullptr;
}
if (items[2].revents & ZMQ_POLLIN) {
zmsg_t * data = zmsg_recv(m_node.m_net);
if (data == nullptr){
break;
}
if (m_node.m_callback){
m_node.m_callback(static_cast<void*>(data));
}
if (data != nullptr){
zmsg_destroy(&data);
}
}
else{
SEED_ZMQC_LOG1(SD_LOG_INFO, "EPOLL MESSAGE TIMEOUT [%d]'S...", m_node.m_timeout);
if (m_node.m_stats == CZMQ_STOP){
SEED_ZMQC_LOG0(SD_LOG_INFO, "check CMQ is STOP so break epoll");
break;
}
}
}
m_node.m_type = CZMQ_STOP;
if (m_node.m_inserver){
zsock_destroy((zsock_t**)(&m_node.m_inserver));
m_node.m_inserver= nullptr;
}
if (m_node.m_inclient){
zsock_destroy((zsock_t**)(&m_node.m_inclient));
m_node.m_inclient= nullptr;
}
if (m_node.m_icontrol){
zsock_destroy((zsock_t**)(&m_node.m_icontrol));
m_node.m_icontrol= nullptr;
}
if (m_node.m_scontrol){
zsock_destroy((zsock_t**)(&m_node.m_scontrol));
m_node.m_scontrol= nullptr;
}
if (m_node.m_net){
zsock_destroy((zsock_t**)(&m_node.m_net));
m_node.m_net= nullptr;
}
return ERROR_BASE_SUCCEED;
}
unsigned int SeedCzmqClient::ZmqInit(std::string adress, SD_ULONG32 ultype) {
SD_ULONG32 ulret = ERROR_BASE_SUCCEED;
try
{
m_node.m_inserver = zsock_new(ZMQ_PAIR);
m_node.m_inclient = zsock_new(ZMQ_PAIR);
m_node.m_icontrol = zsock_new(ZMQ_PAIR);
m_node.m_scontrol = zsock_new(ZMQ_PAIR);
m_node.m_net = zsock_new(ultype);
m_node.m_stats = CZMQ_STOP;
this->ZmqSetBeOpt();
int ret = zsock_bind(static_cast<zsock_t*>(m_node.m_inserver),"inproc://czmq_client_inter_%d",m_node.m_uid);
if (ret != ERROR_BASE_SUCCEED){
SEED_ZMQC_LOG1(SD_LOG_ERROR, "fail connect inproc://czmq_client_inter_%d", m_node.m_uid);
this->ZmqStop();
return ERROR_BASE_FALT;
}
ret = zsock_connect(static_cast<zsock_t*>(m_node.m_inclient),"inproc://czmq_client_inter_%d",m_node.m_uid);
if (ret != ERROR_BASE_SUCCEED){
SEED_ZMQC_LOG1(SD_LOG_ERROR, "fail connect inproc://czmq_client_inter_%d", m_node.m_uid);
this->ZmqStop();
return ERROR_BASE_FALT;
}
ret = zsock_bind(static_cast<zsock_t*>(m_node.m_inserver),"inproc://czmq_client_control_%d",m_node.m_uid);
if (ret != ERROR_BASE_SUCCEED){
SEED_ZMQC_LOG1(SD_LOG_ERROR, "fail bind inproc://czmq_client_control_%d", m_node.m_uid);
this->ZmqStop();
return ERROR_BASE_FALT;
}
ret = zsock_connect(static_cast<zsock_t*>(m_node.m_inclient),"inproc://czmq_client_control_%d",m_node.m_uid);
if (ret != ERROR_BASE_SUCCEED){
SEED_ZMQC_LOG1(SD_LOG_ERROR, "fail connect inproc://czmq_client_control_%d", m_node.m_uid);
this->ZmqStop();
return ERROR_BASE_FALT;
}
ret = zsock_connect(static_cast<zsock_t*>(m_node.m_net),adress.c_str());
if (ret != ERROR_BASE_SUCCEED) {
SEED_ZMQC_LOG1(SD_LOG_ERROR,"fail bind path %s", adress.c_str());
this->ZmqStop();
return ERROR_BASE_FALT;
}
this->ZmqSetAfOpt();
}
catch (std::exception& e)
{
SEED_ZMQC_LOG1(SD_LOG_ERROR, "fail create client exception [%s]", e.what());
this->ZmqStop();
}
return ulret;
}
unsigned int SeedCzmqClient::ZmqSetBeOpt() {
return 0;
}
unsigned int SeedCzmqClient::ZmqSetAfOpt() {
return 0;
}
//
// Created by yang shaofei on 2019-05-31.
/*
@filename: seed_czmq_server.h
@comment:
log example
*/
#ifndef SEED_BP_SEED_CZMQ_SERVER_H
#define SEED_BP_SEED_CZMQ_SERVER_H
#include
#include
class SeedCzmqServer :public SeedZmqBase {
public:
private:
virtual unsigned int ZmqStart() override;
virtual unsigned int ZmqSend() override;
virtual unsigned int ZmqStop() override;
unsigned int ZmqReset() override;
unsigned int CreatePool() override;
unsigned int ZmqInit(std::string adress, SD_ULONG32 ultype) override;
unsigned int ZmqSetBeOpt() override;
unsigned int ZmqSetAfOpt() override;
private:
SeedNode m_node;
};
#define SEED_ZMQS_LOG0(level,message) if(1){ SeedCZMQLog::log(level,__FILE__,__LINE__,message);}
#define SEED_ZMQS_LOG1(level,fmt,v1) if(1){SeedCZMQLog::log(level,__FILE__,__LINE__,fmt,v1);}
#define SEED_ZMQS_LOG2(level,message,v1,v2) if(1){SeedCZMQLog::log(level,__FILE__,__LINE__,message,v1,v2);}
#endif //SEED_BP_SEED_CZMQ_SERVER_H
/*
@filename: seed_czmq_server.cpp
@comment:
log example
*/
#include
#include
#include "seed_czmq_server.h"
unsigned int SeedCzmqServer::ZmqInit(std::string adress, SD_ULONG32 ultype) {
SD_ULONG32 ulret = ERROR_BASE_SUCCEED;
try
{
m_node.m_inserver = zsock_new(ZMQ_PAIR);
m_node.m_inclient = zsock_new(ZMQ_PAIR);
m_node.m_icontrol = zsock_new(ZMQ_PAIR);
m_node.m_scontrol = zsock_new(ZMQ_PAIR);
m_node.m_net = zsock_new(ultype);
m_node.m_stats = CZMQ_STOP;
this->ZmqSetBeOpt();
int ret = zsock_bind(static_cast<zsock_t*>(m_node.m_inserver),"inproc://czmq_server_inter_%d",m_node.m_uid);
if (ret != ERROR_BASE_SUCCEED){
SEED_ZMQS_LOG1(SD_LOG_ERROR, "fail connect inproc://czmq_server_inter_%d", m_node.m_uid);
this->ZmqStop();
return ERROR_BASE_FALT;
}
ret = zsock_connect(static_cast<zsock_t*>(m_node.m_inclient),"inproc://czmq_server_inter_%d",m_node.m_uid);
if (ret != ERROR_BASE_SUCCEED){
SEED_ZMQS_LOG1(SD_LOG_ERROR, "fail connect inproc://czmq_server_inter_%d", m_node.m_uid);
this->ZmqStop();
return ERROR_BASE_FALT;
}
ret = zsock_bind(static_cast<zsock_t*>(m_node.m_inserver),"inproc://czmq_server_control_%d",m_node.m_uid);
if (ret != ERROR_BASE_SUCCEED){
SEED_ZMQS_LOG1(SD_LOG_ERROR, "fail bind inproc://czmq_server_control_%d", m_node.m_uid);
this->ZmqStop();
return ERROR_BASE_FALT;
}
ret = zsock_connect(static_cast<zsock_t*>(m_node.m_inclient),"inproc://czmq_server_control_%d",m_node.m_uid);
if (ret != ERROR_BASE_SUCCEED){
SEED_ZMQS_LOG1(SD_LOG_ERROR, "fail connect inproc://czmq_server_control_%d", m_node.m_uid);
this->ZmqStop();
return ERROR_BASE_FALT;
}
ret = zsock_bind(static_cast<zsock_t*>(m_node.m_net),adress.c_str());
if (ret != ERROR_BASE_SUCCEED) {
SEED_ZMQS_LOG1(SD_LOG_ERROR, "fail bind path %s", adress.c_str());
this->ZmqStop();
return ERROR_BASE_FALT;
}
this->ZmqSetAfOpt();
}
catch (std::exception& e)
{
SEED_ZMQS_LOG1(SD_LOG_ERROR, "fail create server exception [%s]", e.what());
this->ZmqStop();
}
return ulret;
}
unsigned int SeedCzmqServer::ZmqStart() {
return this->CreatePool();
}
unsigned int SeedCzmqServer::ZmqStop() {
SD_ULONG32 ulret = ERROR_BASE_SUCCEED;
if (m_node.m_stats == CZMQ_STOP){
SEED_ZMQS_LOG1(SD_LOG_INFO,"CZMQ alread stop [%s]", m_node.m_net_path.c_str());
return ulret;
}
zmsg_t * msg = zmsg_new();
if(msg != nullptr){
zmsg_pushstr(msg,"SEED_QUIT");
SD_LONG32 ret = zmsg_send(&msg,m_node.m_icontrol);
if(ret != -1){
return ERROR_BASE_FALT;
}
zmsg_destroy(&msg);
}
return ulret;
}
unsigned int SeedCzmqServer::ZmqSend() {
return 0;
}
unsigned int SeedCzmqServer::ZmqReset() {
this->ZmqStop();
BP_Sleep(3);
this->ZmqStart();
return 0;
}
unsigned int SeedCzmqServer::CreatePool() {
SD_ULONG32 ulret = ERROR_BASE_SUCCEED;
if(m_node.m_inclient == nullptr ||
m_node.m_net == nullptr ||
m_node.m_inserver == nullptr ||
m_node.m_icontrol == nullptr ||
m_node.m_scontrol == nullptr)
{
SEED_ZMQS_LOG0(SD_LOG_INFO, "Fail create ZMQ Poll...");
return ERROR_BASE_FALT;
}
while (true){
zmq_pollitem_t items[] = {
{zsock_resolve(m_node.m_inserver),0,ZMQ_POLLIN,0},
{zsock_resolve(m_node.m_scontrol),0,ZMQ_POLLIN,0},
{zsock_resolve(m_node.m_net),0,ZMQ_POLLIN,0}
};
m_node.m_type = CZMQ_START;
zmq_poll(items,2,m_node.m_timeout);
if (items[0].revents & ZMQ_POLLIN){
zmsg_t * data = zmsg_recv(m_node.m_inserver);
if (data == nullptr){
break;
}
zmsg_send(&data,m_node.m_net);
zmsg_destroy(&data);
data = nullptr;
}
if (items[1].revents & ZMQ_POLLIN){
zmsg_t * data = zmsg_recv(m_node.m_scontrol);
if (data == nullptr){
break;
}
if(zmsg_size(data) != 1){
zmsg_destroy(&data);
break;
}
zframe_t * frame = zmsg_next(data);
if (std::string("SEED_QUIT") == std::string((char*)zframe_data(frame),zframe_size(frame))){
zmsg_destroy(&data);
data = nullptr;
break;
}
zmsg_destroy(&data);
data = nullptr;
}
if (items[2].revents & ZMQ_POLLIN) {
zmsg_t * data = zmsg_recv(m_node.m_net);
if (data == nullptr){
break;
}
if (m_node.m_callback){
m_node.m_callback(static_cast<void*>(data));
}
if (data != nullptr){
zmsg_destroy(&data);
}
}
else{
SEED_ZMQS_LOG1(SD_LOG_INFO, "EPOLL MESSAGE TIMEOUT [%d]'S...", m_node.m_timeout);
if (m_node.m_stats == CZMQ_STOP){
SEED_ZMQS_LOG0(SD_LOG_INFO, "check CMQ is STOP so break epoll");
break;
}
}
}
m_node.m_type = CZMQ_STOP;
if (m_node.m_inserver){
zsock_destroy((zsock_t**)(&m_node.m_inserver));
m_node.m_inserver= nullptr;
}
if (m_node.m_inclient){
zsock_destroy((zsock_t**)(&m_node.m_inclient));
m_node.m_inclient= nullptr;
}
if (m_node.m_icontrol){
zsock_destroy((zsock_t**)(&m_node.m_icontrol));
m_node.m_icontrol= nullptr;
}
if (m_node.m_scontrol){
zsock_destroy((zsock_t**)(&m_node.m_scontrol));
m_node.m_scontrol= nullptr;
}
if (m_node.m_net){
zsock_destroy((zsock_t**)(&m_node.m_net));
m_node.m_net= nullptr;
}
return ERROR_BASE_SUCCEED;
}
unsigned int SeedCzmqServer::ZmqSetBeOpt() {
return 0;
}
unsigned int SeedCzmqServer::ZmqSetAfOpt() {
return 0;
}