Как указать протокол TCP для "многоадресной" TCP в Nanomsg
Я прочитал: проблема пропускной способности многоадресной рассылки Nanomsg
Но мне не нужен настоящий IP-адрес многоадресной передачи (например, 239.0.0.0:3000). У меня также очень небольшая нагрузка. Так что меня не беспокоит обратное давление.
Да, я мог бы использовать автобусную парадигму. Но, скажем, я хочу сначала проверить с pubsub.
Что будет использовать отправитель в качестве URL для отправки по TCP для отправки нескольким клиентам?
(Я на самом деле использую Nanomg следующего поколения):
https://nanomsg.github.io/nng/man/v1.0.0/nng_tcp.7.html
Могу ли я отправить на tcp://*:3000
Могу ли я привязать подписчиков к этому адресу?
2 ответа
Информация, которую я получил от gdamore, похоже, указывает на то, что нельзя использовать tcp://*:3000, так как вам нужно привязать производителя / издателя к какому-либо интерфейсу. Однако с фиксированной конечной точкой у меня теперь есть 1-1 издателя на подписчика, работающего через tcp.
(это обсуждалось в: https://www.freelists.org/post/nanomsg/does-nanomsg-support-multi-producer-in-pubsub-mode,10)
Теперь, когда я вижу, что многоадресная рассылка на самом деле невозможна (пока не разрешен транспорт UDP), я пересмотрел свой вопрос и поместил его в контекст моего окончательного решения. Увидеть:
Могу ли я отправить
tcp://*:3000
?
Да.
Могу ли я привязать подписчиков к этому адресу?
Да. Конечно, каждый должен иметь свой собственный набор (очевидно, не может "делиться" каким-либо эксклюзивным ресурсом)
Еще,PUB
придется "вязать в сети" с правильно настроенным.connect()
-с (nng_dial()
-s), чтобы охватить все те удаленные AccessPoint-ы, о которых он не должен знать самостоятельно.
Свобода использования реверса.bind()/.connect()
была обычной практикой для ZeroMQ и nanomsg, но все же проверьте, сохраняет ли nng эту свободу выбора.
... хочу сначала проверить с pubsub.Что будет использовать отправитель в качестве URL для отправки по TCPдля отправки нескольким клиентам?
Что ж, все кажется немного запутанным, если просто начать с ZeroMQ / nanomsg / nng.
Первый:
оба исходных API zeromq v2.x и nng не будут отправлять только нескольким клиентам, новсегда будут отправлять всем клиентам, когда-либо видимым движку Socket-archetype (возможные подробности настройки конфигурации выходят за рамки этого поста).
Другими словами,PUB
код приложения не определяет, кто получит сообщение или нет. Все когда-то увиденные клиенты будут в "списке доставки", и сети придется переносить все реплики ко всем таким клиентам, которые смогли подключиться ad-hoc (некоторые раньше, некоторые позже, остальные, которые никогда не были видны назад Это отдельный концерт, который также не является вашей проблемой, как указано в вашем предыдущем вопросе).
PUB/SUB
Механика подписки является важным вопросом здесь. И nng, и ранний zeromq v2.x выполняют отложенную фильтрацию TOPIC, и это происходит, когда каждое сообщение доставляется на удаленную клиентскую сторону, за счет удаленного отклонения {PASS|FAIL}, основанный на ТЕМАТИКЕ (ах) этого удаленного клиента. Таким образом, все сообщения направляются всем клиентам по замыслу.
Это означает, что ваша многоадресная рассылка на уровне сети практически бесполезна для этого типа локальной( только) сети(как было опубликовано в вашем предыдущем вопросе)PUB/SUB
Масштабируемый Формальный Шаблон Коммуникации Архетип. Кроме того, nng пока не опубликовал поддержку реализации такого транспортного класса (тогда как zeromq имеет).
Следующий:
кажется, что краткое прочтение основных концептуальных различий в [ иерархии ZeroMQ менее чем за пять секунд ] может помочь устранить неоднозначность как терминологии, так и концепции настройки инфраструктуры в стиле LEGO:
Код, очевидно, схематичный, неполный, но примерный для чтения и понимания:
// 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 );
}