8

我正在尝试使用 ZeroMQ 重写我们的旧服务器之一,现在我有以下服务器设置(适用于 Zmq 请求):

    using (var context = ZmqContext.Create())
    using (var server = context.CreateSocket(SocketType.REP)) {
        server.Bind("tcp://x.x.x.x:5705");

        while (true) { ... }

如果我使用 Zmq 客户端库进行连接,这种设置可以正常工作context.CreateSocket(SocketType.REQ)

但不幸的是,我们有很多遗留代码需要连接到这个服务器,并且套接字是使用 .net 套接字库创建的:

    Socket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
    Socket.Connect(ipAddress, port);

有没有办法编写一个 ZeroMQ 服务器来接受这些传统的 .net 套接字连接?

4

2 回答 2

15

您可以使用ZMQ_STREAM 套接字来实现这一点。

请注意,自 zeroMQ 4.x 以来,RAW 路由器选项已被弃用,用于新的 ZMQ_STREAM 套接字类型,其工作方式与 ROUTER + RAW 相同。

不过,它似乎必然会发展。

我最近在 4.0.1 版本中尝试了 ZMQ_STREAM 套接字。

您可以打开一个,使用zmq_rcv直到收到整个消息(您必须自己检查它是否完整),或者zmq_msg_rcv让 ZeroMQ 处理它。您将收到一个标识符消息部分,就像您在套接字中找到的标识符ROUTER一样,紧随其后的是一个唯一的 正文部分。它们之间没有空分隔符,就像使用REQSocket 与ROUTERSocket 通信一样。因此,如果您路由它们,请务必自己添加。

但请注意:如果另一端存在延迟,或者您的消息超出 ZeroMQZMQ_STREAM缓冲区(我的缓冲区长度为 8192 字节),则 zeroMQ 可以将您的消息解释为一系列消息。

在这种情况下,您将收到尽可能多的不同 ZeroMQ 消息,包括标识符部分正文部分,并且您的工作是聚合它们,知道如果有多个客户端正在与STREAM套接字通信,它们可能会混淆。我个人使用使用二进制标识符作为键的哈希表,并在我知道消息完成并发送到下一个节点时从表中删除条目。

通过ZMQ_STREAMwith zmq_msg_sendor发送zmq_send可以正常工作。

于 2013-12-04T16:34:40.383 回答
4

您可能必须使用 zmq 的 RAW 套接字类型(而不是 REP)来连接和读取客户端数据,而无需 zmq 特定的框架。

C 中的 HTTP 服务器(来自 Pieter 的博客)
http://hintjens.com/blog:42

原始套接字类型信息
https://github.com/hintjens/libzmq/commit/777c38ae32a5d1799b3275d38ff8d587c885dd55

于 2013-06-18T20:34:09.243 回答