如何在桌面应用程序中使用 zeroMQ

How to use zeroMQ in Desktop application

我在桌面应用程序中工作,该应用程序部署在 windows 和 mac 平台上。作为应用程序的一部分,它应该与本地层进行通信。目前本机层和 Java 层之间的通信是使用套接字完成的。最近团队中有人建议使用 zeroMQ。有哪位大侠能解答一下我的疑惑吗

  1. zeroMQ 比套接字好在哪里
  2. 是否可以安装 zeroMQ 库作为桌面客户端安装的一部分
  3. 我浏览了 link“https://github.com/zeromq/clrzmq4”,它提供了特定于 amd64 和 i386 处理器系列的库。我是否需要为不同的处理器从源代码中单独构建它?
  4. 我还需要 .dll 文件才能在 Java 中使用 zeroMQ 吗?
  5. 我是否需要 Visual studio 在 windows 中构建 zeroMQ 库(因为我的本机层是用 C# 编写的,所以我的 C# 应用程序与编写的 zeroMQ 套接字套接字通信 java)?
  1. zeroMQ 比套接字好在哪里

    http://zeromq.org/topics:omq-is-just-sockets

  2. 是否可以安装 zeroMQ 库作为桌面客户端安装的一部分?

    是的,您需要构建依赖于处理器的库并将它们嵌入到您的应用程序中。

  3. 是否需要针对不同的处理器从源代码中单独构建它?

    是的,您需要从源代码构建库。 zeroMQ 以处理器为中心。

  4. 我是否仍然需要 .dll 文件才能在 Java 中使用 zeroMQ? 是的,关注 link 可能会对您有所帮助

    Exception in thread "main" java.lang.UnsatisfiedLinkError: ... \jzmq.dll: Can't find dependent libraries

  5. 我需要 Visual studio 在 windows 中构建 zeroMQ 库吗?

这个link可能会帮助您获得基本示例。

关于 Windows 桌面应用程序中的 ZeroMQ 与同一台机器上的另一个进程通信,请记住 zmq_ipc 不受支持(参见 zmq_ipc(7))。或者至少,那是我最后一次听到。这是因为根本不可能为 Windows 中的命名管道实现类似 select() 或 epoll() 的任何东西。只需使用 zmq_tcp 即可。

相同的基本问题困扰着 Cygwin 及其衍生产品中 select() 实现的开发。他们通过为每个 non-socket 文件描述符(即命名管道、串行端口等)启动一个线程来解决这个问题 selected,每个线程轮询 HANDLE 是否有任何数据到达(或select() 中设置的任何事件)。效率不高。耶克。

Proactor 与 Reactor

Windows是proactor(只能做proactor),其他的(*nix,VxWorks)都是reactor(也可以用来实现proactor)。 C++ 的 boost.asio 库的开发受此影响,结果是一个 proactor 设计,因此它可以 运行 on Windows。 RabbitMQ 也是前摄器。

ZeroMQ with zmq_poll() 是反应器。

Proactor - 你 pro-actively 启动一个异步例程来处理将来出现的任何事情。

Reactor - 您可以通过同步调用您希望处理的任何例程来对出现的任何情况做出反应,因为知道它会很快完成,因为数据已经存在。

区别是关键。在前摄器设计中,一旦您启动了异步例程来读取消息,您就不能(轻易地)停止它或更改它,直到它完成它的事情。如果您改变主意,例如由于从其他地方阅读了一些消息,这将非常烦人。

小警告 - Windows 确实支持 select() 用于网络套接字(因此反应器编程可以使用网络套接字,但仅限于网络套接字),并且是支持 ZMQ 的唯一原因Windows 上的任何程度。

将 ZMQ 与桌面应用程序事件回调混合

无论如何,proactor 意味着 Windows 并且 C# 从根本上期望一切都由回调提供服务。这基本上意味着如果您还有处理 GUI 事件的回调,您将不会使用 zmq_poll() 调用来告诉您是否有新消息到达。相反,您很可能会异步调用 zmq_revcmsg()。试图将 zmq_poll() 与回调混合在一起是自找麻烦(你会混合前摄器和反应器)。

消息格式

ZeroMQ 和套接字都传输字节(作为 ZeroMQ 的离散消息,作为套接字的字节流)。人们仍然面临着决定字节对应用程序意味着什么的挑战。

我可以推荐使用 Google 协议缓冲区之类的东西来序列化消息以供 ZeroMQ 传输。它可用于 C# 和 Java,但它不划分消息边界。幸运的是,ZeroMQ 可以。 [在套接字流上使用 GPB 可能很痛苦,您必须自己划定消息边界]。因此,您可以将消息序列化到缓冲区,将缓冲区作为消息移交给 ZeroMQ,接收者收到消息并绝对确定其中有一个单独的 GPB。如果您愿意,可以使用 GPB 的 "oneof" 来走私任意消息类型,这会非常自由。当然,您也可以使用其他序列化技术实现同样的效果,我个人最喜欢的是 ASN.1。