Zmq封装

/********************************************************************
 author  :   Clark/陈泽丹
 created :   2014-6-21
 purpose :   ZMQ辅助类
*********************************************************************/
#pragma once
#include <vector>



//ZMQ设备上下文
//注意不要通过引用使用它,否则浅拷贝时会导致引用量在析构时释放了设备上下文
class ZmqContext
{
public:
	static void Start( long _io_thread_num = 1 );
	static void Stop();
	static void* GetContext();

private:
	ZmqContext( long _io_thread_num );
	~ZmqContext();

private:
	static ZmqContext* mp_zmqcontext;
	void* context;
};


//ZMQ套接字
//注意必须先行统一初始化的建立节点,不然不会保存发送接收的信息缓存
//当节点初始化不统一时,发送的信息不会缓存起来,然后导致recv时在那挂起
//所以recv的节点一定要预先建好
class ZmqSkt
{
public:
	ZmqSkt( const char* _addrest );
	~ZmqSkt();
	void Close();
	void* GetContext(){ return skt; }

protected:
	char addr[256];
	void* skt;
};


//ZMQ_PAIR(只能1:1)
struct PairSkt: public ZmqSkt
{
	PairSkt( const char* _addrest ):ZmqSkt(_addrest){}
	long Recv( char* _buf, long _len );
	void Send( char* _buf, long _len );
};
struct ConnetPairSkt: public PairSkt
{
	ConnetPairSkt( const char* _addrest/* = "inproc://unknown"*/ );
};
struct BindPairSkt: public PairSkt
{
	BindPairSkt( const char* _addrest/* = "inproc://unknown"*/ );
};


//ZMQ_PUSH & ZMQ_PULL (N:1)
struct PushPairSkt: public ZmqSkt
{
	PushPairSkt( const char* _addrest/* = "inproc://unknown"*/ );
	void Send( char* _buf, long _len );
};
struct PullPairSkt: public ZmqSkt
{
	PullPairSkt( const char* _addrest/* = "inproc://unknown"*/ );
	long Recv( char* _buf, long _len );
};



//ZMQ_REQ & ZMQ_REP
struct ReqSkt: public ZmqSkt
{
	ReqSkt( const char* _addrest/* = "inproc://unknown"*/ );
	void BeginSend( char* _buf, long _len );
	long End( char* _buf, long _len );
	void End();
};
struct RepSkt: public ZmqSkt
{
	RepSkt( const char* _addrest/* = "inproc://unknown"*/ );
	long BeginRecv( char* _buf, long _len );
	void End( char* _buf = "OK", long _len = 2 );
};


class PollItem
{
public:
	PollItem();
	virtual ~PollItem();
	void Init( std::vector< ZmqSkt* >* _skt );
	void Uninit();
	void WaitEvents();
	virtual bool OnSktEvent( long _skt_id ) = 0;

private:
	void* mp_poll_item;
	long len;
};


#include "ZmqHelpler.h"
#include <zhelpers.h>
#include <zmq.h>

void api_zmq_send( void* _skt, char* _buf, long _len );
long api_zmq_recv( void* _skt, char* _buf, long _len );

void api_zmq_send( void* _skt, char* _buf, long _len )
{
	zmq_msg_t msg;
	zmq_msg_init_size(&msg, _len);
	memcpy( zmq_msg_data(&msg), _buf, _len);
	zmq_sendmsg(_skt, &msg, ZMQ_DONTWAIT);
	zmq_msg_close(&msg);
}

long api_zmq_recv( void* _skt, char* _buf, long _len )
{
	zmq_msg_t msg;
	zmq_msg_init(&msg);
	zmq_recvmsg(_skt,&msg,0);
	long num = 0;
	if( _len >= zmq_msg_size(&msg) )
	{
		num = zmq_msg_size(&msg);
		memcpy(_buf,(char*)zmq_msg_data(&msg),num);
	}
	zmq_msg_close(&msg);
	return num;
}

//ZMQ设备上下文
//注意不要通过引用使用它,否则浅拷贝时会导致引用量在析构时释放了设备上下文
ZmqContext* ZmqContext::mp_zmqcontext = 0;
void ZmqContext::Start( long _io_thread_num )
{
	if( 0 == mp_zmqcontext )
	{
		mp_zmqcontext = new ZmqContext(_io_thread_num);
	}
}
void ZmqContext::Stop()
{
	if( 0 != mp_zmqcontext )
	{
		delete mp_zmqcontext;
		mp_zmqcontext = 0;
	}
}
void* ZmqContext::GetContext()
{ 
	if( 0 != mp_zmqcontext )
		return mp_zmqcontext->context;
	return 0; 
}
ZmqContext::ZmqContext( long _io_thread_num )
{ 
	context = zmq_init(_io_thread_num); 
}
ZmqContext::~ZmqContext()
{ 
	zmq_term(context); 
}




