PyZMQ (ZeroMQ) - Как получить ключ подписки из SUB-сокета? - PullRequest
0 голосов
/ 28 июня 2018

Я хотел бы получить ключ подписки сокета абонента (SUB) после его установки.

Скажем, у меня есть следующее гнездо:

import zmq
ctx = zmq.Context.instance()
sub_sock = ctx.socket(zmq.SUB)
sub_sock.bind("tcp://127.0.0.1:6667")
sub_sock.setsockopt(zmq.SUBSCRIBE, "foo1".encode('ascii'))

Я хочу сделать что-то вроде этого (псевдокод):

sub_key = sub_sock.get_sub_key().decode("ascii")
sub_key = subkey[:-1] + "2"  # "foo2"

# unsubscribe all keys
sub_sock.setsockopt(zmq.UNSUBSCRIBE, '')

# subscribe to new key
sub_sock.setsockopt(zmq.SUBSCRIBE, sub_key.encode('ascii'))

Вопрос:

Однако я не могу обнаружить функцию, которая может получить ключ от сокета абонента. Как я могу получить ключ подписки сокета?

Система:

  • Python 3,6
  • libzmq версия: 4.2.5
  • pyzmq версия: 17.0.0

Ответы [ 2 ]

0 голосов
/ 28 июня 2018

Как я могу получить ключ подписки сокета (... после его установки) ?

Да, можно , но только на стороне PUB (ну, на самом деле это клон XPUB поведения PUB) архетип), если он был тщательно настроен с помощью метода .setsockopt( { XPUB_VERBOSE | XPUB_VERBOSER }, 1 ), чтобы начать обслуживание связанных с каналом (X)SUB -s в этом конкретном режиме.

Таким образом, в случае крайней необходимости (в случае полной потери контекста на стороне SUB или из-за амнезии его собственной системы управления подписками) можно настроить XSUB также на создание экземпляра утилитарного XPUB с эта дополнительная конфигурация .setsockopt( { XPUB_VERBOSE | XPUB_VERBOSER }, 1 ), { .bind() | .connect() } ссылка от-Home-Base на-Home-Base и обработка всех поступивших (X)SUB -подписок на лету.

В документации по нативному API публикуются все подробности, позволяющие сделать это правильно.

Уникальный подход к изучению собственной подписки с помощью прослушивания, но выполнимый.


Заключительные замечания:

Тематический фильтр ZeroMQ разработан более сложным способом и оптимизирован для скорости (высокая пропускная способность, низкая задержка) . Он может обрабатывать единицы, сотни, тысячи, десятки тысяч подписок для каждого из { .bind() | .connected() } пиров.

Причиной этого стремления к дизайну и ориентации на производительность было отсутствие такой функции, когда экс-пост просил «библиотекаря» найти все « мои собственные » ключи подписки. (независимо от того, забыт ли он или просто забыт).

Можно также понять, что начиная с API v4.x, нативная обработка ZeroMQ начала управлять фильтрацией тем на стороне (X)PUB, в то время как в более старых версиях API эта критическая для производительности операция откладывалась на каждом из Со стороны (X)SUB, за счет увеличения совокупных объемов сетевого трафика, поскольку все сообщения (да, действительно, ВСЕ СООБЩЕНИЯ) перешли с (X)PUB на все (X)SUB -ы. Здесь кто-нибудь упоминал о проблемах безопасности?

# unsubscribe all keys                        // THIS WILL NOT FLY THAT WAY

Те же рассуждения стоят за «пропущенным» вызовом API с просьбой « забыть все мои собственные подписки », но нужно явно отписаться, по одному или правильно .close() экземпляр сокета (X)SUB и, скорее, создать экземпляр другого экземпляра на основе «зеленого поля» и повторно { .bind() | .connect() } вернуть его обратно в инфраструктуру для достижения поставленной цели в блоке.

0 голосов
/ 28 июня 2018

Нет поддержки для получения подписок из сокета SUB. Вам нужно будет хранить их в вашей собственной структуре данных (список, карта и т. Д.)

Другая информация:

Гнездо SUB поддерживает несколько одновременных подписок.

Строка ниже не отменяет подписку всех ключей, фактически отменяет подписку на ключ "", который является действительной подпиской.

# unsubscribe all keys
sub_sock.setsockopt(zmq.UNSUBSCRIBE, '')

Вы должны быть явными:

sub_sock.setsockopt(zmq.UNSUBSCRIBE, "foo1".encode('ascii'))
...