零消息队列(ZeroMQ)可以用来接受传统的套接字请求吗?

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套接字连接?
2个回答

16
您可以使用ZMQ_STREAM套接字来实现这一点。
请注意,自从ZeroMQ 4.x以来,已经将RAW路由器选项弃用,取而代之的是新的ZMQ_STREAM套接字类型,它与ROUTER + RAW的工作方式相同。
不过,看起来它还将进一步发展。
我最近在版本4.0.1中尝试了ZMQ_STREAM套接字。
您可以打开一个套接字,并使用zmq_rcv直到收到整个消息(您必须自己检查它是否完整),或者使用zmq_msg_rcv让ZeroMQ处理它。您将收到一个标识符消息部分,就像您在ROUTER套接字中找到的标识符一样,直接跟着一个只有一个正文部分。它们之间没有空分隔符,就像使用REQ套接字与ROUTER套接字交互时那样。因此,如果您要路由它们,请确保自己添加。
请注意:如果另一端存在延迟,或者您的消息超过了ZeroMQ ZMQ_STREAM缓冲区(我的缓冲区长度为8192个字节),则您的消息可能会被ZeroMQ解释为一系列消息。
在这种情况下,您将收到许多不同的ZeroMQ消息,包括标识符部分正文部分,并且需要聚合它们,知道如果有几个客户端正在与STREAM套接字交互,则它们可能会混淆。我个人使用哈希表,以二进制标识符作为键,并在知道消息完整并发送到下一个节点后从表中删除条目。

使用zmq_msg_sendzmq_send通过ZMQ_STREAM发送数据是没有问题的。


4

1
嘿@Raffian,谢谢,但不确定如何实现这个。没有原始的SocketType,你能提供一个例子吗? - Mark Kadlec
2
是的,这里有一个Pieter写的例子,http://hintjens.com/blog:42,它基本上是使用zmq原始套接字的HTTP服务器,它是用C编写的,但只要.net支持“RAW”套接字,你应该能够将其移植到.net上,我知道纯Java zmq库(jeromq)不支持...希望能对你有所帮助。 - raffian
感谢@Raffian,我无法直接链接到ZMQ库,因此我正在使用clrzmq,这是.Net的实现,因此可能不可能。 - Mark Kadlec

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接