//ZMQ套接字
long G_ZMQ_COUNT = 0;
ZmqSkt::ZmqSkt(const char* _addrest)
{ 
	//strcpy( addr, _addrest );
	//G_ZMQ_COUNT = G_ZMQ_COUNT + 1;
	//printf("G_ZMQ_COUNT %s %d \n", addr, G_ZMQ_COUNT);
}
ZmqSkt::~ZmqSkt()
{ 
	//G_ZMQ_COUNT = G_ZMQ_COUNT - 1;
	//printf("G_ZMQ_COUNT %s %d \n", addr, G_ZMQ_COUNT);
	Close(); 
}
void ZmqSkt::Close()
{ 
	zmq_close(skt);
}



//ZMQ_PAIR(只能1:1)
long PairSkt::Recv( char* _buf, long _len )
{
	return api_zmq_recv( skt, _buf, _len );
}
void PairSkt::Send( char* _buf, long _len )
{
	api_zmq_send( skt, _buf, _len );
}
ConnetPairSkt::ConnetPairSkt( const char* _addrest ):PairSkt(_addrest)
{
	skt = zmq_socket( ZmqContext::GetContext(), ZMQ_PAIR ); 
	zmq_connect( skt, _addrest );
}
BindPairSkt::BindPairSkt( const char* _addrest ):PairSkt(_addrest)
{
	skt = zmq_socket( ZmqContext::GetContext(), ZMQ_PAIR ); 
	zmq_bind( skt, _addrest );
}



//ZMQ_PUSH & ZMQ_PULL (N:1)
PushPairSkt::PushPairSkt( const char* _addrest ):ZmqSkt(_addrest)
{
	skt = zmq_socket( ZmqContext::GetContext(), ZMQ_PUSH ); 
	zmq_connect( skt, _addrest );
}
void PushPairSkt::Send( char* _buf, long _len )
{
	api_zmq_send(skt,_buf,_len);
}
PullPairSkt::PullPairSkt( const char* _addrest ):ZmqSkt(_addrest)
{
	skt = zmq_socket( ZmqContext::GetContext(), ZMQ_PULL ); 
	zmq_bind( skt, _addrest );
}
long PullPairSkt::Recv( char* _buf, long _len )
{
	return api_zmq_recv( skt, _buf, _len );
}


//ZMQ_REQ & ZMQ_REP
ReqSkt::ReqSkt( const char* _addrest ):ZmqSkt(_addrest)
{
	skt = zmq_socket( ZmqContext::GetContext(), ZMQ_REQ ); 
	zmq_connect( skt, _addrest );
}
void ReqSkt::BeginSend( char* _buf, long _len )
{
	api_zmq_send( skt, _buf, _len );
}
long ReqSkt::End( char* _buf, long _len )
{
	return api_zmq_recv( skt, _buf, _len );
}
void ReqSkt::End()
{
	char msg[64];
	api_zmq_recv(skt, msg, sizeof(msg));
}


RepSkt::RepSkt( const char* _addrest ):ZmqSkt(_addrest)
{
	skt = zmq_socket( ZmqContext::GetContext(), ZMQ_REP ); 
	zmq_bind( skt, _addrest );
}
long RepSkt::BeginRecv( char* _buf, long _len )
{
	return api_zmq_recv( skt, _buf, _len );
}
void RepSkt::End( char* _buf, long _len )
{
	api_zmq_send( skt, _buf, _len );
}



PollItem::PollItem( ):mp_poll_item(0),len(0)
{
}

PollItem::~PollItem( )
{
	Uninit();
}

void PollItem::Init(std::vector< ZmqSkt* >* _skt )
{
	if( NULL == _skt)
		return;
	Uninit();
	len = _skt->size();
	zmq_pollitem_t *p_items = new zmq_pollitem_t[_skt->size()];
	for( int i=0; i<_skt->size(); ++i )
	{
		p_items[i].socket = (*_skt)[i]->GetContext();
		p_items[i].fd = 0;
		p_items[i].events = ZMQ_POLLIN;
	}
	mp_poll_item = p_items;
}

void PollItem::Uninit()
{
	if( 0 != mp_poll_item )
	{
		zmq_pollitem_t **p_items = (zmq_pollitem_t **)mp_poll_item;
		delete[] p_items;
		mp_poll_item = 0;
	}
}

void PollItem::WaitEvents()
{
	bool is_run = true;
	while( is_run )
	{
		zmq_pollitem_t *p_items = (zmq_pollitem_t *)mp_poll_item;
		int nRet = zmq_poll(p_items,len,-1);
		if(0 == nRet)
			continue;
		for( int i=0; i<len; ++i )
		{
			if( p_items[i].revents > 0 )
			{
				if( OnSktEvent(i) )
				{
					is_run = false;
				}
			}
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值