How do I get nanomsg to automatically reconnect reliably?

I am having problems with re-creating where the server goes down for a short time or shuts down completely and then comes back. I cannot get my clients to automatically reconnect. Also, there is no property anywhere where I can see the state of the socket (is the socket disconnected?) So that I can manually reconnect. What am I missing?

According to nanomsg documentation , there is a reconnect interval called NN_RECONNECT_IVL

. I can't seem to get it to work. Consider the following:

I have a working nanomsg server:

nanocat --bind-local 1234 --bus --interval 1 --ascii --data "hello world"

      

Then I attach to it:

nanocat --connect-local 1234 -A --bus

      

and I see:

hello world
hello world
hello world

      

Then I remove the server and restart it, and the nanokat does not automatically connect automatically. Maybe where I am missing?

Then I built a client in C # using NNanomsg:

class Program
{
    static void Main(string[] args)
    {
        NNanomsg.NanomsgSocket s = new NNanomsg.NanomsgSocket(NNanomsg.Domain.SP, NNanomsg.Protocol.BUS);

        // doesn't seem to do anything
        s.Options.ReconnectInterval = new TimeSpan(0, 0, 5);

        var e = s.Connect("tcp://127.0.0.1:1234");

        while (true)
        {
            byte[] ddd;
            ddd = s.ReceiveImmediate();
            if (ddd != null)
            {
                string m = UTF8Encoding.UTF8.GetString(ddd);
                Console.WriteLine(m);
            }
            else
            {
                // don't peg the CPU
                Thread.Sleep(100);
            }
        }
    }
}

      

and I see:

hello world
hello world
hello world

      

Then I remove the server and restart it and my C # client doesn't connect automatically. Maybe where I am missing?

Then I built the client in c:

#include <nanomsg/nn.h>
#include <nanomsg/bus.h>

int _tmain(int argc, _TCHAR* argv[])
{
    int sock;
    int recv;
    int reconnect_interval;
    char *buf;

    buf = NULL;
    reconnect_interval = 5;

    sock = nn_socket (AF_SP, NN_BUS);

    nn_setsockopt(sock, NN_SOL_SOCKET , NN_RECONNECT_IVL, &reconnect_interval, sizeof(reconnect_interval));

    nn_connect(sock, "tcp://127.0.0.1:1234");

    while(1 == 1)
    {
        recv = nn_recv(sock, &buf, NN_MSG, 0);
        if(recv > 0)
        {
            printf("%s\r\n", buf);
            nn_freemsg (buf);
        }
    }

    return 0;
}

      

and I see:

hello world²²²²½½½½½½½½■ε■ε■
hello world²²²²½½½½½½½½■ε■ε■
hello world²²²²½½½½½½½½■ε■ε■

      

(Crash because I think nanomsg does not initialize the buffer and I am lazy using printf)

Then I remove the server and restart it and my C client doesn't connect automatically.

What am I missing?

Note: I've experimented with setting the socket option before as well as after nn_connect()

and s.Connect

. Not.

+3


source to share


1 answer


I did the test without a nanokata. I took the BUS example from this tutorial as a basis.

This is the C ++ code for the nodes:

#include <assert.h>
#include <libc.h>
#include <stdio.h>
#include "nanomsg-master/src/nn.h"
#include "nanomsg-master/src/bus.h"

int node (const int argc, const char **argv)
{
  int sock = nn_socket (AF_SP, NN_BUS);
  assert (sock >= 0);
  assert (nn_bind (sock, argv[2]) >= 0);
  sleep (1); // wait for connections
  if (argc >= 3)
    {
      int x=3;
      for(x; x<argc; x++)
        assert (nn_connect (sock, argv[x]) >= 0);
    }
  sleep (1); // wait for connections

  int to = 1000;
  assert (nn_setsockopt (sock, NN_SOL_SOCKET, NN_RCVTIMEO, &to, sizeof (to)) >= 0);
  // SEND
  int sz_n = strlen(argv[1]) + 1; // '\0' too
  printf ("%s: SENDING '%s' ONTO BUS\n", argv[1], argv[1]);
  int send = nn_send (sock, argv[1], sz_n, 0);
  assert (send == sz_n);
  while (1)
    {
      // RECV
      char *buf = NULL;
      int recv = nn_recv (sock, &buf, NN_MSG, 0);
      if (recv >= 0)
        {
          printf ("%s: RECEIVED '%s' FROM BUS\n", argv[1], buf);
          nn_freemsg (buf);
        }
    }
  return nn_shutdown (sock, 0);
}

int main (const int argc, const char **argv)
{
  if (argc >= 3) node (argc, argv);
  else
    {
      fprintf (stderr, "Usage: bus <NODE_NAME> <URL> <URL> ...\n");
      return 1;
    }
}

      

I changed the startup script for the test:



gcc testbus.c nanomsg-master/.libs/libnanomsg.a -o testbus
./testbus node0 tcp://127.0.0.1:1234 & node0=$!
./testbus node1 tcp://127.0.0.1:1235 tcp://127.0.0.1:1234 & node1=$!
./testbus node2 tcp://127.0.0.1:1236 tcp://127.0.0.1:1234 & node2=$!
./testbus node3 tcp://127.0.0.1:1237 tcp://127.0.0.1:1234 & node3=$!
sleep 2

ps -ax | grep testbus | grep -v grep
echo "-"

kill $node0
echo "After killing server"
ps -ax | grep testbus | grep -v grep
echo "-"

echo "Running new server..."
./testbus node0 tcp://127.0.0.1:1234 & node0=$!
sleep 5
ps -ax | grep testbus | grep -v grep
echo "-"


kill $node0 $node1 $node2 $node3
ps -ax | grep testbus | grep -v grep
echo "-"

      

Here I made node0 as a server point with no outgoing connections. Other nodes only have one outgoing connection to one server node. And after 2 seconds im killing node0. Take a look at the log I got as output:

script run results

As you can see, there is communication after restarting node0 as expected. Even without setting the reconnection time. Hope this example helps.

0


source







All Articles