ZeroMQ(NetMQ)TCP传输可以在同一进程中在发布者和订阅者之间使用吗?

时间:2018-05-23 13:58:02

标签: c# .net zeromq netmq

我认为这个问题确实存在。

对于一些背景知识,我有一个订阅者,我正在尝试为其编写一些测试。为了做到这一点,我在测试中启动了一个发布者,指定tcp://localhost:[port]作为地址。发送消息时,订户无法接收消息。以下是一些示例代码:

   string address   =    "tcp://localhost:1026";
// string address   = "inproc://localhost1026";

   var    pubSocket =  new PublisherSocket();
   pubSocket.Bind(address);

   var subSocket = new SubscriberSocket();
   subSocket.Connect(address);
   subSocket.SubscribeToAnyTopic();

   pubSocket.SendFrame("Hello world!", false);

   Console.WriteLine(subSocket.ReceiveFrameString()); /* <-- tcp transport 
                                                         waits here forever
                                                         */
   subSocket.Dispose();
   pubSocket.Dispose();

如果我将协议更改为inproc://,那么一切都很顺利。但是,我不想在我的测试中执行此操作,因为我还想测试一个监视器套接字,这不会引发 inproc:// 连接的事件(如我可以看到。)

请注意,我使用的是C#代码中的NetMQ(在.NET Framework 4.6.2下运行)。

2 个答案:

答案 0 :(得分:3)

O / P值得 +1 用于发布所用.NET的版本号。干得好,先生。

  

可以在同一进程中在发布者和订阅者之间使用ZeroMQ(NetMQ)TCP传输吗?

当然,没有限制阻止人们这样做。 。

您的观察与隐藏处理的延迟有关,这种延迟发生在主引擎内......在ZeroMQ Context() 实例内。

事情不会发生在零时间,对不起,不要(甚至(差不多) - 像大爆炸这样的魔法棒球确实采取了一段时间来实例化我们真实的宇宙...最好阅读一本关于此的真实侦探书,由Steven WEINBERG发表:前三分钟,宇宙起源的现代观点 - 必读的人会爱上。

嗯,有人可能会选择在Pieter HINTJENS&#39;之后推迟这一个。一,&#34; 代码已连接,第1卷&#34;关于ZeroMQ Zen-of-Zero 。这很有道理,很有意义,不仅仅是在这里。)

所以,虽然 inproc:// 传输类具有(几乎) -zero-resources,但它们是纯粹的私有 - &#34;进程中& #34;内存映射抽象(当然,除了一些 sub - [ns] - &#34;设备&#34;像信号量/锁定),ZeroMQ基础设施启动并运行&#34;立即&#34; -fashion, tcp:// 没有这种安慰,因为它必须首先使用O / S生成所有与运输类特定的合同-driver(s),实例化传输类特定的ISO / OSI- {L0,L1,L3,L3 +}处理策略,将相应的数据泵代码实例化为Context()的RTO状态,分配和映射内存缓冲区以实现这些目的,所以要做很多工作,在 PUB -side进入RTO状态之前(在更新的情况下) ~API 4. +)的版本还有义务接收处理订阅服务 - 遥测,因为它承担着对每个 SUB -client TOPIC-filterlist处理。

这是为什么导致在<{1}}的NetMQ包装抽象中隐藏 .recv( ..., ZMQ_BLOCK )

要测试它,只需进行修改后的测试:

subSocket.ReceiveFrameString()

可以进行更多努力并在此进行实验,以了解 // --------------------------------------------------- // DEMO PSEUDO-CODE string rF = ""; while True: pubSocket.SendFrame( "Hello world!", false ); // keep sending ... // also may count++ // so as to "show" how // many loops it took rF = subSocket.ReceiveFrameString( false ); // non-blocking mode ~ // .recv( ZMQ_NOBLOCK ) // or may use Poll() // to just sniff for // a message presence if rF == "": continue; // ---^ LOOP NEXT, AS DID .recv() NOTHING YET break; // ----------v BREAK AS DID .recv() MESSAGE // ---------------------------------------------------------------------- Console.WriteLine( rF ); 相关费用的关键作用,但也不必错过 {{1} - 在设置订阅时发出信号的遥测信号+接收它的需要+在 .connect() 旁边重新处理它,然后在任何消息首次发送之前发送给预期的,否则只是&#34; 永远&#34; -waiting,SUB

PUB 之后,@HesamFaridmehr已经提出了&#34;胖&#34; -enough SUB - side有.sleep( someGuestimateTIME ) - ed加上它SUB(必须首先发送并在 .connect() 上以正当方式处理 - side(正确配置TOPIC过滤器列表处理器处理器))在第一个.setsockopt( ZMQ_SUBSCRIBE ) 之前足够好,屏蔽根本原因它&#34;间接&#34;阻止和代码执行流程停止,而不是使解决方案足够聪明 - 使用非阻塞形式的 PUB - 专业人士设计了最佳实践,其中一个人确实可以遵守装配黑客所钟爱的第一行宏 PUB.send()

答案 1 :(得分:2)

因为pub/sub模式就像无线电一样。发布者不会等待用户连接,如果没有用户,它将忽略发送。您只需在Thread.Sleep(1000);行之后添加subSocket.SubscribeToAnyTopic();即可测试,您会看到您将收到该消息。

inproc中,绑定时间少于tcp,这就是您收到邮件的原因

inproc,发布商应该在订阅者连接之前启动