【问题标题】:How to use ZMQ when Server on IP other than the client当服务器在 IP 而非客户端时如何使用 ZMQ
【发布时间】:2016-06-08 15:37:33
【问题描述】:

我学会了如何在 localhost 上使用 ZeroMQ,但我在远程 IP 上没能做到。

Q1: 我需要经纪人吗?
如果需要,
Q2: 哪个经纪人以及如何做?


更新:

好的。我正在使用 ZMQ Weather Update 示例,但使用远程 IP(不是 localhost )。这是我使用 C# ZMQ 绑定所做的(不过,我可以使用任何其他语言):

ZMQ 服务器:

using (var context = new ZContext())
using (var publisher = new ZSocket(context, ZSocketType.PUB))
{
    string address = "tcp://*:5001";

    publisher.Bind(address);

    publisher.Send("msg")
}

代理:

using (var context  = new ZContext())
using (var frontend = new ZSocket(context, ZSocketType.XSUB))
using (var backend  = new ZSocket(context, ZSocketType.XPUB))
{
    // Frontend is where the weather server sits
    string localhost = "tcp://127.0.0.1:5001";
    Console.WriteLine("I: Connecting to {0}", localhost);

    frontend.Connect(localhost);

    // Backend is our public endpoint for subscribers
    string remoteIP = "216.123.23.98";                          // For example
    var tcpAddress = string.Format("tcp://{0}:8100", remoteIP); // I also tried localhost address here

    Console.WriteLine("I: Binding on {0}", tcpAddress);

    backend.Bind(tcpAddress);

    var epgmAddress = string.Format("epgm://localhost;{0}:8100", remoteIP);

    Console.WriteLine("I: Binding on {0}", epgmAddress);

    backend.Bind(epgmAddress);

    using (var subscription = ZFrame.Create(1))
    {
        subscription.Write(new byte[] { 0x1 }, 0, 1);
        backend.Send(subscription);
    }

    // Run the proxy until the user interrupts us
    ZContext.Proxy(frontend, backend);
}

客户:

using (var context    = new ZContext())
using (var subscriber = new ZSocket(context, ZSocketType.SUB))
{
    string remoteIP = "tcp://216.123.23.98";              //For example
    Console.WriteLine("I: Connecting to {0}…", remoteIP);

    subscriber.Connect(connect_to);

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

    subscriber.Subscribe(zipCode);

    // Process 10 updates
    int i = 0;
    long total_temperature = 0;
    for (; i < 20; ++i)
    {
        ZError err;
        using (var replyFrame = subscriber.ReceiveFrame(out err))
        {
            string reply = replyFrame.ReadString(Encoding.ASCII);

            Console.WriteLine(reply);
            total_temperature += Convert.ToInt64(reply.Split(' ')[1]);
        }
    }
    Console.WriteLine("Average temperature for zipcode '{0}' was {1}", zipCode, (total_temperature / i));
}

当我运行它时,我在 Server 中出现错误,在 proxy 中出现错误 - server gets

Invalid end point

并且代理得到EINVAL(22):

Invalid argument at ZeroMQ.ZSocket.Bind(String endpoint)

【问题讨论】:

  • 远程和本地应该没有区别。它是如何失败的?错误消息、MCVE 等?
  • StackOverflow 鼓励用户发布 MCVE-代码连同所有输出和错误消息 - 原样来自控制台输出。而是保持这一惯例,因为政策执行者有时会对帖子采取纠正措施,这不符合这种公平和普遍的做法。

标签: zeromq pyzmq jzmq


【解决方案1】:

A1: 不,ZeroMQ 是一个无代理的消息传递框架。

A2: 不适用


如何修复代码?

所有服务都需要遵守各自的传输类寻址规则,对于 TCP/IP 情况 - .bind() / .connect() 方法都必须声明IP:PORT# 规范的两个部分(IP-part 的 DNS 解析提供了一些帮助,但 :PORT#-part 仍然是强制性的)

(源代码在客户端中不符合,参考:

 subscriber.Connect(connect_to);

而还应该有一个Proxy-side 匹配:PORT#,即指定:8100,以获得正确的.connect())。

为了清楚起见并避免 port# 冲突,请从代码中删除 epgm 传输类。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 2010-11-16
    • 2015-05-21
    • 1970-01-01
    • 2013-05-18
    • 2015-01-21
    • 2015-06-20
    相关资源
    最近更新 更多