2015-10-12 1 views
1

Я использую библиотеку pyzmq, чтобы установить связь между двумя процессами python на одной машине. Рассматривая доступные шаблоны обмена сообщениями, предлагаемые ZMQ, неясно, какой из них подходит.
В моем случае оба процесса должны посылать независимо сообщения друг другу в некоторые случайные моменты времени. В основном в разные моменты каждый процесс является одновременно клиентом и сервером. Некоторое визуальное описание ниже. enter image description hereПодходящий шаблон messmage Zmq для коммуникационных процессов

Для достижения этой модели, я использую два ZMQ.PAIR сокетов. Каждый процесс .bind() -s гнездо для приема на нем и .connect() -s к другому - .send() всякий раз, когда это необходимо.
Аналогичным образом каждый имеет выделенный поток для обработки принимающего, который блокирует.

Однако этот дизайн мне кажется немного растянутым, и мне интересно, есть ли установка, более естественная и подходящая для этого сценария? Я также представляю, что это должно быть довольно распространенным явлением. В текущем проекте мне также не нравится тот факт, что мне нужно вручную позаботиться о чистке двух сокетов при завершении процессов.

ответ

1

Если узлы буквально идентичны (по крайней мере, с точки зрения того, как они смотрят друг на друга в целях коммуникации, то есть никакой реальной «надежный» сервер для других «переходных» клиент), то у вас есть два варианта:

(A) Разверните две пары сокетов, одну пару, которая обрабатывает один узел как сервер, а другой - клиент, а другой - отменяет эти отношения.

Это может быть целесообразно, если сообщение соответствует строгой схеме между узлами, например. один узел инициирует связь, и существует конкретная функция назад и вперед, которая происходит до конца этого конкретного разговора. Это позволяет каждому узлу самостоятельно инициировать связь и поддерживать свою собственную каденцию связи, не путая ее с «перекрестными помехами», инициированными другим узлом.

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

(B) Просто выберите один узел, чтобы быть «сервером», а другой узел, чтобы быть «клиент», bind() и connect() соответственно, и после этого момента просто относиться к ним как к равным

Это звучит больше всего нравится то, что вы ищете. Вы не необходимо, чтобы быть чрезмерно обеспокоен, с какой стороны bind() s и с какой стороны connect() s. На данный момент это звучит так, как будто вы открываете и закрываете соединение каждый раз, когда вам нужно общаться. Вы должны просто оставить сообщение открытым для жизни вашего процесса. Сокеты PAIR, которые вы используете, поддерживают полностью неструктурированную связь, поэтому вы можете свободно отправлять и получать с любого направления, независимо от того, какую сторону вы обозначаете как «сервер» и какую сторону вы обозначаете как «клиент».

+0

В случае A) ясно, что для каждого процесса задействованы 2 сокета. Для случая B) мне не ясно, имеете ли вы один или два сокета в процессе.Один сокет будет означать, что пока поток ожидает приема в сокете, другой поток попытается написать. Если возможно, я бы предпочел этот вариант, так как его проще управлять, но безопасно ли использовать zmq-сокет таким образом? – steve

+0

Сокеты ZMQ не являются потокобезопасными, поэтому вы не должны делиться одним сокетом между несколькими потоками (за исключением некоторых ограниченных условий, если вы знаете, что вы делаете, см. [Второй вопрос здесь] (http: // zeromq.org/area:faq#toc6)). Итак, нет, это небезопасно. Вам нужно * использовать блокирующий прием? Есть варианты не блокировать. Если вы блокируете свой приемный сокет, то этот сокет просто должен быть выделен для приема, и вам понадобится другой сокет для отправки, если только я не ошибочно не понимаю вашу архитектуру. – Jason

+0

Думаю, мне нужно будет заблокировать. Я не могу предвидеть, когда другой процесс что-то пошлет. Если я не могу зарегистрировать обратный вызов для приема/обработки файлов. – steve