117 lines
2.6 KiB
C++
117 lines
2.6 KiB
C++
#include "CVrZeroMQPubSub.h"
|
|
#include <thread>
|
|
#include <string>
|
|
#include "VrLog.h"
|
|
|
|
// ========== 发布者实现 ==========
|
|
bool IVrZeroMQPublisher::CreateObject(IVrZeroMQPublisher** ppPublisher)
|
|
{
|
|
*ppPublisher = new CVrZeroMQPublisher();
|
|
return true;
|
|
}
|
|
|
|
CVrZeroMQPublisher::CVrZeroMQPublisher()
|
|
{
|
|
m_pContext = new zmq::context_t;
|
|
m_pSocket = new zmq::socket_t(*m_pContext, ZMQ_PUB);
|
|
}
|
|
|
|
CVrZeroMQPublisher::~CVrZeroMQPublisher() {}
|
|
|
|
int CVrZeroMQPublisher::Init(int nPort)
|
|
{
|
|
try {
|
|
std::string addr = "tcp://*:" + std::to_string(nPort);
|
|
LOG_DEBUG("zeroMQ: %s \n", addr.c_str());
|
|
m_pSocket->bind(addr);
|
|
return 0;
|
|
}
|
|
catch (const zmq::error_t& e) {
|
|
LOG_ERROR("ZeroMQ bind failed: %s\n", e.what());
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
int CVrZeroMQPublisher::Publish(const char* pTopic, const char* pData, const size_t nLen)
|
|
{
|
|
size_t topicLen = strlen(pTopic);
|
|
zmq::message_t topicMsg(topicLen);
|
|
memcpy(topicMsg.data(), pTopic, topicLen);
|
|
m_pSocket->send(topicMsg, zmq::send_flags::sndmore);
|
|
|
|
zmq::message_t dataMsg(pData, nLen);
|
|
m_pSocket->send(dataMsg, zmq::send_flags::none);
|
|
return 0;
|
|
}
|
|
|
|
int CVrZeroMQPublisher::UnInit()
|
|
{
|
|
delete m_pSocket;
|
|
delete m_pContext;
|
|
m_pSocket = nullptr;
|
|
m_pContext = nullptr;
|
|
return 0;
|
|
}
|
|
|
|
// ========== 订阅者实现 ==========
|
|
bool IVrZeroMQSubscriber::CreateObject(IVrZeroMQSubscriber** ppSubscriber)
|
|
{
|
|
*ppSubscriber = new CVrZeroMQSubscriber();
|
|
return true;
|
|
}
|
|
|
|
CVrZeroMQSubscriber::CVrZeroMQSubscriber()
|
|
: m_bRecv(false), m_funRecv(nullptr)
|
|
{
|
|
m_pContext = new zmq::context_t;
|
|
m_pSocket = new zmq::socket_t(*m_pContext, ZMQ_SUB);
|
|
}
|
|
|
|
CVrZeroMQSubscriber::~CVrZeroMQSubscriber() {}
|
|
|
|
int CVrZeroMQSubscriber::Init(const char* sIP, int nPort, const char* pTopic, FunSubRecv funRecv)
|
|
{
|
|
std::string addr = "tcp://" + std::string(sIP) + ":" + std::to_string(nPort);
|
|
m_pSocket->connect(addr);
|
|
m_pSocket->set(zmq::sockopt::subscribe, pTopic);
|
|
|
|
m_funRecv = funRecv;
|
|
m_bRecv = true;
|
|
std::thread recvThread(&CVrZeroMQSubscriber::_RecvData, this);
|
|
recvThread.detach();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int CVrZeroMQSubscriber::UnInit()
|
|
{
|
|
m_bRecv = false;
|
|
delete m_pSocket;
|
|
delete m_pContext;
|
|
m_pSocket = nullptr;
|
|
m_pContext = nullptr;
|
|
return 0;
|
|
}
|
|
|
|
void CVrZeroMQSubscriber::_RecvData()
|
|
{
|
|
while (m_bRecv)
|
|
{
|
|
zmq::message_t topicMsg;
|
|
zmq::recv_result_t ret1 = m_pSocket->recv(topicMsg, zmq::recv_flags::dontwait);
|
|
if (!ret1.has_value()) continue;
|
|
|
|
zmq::message_t dataMsg;
|
|
zmq::recv_result_t ret2 = m_pSocket->recv(dataMsg, zmq::recv_flags::dontwait);
|
|
if (!ret2.has_value()) continue;
|
|
|
|
if (m_funRecv)
|
|
{
|
|
m_funRecv(static_cast<char*>(topicMsg.data()),
|
|
topicMsg.size(),
|
|
static_cast<char*>(dataMsg.data()),
|
|
dataMsg.size());
|
|
}
|
|
}
|
|
}
|