0

I learned how to use ZeroMQ on a localhost, but I failed to do it on a remote IP.

Q1: Do I need a broker?
If so,
Q2: which broker and how to do it.?


Update:

OK. I'm using the ZMQ Weather Update example but with a remote IP ( not the localhost ). Here is what I do using C# ZMQ bindings ( however, I'm OK to use any other language ):

ZMQ Server:

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

    publisher.Bind(address);

    publisher.Send("msg")
}

Proxy:

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);
}

Client:

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));
}

When I run this I get error in Server and error in proxy - server gets

Invalid end point

and proxy gets EINVAL(22):

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

user3666197
  • 1
  • 6
  • 50
  • 92
m.othman
  • 638
  • 7
  • 28
  • There shouldn't be any difference between remote and local. How did it fail? Error messages, MCVE etc? – David Jun 08 '16 at 22:45
  • StackOverflow encourages users to post **`MCVE`**-code **altogether with all outputs and error messages - as-is from console output**. Rather keep this convention as policy enforcers sometimes start corrective measures on posts, that do not meet this fair & common practice. – user3666197 Jun 09 '16 at 13:10

1 Answers1

1

A1: No, ZeroMQ is a Broker-less messaging framework.

A2: N/A


How to repair the code?

All the services need to obey respective transport-class addressing rules, for the TCP/IP case - both the .bind() / .connect() methods have to state both parts of the IP:PORT# specification ( with some aids from DNS-resolution for the IP-part, but the :PORT#-part is still mandatory )

( which the source-code does not meet in client, ref.:

 subscriber.Connect(connect_to);

whereas there ought be also a Proxy-side matching :PORT#, i.e.:8100, specified, for a correct .connect() ).

For the clarity and for avoiding a port#-collision, remove the epgm transport class from the code.

user3666197
  • 1
  • 6
  • 50
  • 92