如何在 nanomsg 中为 "multicast" tcp 指定 tcp 协议

how to specify tcp protocol for "multicast" tcp in nanomsg

我已阅读:

但我不需要真正的多播 IP(例如 239.0.0.0:3000)我的负载也很轻。所以我不太关心背压。

是的,我可以使用总线范例。但是说我想先用 pubsub 测试。

发件人使用什么作为发送到 url 的 tcp 发送到多个客户端?

(我实际上使用的是下一代 nanomsg):

https://nanomsg.github.io/nng/man/v1.0.0/nng_tcp.7.html

我可以发送到 TCP://*:3000

我可以将订阅者绑定到该地址吗?

Can I send to tcp://*:3000 ?

是的。

Can I bind the subscribers to that address ?

是的。当然,一个人必须拥有自己的一套(显然不能 "share" 任何独占资源)
然而,
PUB 必须 "knit-the-net" 正确配置 .connect()-s ( nng_dial()-s ),以便达到所有这些远程 AccessPoint-s,它自己不需要知道。

使用反向 .bind()/.connect() 的自由是 ZeroMQ 和 nanomsg 的常见做法,但请检查 是否保留了这种选择的自由。

...want to test first with the pubsub. What would be the sender use as the send to url for tcp to send to multiple clients ?

好吧,如果刚开始使用 ZeroMQ / nanomsg / nng,事情似乎有点混乱。

第一个:
初始的 API v2.x 和 都将 not 仅发送给多个客户端,但 将始终发送给套接字原型引擎可见的所有客户端 (可能的配置调整细节超出了本 post 的范围).

换句话说,PUB端的应用程序代码根本不决定谁会收到消息。所有曾经看到的客户端都在 "delivery-list" 上,并且网络必须将所有副本传送到所有能够临时连接的客户端(有些早一些,有些晚一些,其余的再也看不到了)是一场单​​独的音乐会 - 也不是你的问题,如 posted 在你之前的问题中)。

PUB/SUB 订阅机制是这里的一个重要问题。 和早期的 v2.x,执行订阅主题过滤延迟,它实际上发生在每条消息被传递到远程客户端时 -一方,以远程{PASS|FAIL}-rejection为代价,基于该远程客户端订阅的TOPIC。因此,所有消息都按设计流向所有客户端。

这意味着,您的网络级通信多播实际上对这种类型的本地(仅)网络没有任何好处(正如您在上一个问题中 posted ) PUB/SUB 可扩展的正式沟通模式原型。另外 到目前为止还没有发布支持这种传输的实现-class(而 有)。

下一个:
看来,简短阅读 [ 部分中的主要概念差异可能有助于消除乐高式基础设施设置的术语和概念的歧义:

代码显然是示意性的、不完整的,但是阅读和理解的典范:

// PUB_sender( "<tcp4>://<A.B.C.D>:<PORT>" ); // will launch it
//              <tcp6>://[::1]:<PORT>
//          <tls+tcp4>://<___aTransportClass_specific_AccessPoint_ADDRESS_>:<_aTransportClass_spcific_AccessPoint_SPECIFIER>
//
// -------------------------------------------------------------------
// SUB_client( "..." ); // anyone ( all ) who will "dial-in" will receive messages

#define PUT64( ptr, u )                              \
    do {                                             \
        (ptr)[0] = (uint8_t)(((uint64_t)(u)) >> 56); \
        (ptr)[1] = (uint8_t)(((uint64_t)(u)) >> 48); \
        (ptr)[2] = (uint8_t)(((uint64_t)(u)) >> 40); \
        (ptr)[3] = (uint8_t)(((uint64_t)(u)) >> 32); \
        (ptr)[4] = (uint8_t)(((uint64_t)(u)) >> 24); \
        (ptr)[5] = (uint8_t)(((uint64_t)(u)) >> 16); \
        (ptr)[6] = (uint8_t)(((uint64_t)(u)) >> 8);  \
        (ptr)[7] = (uint8_t)((uint64_t)(u));         \
    } while (0)
int
PUB_sender( const char *aTransportClassAccessPointURL )
{
   int        aRetVAL = -1;
   nng_socket aSOCKET = NNG_SOCKET_INITIALIZER;
// ---------------------------------aSOCKET = Context().socket( PUB );
   if ( ( aRetVAL = nng_pub0_open( &aSOCKET )
          ) != 0 )                  fatal( "nng_pub0_open",
                                            aRetVAL 
                                            );

// ---------------------------------aSOCKET.bind( aTransportClassAccessPointURL );
   if ( ( aRetVAL = nng_listen(     aSOCKET,
                                    aTransportClassAccessPointURL,
                                    NULL,
                                    NNG_FLAG_NONBLOCK
                                    )
          ) != 0 )                  fatal( "nng_listen",
                                            aRetVAL
                                            );

// ---------------------------------aSOCKET.setsockopt( LINGER, 0 );
   if ( ( aRetVAL = nng_setopt_int( aSOCKET,
                                    NNG_OPT_LINGER,
                                    0
                                    )
          ) != 0 )                  fatal( "nng_setopt_int",
                                            aRetVAL
                                            );
   for (;;)
   {
       char *   aBUF = "12345678";
       uint64_t aVAL;
       time_t   aNOW;

       aNOW = time( &aNOW ); printf( "PUB.send()-s: "); showdate( aNOW );

       PUT64( aBUF, (uint64_t) aNOW );

   // ----------------------------aSOCKET.send( aBUF, ... );
      if ( ( aRetVAL = nng_send(  aSOCKET,
                                  aBUF,
                                  sizeof( aBUF ),
                                  NNG_FLAG_ALLOC
                                  )
             ) != 0 )             fatal( "nng_send",
                                          aRetVAL
                                          );
   }
   nng_free(  aBUF, 8 );
   nng_close( aSOCKET );
}

我从 gdamore 获得的信息似乎表明不能使用 tcp://*:3000,因为您需要将 producer/publisher 绑定到某个接口。但是,固定端点我现在有 1-1 发布者到订阅者通过 tcp 工作。

(讨论于:https://www.freelists.org/post/nanomsg/does-nanomsg-support-multi-producer-in-pubsub-mode,10

现在我发现多播实际上是不可能的(直到允许 UDP 传输)我修改了我的问题并将其放在我最终解决方案的上下文中。参见: