czmq异步发送/接收(PUB / SUB)

时间:2016-03-02 16:13:14

标签: c++ ipc zeromq

我使用czmq进行进程间通信。

有两个过程:

  • 服务器,接收请求并发送回复,但也发送事件。
  • 客户端,发送请求和接收回复,但也听取事件。

我已经成功实施了"请求/回复" REQ / REP模式(详情如下)

现在我想实现通知机制。 我希望我的服务器发送它的事件而不关心是否有人收到它们而且没有被阻止。 客户端会监听这些事件,但如果崩溃,它不会对服务器产生任何影响。 我相信PUB / SUB是最合适的模式,但如果不是,请不要犹豫,启发我。

这是我的实施(从支票和日志中清除):

服务器发布事件

Server::eventIpcPublisher = zsock_new_pub("@ipc:///tmp/events.ipc");

void Server::OnEvent(uint8_t8* eventData, size_t dataSize) {
  if (Server::eventIpcPublisher != nullptr) {
    int retCode = zsock_send(Server::eventIpcPublisher, "b", eventData, dataSize);
}

客户端在专用线程中侦听它们

void Client::RegisterToEvents(const std::function<void(uint8_t*, size_t)>& callback) {
  zsock_t* eventIpcSubscriber = zsock_new_sub(">ipc:///tmp/events.ipc", "");
  listening = true;
  while (listening) {
    byte* receptionBuffer;
    size_t receptionBufferSize;
    int retCode = zsock_recv(eventIpcSubscriber, "b", &receptionBuffer, &receptionBufferSize);
    --> NEVER REACHED <--
    if (retCode == 0) {
      callback(static_cast<uint8_t*>(receptionBuffer), receptionBufferSize);
    }
  }
  zsock_destroy(&eventIpcSubscriber);
}

它不起作用:

  • 服务器发送返回码为0,好像一切正​​常,
  • 客户端未收到任何内容(收到时被阻止)。

非常感谢帮助,提前谢谢!

克里斯。

PS:这是我已成功实施的REQ / REP(此处无需帮助,只是为了理解)

客户端发送请求,然后等待答案。

uint8_t* MulticamApi::GetDatabase(size_t& sizeOfData) {
  zsock_t* requestSocket = zsock_new_req(">ipc:///tmp/requests.ipc");
  if (requestSocket == nullptr)
    return nullptr;
  byte* receptionBuffer;
  size_t receptionBufferSize;
  int retCode = zsock_send(requestSocket, "i", static_cast<int>(IpcComm_GetClipDbRequest));
  if (retCode != 0) {
    sizeOfData = 0;
    return nullptr;
  }
  retCode = zsock_recv(requestSocket, "b", &receptionBuffer, &receptionBufferSize);
  databaseData.reset(new MallocGuard(static_cast<void*>(receptionBuffer)));
  sizeOfData = receptionBufferSize;
  return static_cast<uint8_t*>(databaseData->Data());
}

服务器中的专用线程侦听请求,处理请求并回复。 (别担心,删除会在其他地方处理)

U32 Server::V_OnProcessing(U32 waitCode) {
  protocolIpcWriter = zsock_new_rep("@ipc:///tmp/requests.ipc");
  while (running) {
    int receptionInt = 0;
    int retCode = zsock_recv(protocolIpcWriter, "i", &receptionInt);
    if ((retCode == 0) && (receptionInt == static_cast<int>(IpcComm_GetClipDbRequest))) {
      GetDatabase();
    }
    sleep(1);
  }
  zsock_destroy(&protocolIpcWriter);
  return 0;
}

void Server::GetDatabase() {
  uint32_t dataSize = 10820 * 340;
  uint8_t* data = new uint8_t[dataSize];
  uint32_t nbBytesWritten = DbHelper::SaveDbToBuffer(data, dataSize);
  int retCode = zsock_send(protocolIpcWriter, "b", data, nbBytesWritten);
}

1 个答案:

答案 0 :(得分:0)

我知道我的问题已经很老了,但为了记录,我从czmq切换为基础zmq api,一切顺利。我的一位同事在czmq层上也遇到了问题,因此改用zmq进行修复,因此绝对是我的建议。