CMsgComm

#ifndef CMSGCOMM_H
#define CMSGCOMM_H

#pragma once

#include <msg/MsgExport.h>
#include <msg/CMsg.h>
#include <vector>
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/serialization/singleton.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/atomic.hpp>
#include <list>
#include "pub_utility_api/TimeUtil.h"
#include "pub_logger_api/logger.h"
#include "public/MessageDef.h"


namespace kbd_msg {
class CMsgMng;
class MSG_API CMsgComm
{

public:
/**********************************************************************************
* @brief 构造函数
* @param pchName:为通讯器指定名称,若为NULL或字符为空则自动生成UUID作为名称。
* @return
* @retval
**********************************************************************************/
CMsgComm();
~CMsgComm();


/**********************************************************************************
* @brief 添加订阅频道ID
* @param channelID:订阅频道ID
* @return
* @retval
**********************************************************************************/
void addSub(int channelID);

/**********************************************************************************
* @brief 移除订阅频道ID
* @param channelID:订阅频道ID
* @return
* @retval
**********************************************************************************/
void removeSub(int channelID);

/**********************************************************************************
* @brief 获取当前订阅频道ID
* @param
* @return 获取当前订阅频道ID的集合(vector)
* @retval
**********************************************************************************/
std::vector<int> getSub();

/**********************************************************************************
* @brief 发送消息,异步非阻塞
* @param channelID:订阅频道ID
* msg:消息
* @return 返回值为true不代表消息已经发送到对方,只代表通讯器已经发送到通讯模块,未必已经发送成功
* 返回值为false,表示消息未发送到通讯模块,调用lastError()查看错误消息
* @retval
**********************************************************************************/
bool send(CMsgPtr msgSend);
bool add(CMsgPtr msgSend);
bool send();
/**
* @brief recv 接收一条消息
* @param msgRecv 消息
* @return
*/
bool recv(CMsgPtr &msgRecv);
/**********************************************************************************
* @brief 接收订阅频道中的消息,阻塞
* @param msgRecv:消息
* nTimeoutMSecs:超时时间
* @return 收到消息立刻返回,或者最长等待到超时。
* @retval 超时时间内收到消息返回true,否则返回false。调用lastError()查看错误消息
**********************************************************************************/
bool recv(CMsgPtr &msgRecv,int nTimeoutMSecs);
/**
* @brief recv 批量接收订阅频道中的消息,阻塞
* @param enMsgType 消息类型
* @param msgRecvVec 消息
* @return
*/
bool recv(EnMsgType enMsgType, std::vector<CMsgPtr> &msgRecvVec);
/**
* @brief recv 批量接收订阅频道中的消息,阻塞
* @param enMsgType 消息类型
* @param msgRecvVec 消息
* @param nTimeoutMSecs 超时时间
* @return
*/
bool recv(EnMsgType enMsgType, std::vector<CMsgPtr> &msgRecvVec, int nTimeoutMSecs);
/**********************************************************************************
* @brief 获取上一次的错误
* @param
* @return 返回错误信息的文本
* @retval
**********************************************************************************/
std::string lastError();


void insertMsg(CMsgPtr msg);
void insertVecMsg(std::list<CMsgPtr> &listMsg);
std::list<CMsgPtr> m_msgList;
private:
//to-do
typedef boost::shared_lock<boost::shared_mutex> read_lock;
typedef boost::unique_lock<boost::shared_mutex> write_lock;
boost::shared_mutex read_write_mutex;
boost::atomics::atomic_int m_listSize;
std::map<int,std::list<CMsgPtr> > m_addMsgMap;
};
typedef boost::serialization::singleton<kbd_msg::CMsgMng> CMsgMngInst;
typedef std::vector<CMsgPtr> CMSgPtrVec;
} //< namespace kbd_msg

#endif // CMSGCOMM_H

 

 

 

#include <msg/CMsgComm.h>
#include "msg/CMsgMng.h"
#include "public/pub_utility_api/TimeUtil.h"

using namespace kbd_public;

kbd_msg::CMsgComm::CMsgComm()
{
m_listSize = 0;
}

kbd_msg::CMsgComm::~CMsgComm()
{
write_lock rlock(read_write_mutex);
m_msgList.clear();
}

void kbd_msg::CMsgComm::addSub(int channelID)
{
CMsgMngInst::get_mutable_instance().addSub(channelID, this);
}

void kbd_msg::CMsgComm::removeSub(int channelID)
{
CMsgMngInst::get_mutable_instance().removeSub(channelID, this);
}

