【问题标题】:How to get nanomsg to automatically reconnect reliably?如何让 nanomsg 可靠地自动重新连接?
【发布时间】:2014-11-19 06:01:17
【问题描述】:

当服务器短暂脱机或完全脱机然后重新启动时,我在处理重新连接时遇到问题。我无法让我的客户自动重新连接。此外,在任何地方都没有可以看到套接字状态的属性(套接字已断开连接?),以便我可以手动重新连接。我错过了什么?

According to the nanomsg documentation,有一个称为NN_RECONNECT_IVL 的重新连接间隔设置。我似乎无法让它工作。考虑以下几点:

我有一个可用的 nanomsg 服务器:

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

然后我附上它:

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

我明白了:

hello world
hello world
hello world

然后,我终止服务器并重新启动它,但 nanocat 不会自动重新连接。也许我缺少一个设置?

接下来,我使用 NNanomsg 在 C# 中构建了一个客户端:

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

我明白了:

hello world
hello world
hello world

然后,我终止服务器并重新启动它,我的 C# 客户端不会自动重新连接。也许我缺少一个设置?

接下来,我用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;
}

我明白了:

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

(垃圾,因为我猜 nanomsg 没有初始化缓冲区,我懒惰地使用 printf)

然后,我终止服务器并重新启动它,我的 C 客户端不会自动重新连接。

我错过了什么?

注意: 我尝试在nn_connect() 和s.Connect 之前和之后设置套接字选项。没有。

【问题讨论】:

    标签: c# sockets nanomsg


    【解决方案1】:

    我在没有 nanocat 的情况下进行了测试。作为基础,我以 this tutorial 中的 BUS 为例

    这是节点的 C++ 代码:

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

    我为测试修改了运行脚本:

    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 "-"
    

    在这里,我将 node0 作为没有传出连接的服务器点。其他节点只有一个到一个服务器节点的传出连接。 2秒后我杀死了node0。看看我得到的日志:

    如您所见,重启 node0 后有通信。即使没有设置重新连接间隔。我希望这个例子会有所帮助。

    【讨论】:

    • 这很有趣。 nanocat坏了吗?
    • @010110110101 如果你能成功地在你身边复制我的结果,这将是最有可能的。
    • 可能与一个现已修复的错误 github.com/nanomsg/nanomsg/issues/182 有关
    猜你喜欢
    • 2017-02-08
    • 2021-05-24
    • 2021-10-16
    • 2011-12-03
    • 2017-01-26
    • 1970-01-01
    • 2018-10-07
    • 1970-01-01
    • 2017-09-18
    相关资源
    最近更新 更多