当订阅者在发布者之前启动时,ZeroMQ PUB / C#SUB不起作用

时间:2017-11-05 17:26:57

标签: c# zeromq

当运行ZeroMQ基本PUB / SUB C#样本时,如果我先启动发布者,他们正在为我工​​作,但如果我先启动订阅者则不行。当我这样做时,订户启动,但从不接收任何数据。根据我的阅读,我认为我应该能够以任何顺序启动流程。

我在.NET 4.6,x64应用程序中使用nuget的ZeroMQ 4.1.0.26软件包。这些都在Windows上运行。我在同一台机器上运行这两个应用程序。

以下是我正在运行的代码(这是ZeroMQ教程中示例的简化版本)。

订户:

    static void Main(string[] args)
    {
        var endpoint = "tcp://127.0.0.1:5556";

        // Socket to talk to server
        using (var context = new ZContext())
        using (var subscriber = new ZSocket(context, ZSocketType.SUB))
        {
            Console.WriteLine("I: Connecting to {0}…", endpoint);
            subscriber.Connect(endpoint);

            // Subscribe to zipcode
            string zipCode = "90210 ";
            Console.WriteLine("I: Subscribing to zip code {0}…", zipCode);
            subscriber.Subscribe(zipCode);

            while(true)
            {
                using (var replyFrame = subscriber.ReceiveFrame())
                {
                    string reply = replyFrame.ReadString();
                    Console.WriteLine(reply);
                }
            }
        }
    }

出版商:

    static void Main(string[] args)
    {
        using (var context = new ZContext())
        using (var publisher = new ZSocket(context, ZSocketType.PUB))
        {
            var address = "tcp://*:5556";
            Console.WriteLine("I: Publisher.Bind'ing on {0}", address);
            publisher.Bind(address);

            // Initialize random number generator
            var rnd = new Random();
            while (true)
            {
                // Get values that will fool the boss
                int zipcode = 90210;
                int temperature = rnd.Next(-55, +45);

                // Send message to all subscribers
                var update = string.Format("{0:D5} {1}", zipcode, temperature);
                using (var updateFrame = new ZFrame(update))
                {
                    publisher.Send(updateFrame);
                }

                Thread.Sleep(1000);
            }
        }
    }

修改

根据以下建议答案中的建议,我尝试了:

  • 使用明确的IP地址:这使没有差异
  • 删除主题过滤:这使没有差异
  • 创建新的AnyCPU(而非x64)项目:这使没有差异
  • 尝试其他语言:这很有趣!

使用Python等效发布者和订阅者:

  • Python用户在发布者之前启动时,在连接到Python发布者或C#发布者时起作用。
  • C#订阅者在发布者之前启动时无效,无论它是否连接到Python或C#发布者。

所以看起来C#订阅者代码有问题。

问题:

  • 我的示例代码(下面的最新版本)有问题吗?

  • 或者这是ZeroMQ .NET库的问题吗?

以下是正常工作的Python订阅者

import sys
import zmq

#  Socket to talk to server
context = zmq.Context()
socket  = context.socket( zmq.SUB )

print( "Python: Collecting updates from weather server" )
socket.connect( "tcp://localhost:5556" )

socket.setsockopt_string( zmq.SUBSCRIBE, "" )

while True:
    string = socket.recv_string()
    zipcode, temperature = string.split()
    print( zipcode + " " + temperature )

以下是C#订阅者的最新等效版本(非工作):

static void Main(string[] args)
{
    // Socket to talk to server
    using (var context = new ZContext())
    using (var socket = new ZSocket(context, ZSocketType.SUB))
    {
        Console.WriteLine("C#: Collecting updates from weather server");
        socket.Connect("tcp://localhost:5556");
        socket.Subscribe("");

        while (true)
        {
            using (var replyFrame = socket.ReceiveFrame())
            {
                string reply = replyFrame.ReadString();
                Console.WriteLine(reply);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

如果您按照步骤the flow-chart re-published here进行操作, PUB/SUB 的问题会突出显示。

最近(EoY-2017)API v4.x重新设计工作改变了一些设计方法(主题过滤器是否在 SUB -side上处理,因为它是自v2.1 +起,或者在较新的API版本中 - 在 PUB 旁边 - 反转开销分配/集中,违规流量缓冲+流量/处理 - 但是,PUB/SUB操作顺序似乎保持不变(参见上面提到的流程图)。

事后根本原因隔离测试:

Python SUB正常工作,我的C#没有。不明白为什么:

感谢有效的代码重新测试,这有助于在根本原因歧视中向前迈出几步。

现在让我们关注为什么:

ZeroMQ通常有两个抽象层, ZeroMQ内部,实现框架的核心功能,如ZeroMQ协议RFC规范中所定义。这是负责所有RFC定义的交互变得兼容和交叉兼容的部分,以便以ZeroMQ发布的方式提供服务。

另一层由 “foreign” - 语言包装器/ API绑定构成,可帮助其他语言(ZeroMQ内部代码非本地语言)使用ZeroMQ API为任何特定的第三方语言中介提供的服务,以便“外国”世界有机会在内部ZeroMQ层的世界内调用由库实现的服务。

因此,差异被隔离使用python SUB -probe(运行良好,如定义)到C#语言绑定< / strong>,其中SUB - 探测仍无法正常工作。

正如Dijkstra在测试中指出的那样,一些测试按预期工作的事实并不意味着系统中没有其他错误/错误,绑定可能会有一些问题,但是来自python {{ 1}} - 客户端表明,ZeroMQ核心服务不会因导致错误而受到指责。

A1:不,

您的代码似乎没问题。

A2:是的,

如上所述,这是主要的嫌疑人ATM

向C#绑定维护者报告请求以修复ZeroMQ不符合的行为,在上面观察和重新测试的完整详细信息中记录,最好的下一步来帮助不合规C#绑定无需工作。