std::vector<int> kbd_msg::CMsgComm::getSub()
{
return std::vector<int>();
}

bool kbd_msg::CMsgComm::send(CMsgPtr msgSend)
{
return CMsgMngInst::get_mutable_instance().send(msgSend);
}
bool CMsgComm::add(CMsgPtr msgSend)
{
int nChanNo = msgSend->getChannelID();
int type = msgSend->getType();
if (nChanNo == -1 || type == -1)
{
LOGERROR("添加消息失败,通道:%d,消息类型:%d", nChanNo, type);
return false;
}
std::map<int,std::list<CMsgPtr> >::iterator it = m_addMsgMap.find(nChanNo);
if(it != m_addMsgMap.end())
{
std::list<CMsgPtr> &itList = it->second;
itList.push_back(msgSend);
}else
{
std::list<CMsgPtr> itList;
itList.push_back(msgSend);
m_addMsgMap.insert(std::make_pair(nChanNo,itList));
}
return true;
}

bool CMsgComm::send()
{
return CMsgMngInst::get_mutable_instance().send(m_addMsgMap);
}

bool CMsgComm::recv(CMsgPtr &msgRecv)
{
if (m_listSize == 0)
{
return false;
}

write_lock rlock(read_write_mutex);
if (m_msgList.size() != 0)
{
msgRecv = m_msgList.front();
m_msgList.pop_front();
m_listSize =(int)m_msgList.size();
return true;
}
return false;
}

bool kbd_msg::CMsgComm::recv(CMsgPtr &msgRecv, int nTimeoutMSecs)
{
int64 beginTime = getUTCTimeMsec();
int64 endTime = beginTime;
while (true)
{
if (recv(msgRecv))
{
return true;
}

endTime = getUTCTimeMsec();
if (endTime - beginTime > nTimeoutMSecs)
{
break;
}
else
{
if(nTimeoutMSecs<50)
{
Sleep(nTimeoutMSecs);
}
else
{
Sleep(50);
}
}
}
return false;
}

bool CMsgComm::recv(EnMsgType enMsgType, std::vector<CMsgPtr> &msgRecvVec)
{
if (m_listSize == 0)
{
return false;
}

write_lock rlock(read_write_mutex);
if (m_msgList.size() != 0)
{
std::list<CMsgPtr>::iterator itList = m_msgList.begin();
for (; itList != m_msgList.end();)
{
if ((*itList)->getType() == enMsgType)
{
msgRecvVec.push_back(*itList);
itList = m_msgList.erase(itList++);
}
else
{
++itList;
}
}
m_listSize = (int)m_msgList.size();
if (msgRecvVec.empty())
{
return false;
}
return true;
}
return false;
}

bool CMsgComm::recv(EnMsgType enMsgType, std::vector<CMsgPtr> &msgRecvVec, int nTimeoutMSecs)
{
int64 beginTime = getUTCTimeMsec();
int64 endTime = beginTime;
while (true)
{
if (recv(enMsgType,msgRecvVec))
{
return true;
}

endTime = getUTCTimeMsec();
if (endTime - beginTime > nTimeoutMSecs)
{
break;
}
else
{
if(nTimeoutMSecs<50)
{
Sleep(nTimeoutMSecs);
}
else
{
Sleep(50);
}
}
}
return false;
}

std::string kbd_msg::CMsgComm::lastError()
{
return std::string();
}

void kbd_msg::CMsgComm::insertMsg(kbd_msg::CMsgPtr msg)
{
write_lock rlock(read_write_mutex);
if (m_msgList.size() >= 1000000)
{
m_msgList.clear();
LOGERROR("接收消息队列中的消息数量大于1000000条,请处理!");
//assert(false);
}
m_msgList.push_back(msg);
m_listSize = (int)m_msgList.size();
}

void CMsgComm::insertVecMsg(std::list<CMsgPtr> &listMsg)
{
write_lock rlock(read_write_mutex);
std::list<CMsgPtr>::iterator it =listMsg.begin();
for(;it != listMsg.end();++it)
{
if (m_msgList.size() >= 1000000)
{
m_msgList.clear();
LOGERROR("接收消息队列中的消息数量大于1000000条,请处理!");
//assert(false);
}
m_msgList.push_back(*it);
m_listSize = (int)m_msgList.size();
}
}

posted on 2019-10-23 10:56  码农er  阅读(152)  评论(0)    收藏  举报