zeromq / zyre

Zyre - an open-source framework for proximity-based peer-to-peer applications
Mozilla Public License 2.0
878 stars 174 forks source link

Discovery with VPN #739

Closed JonasMht closed 6 months ago

JonasMht commented 6 months ago

Hello, I would like to use Zyre to discover other peers on a VPN. The problem is that the VPN doesn't allow beaconing (broadcasting). Would it be possible to use gossip instead? If so how could I implement it? The problem is I didn't find any example fully implementing it.

Thanks in advance.

sphaero commented 6 months ago

Should be possible indeed. We definitely could use a good gossip example. This is what the docs say:

 <method name = "gossip bind">
        Set-up gossip discovery of other nodes. At least one node in the cluster
        must bind to a well-known gossip endpoint, so other nodes can connect to
        it. Note that gossip endpoints are completely distinct from Zyre node
        endpoints, and should not overlap (they can use the same transport).
        <argument name = "format" type = "format" />
    </method>

    <method name = "gossip connect">
        Set-up gossip discovery of other nodes. A node may connect to multiple
        other nodes, for redundancy paths. For details of the gossip network
        design, see the CZMQ zgossip class.
        <argument name = "format" type = "format" />
    </method>

So the idea is to have one node as a main one and others can connect to that one.

If you could try to make a minimal example like minimal.c in examples. I can help if you run into trouble.

Also look at the selftest code which uses gossip for discovery:

https://github.com/zeromq/zyre/blob/f2fd7252322b1b52be248b9ef96f8981de3b86ff/src/zyre.c#L782

https://github.com/zeromq/zyre/blob/f2fd7252322b1b52be248b9ef96f8981de3b86ff/src/zyre.c#L801

JonasMht commented 6 months ago

Thank you for your help! I have been able to make the gossip discovery work with a VPN.

Here's a minimal example that works for me.

#include "zyre.h"

#define ROOM "GROUP"

// Minimalistic example of using zyre API with gossip discovery:
//  start two clients, each will SHOUT 10 messages
//
// gcc `pkg-config --libs --cflags libzyre` minimal.c -o minimal
//
// Or if you've build zyre from source:
//
// gcc -lzyre -lczmq -lzmq minimal.c -o minimal 
//
// ./minimal node1
// ./minimal node2

int
main (int argc, char *argv [])
{
    if (argc < 2) {
        puts ("syntax: ./minimal myname");
        exit (0);
    }
    const char *name = argv[1];
    zyre_t *node = zyre_new(name);
    assert(node);

    if (strcmp(name, "node1") == 0)
    {
        // becomes the known node
        zyre_gossip_bind(node, "tcp://known_ip:known_port");
    }
    else
    {
        // connects to the known node
        zyre_gossip_connect(node, "tcp://known_ip:known_port");
    }

    zyre_start(node);
    zyre_join(node, ROOM);

    size_t count = 0;
    while (!zsys_interrupted && count < 10)
    {
        zyre_shouts(node, ROOM, "Hello from %s", name);
        zclock_sleep(250);
        zmsg_t *msg = zyre_recv(node);
        zmsg_print(msg);
        zmsg_destroy(&msg);

        count++;
    }

    zyre_stop(node);
    zyre_destroy(&node);
}