Двунаправленная связь с 1 разъемом - как бороться с коллизиями? - PullRequest
2 голосов
/ 22 апреля 2010

У меня есть одно приложение. который состоит из «Менеджер» и «Рабочий». В настоящее время работник всегда инициирует соединение, что-то говорит менеджеру, и менеджер отправляет ответ.

Поскольку между менеджером и рабочим существует МНОЖЕСТВО, я подумываю о том, чтобы между ними было открыто гнездо и осуществлял связь. Я также надеюсь начать взаимодействие с обеих сторон - дать возможность менеджеру сказать что-то работнику, когда захочет.

Однако меня немного смущает вопрос о том, как бороться с "столкновениями". Скажем, менеджер решает что-то сказать работнику, и в то же время работник решает что-то сказать менеджеру. Что случится? Как справиться с такой ситуацией?

P.S. Я планирую использовать Netty для фактической реализации.

Ответы [ 5 ]

3 голосов
/ 22 апреля 2010

«Я также надеюсь начать взаимодействие с обеих сторон - дать возможность менеджеру сказать что-то работнику, когда захочет».

Простой ответ. Не.

Извлеките уроки из существующих протоколов: есть клиент и сервер. Все будет хорошо. Работник может быть сервером, а менеджер - клиентом. Менеджер может сделать множество запросов. Работник отвечает на запросы по мере их поступления.

Одноранговый может быть сложным без реальной ценности для сложности.

2 голосов
/ 19 июля 2010

Я бы пошел на постоянный двунаправленный канал между сервером и клиентом.

Если все, что у вас будет, это один сервер и один клиент, тогда проблем с коллизиями нет ... Если сервер принимает соединение, он знает, что это клиент и вице наоборот. Оба могут читать и писать в одном сокете.

Теперь, если у вас есть несколько клиентов, и ваш сервер должен отправить запрос конкретно клиенту X, тогда вам нужно рукопожатие !

Когда клиент загружается, он подключается к серверу. Как только это соединение установлено, клиент идентифицирует себя как клиент X (сообщение квитирования). Теперь сервер знает, что у него есть сокет, открытый для клиента X, и каждый раз, когда ему нужно отправить сообщение клиенту X, он снова использует этот сокет.

К счастью, я только что написал учебник (включая пример проекта) по этой конкретной проблеме. Используя Netty! :)

Вот ссылка: http://bruno.linker45.eu/2010/07/15/handshaking-tutorial-with-netty/

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

1 голос
/ 04 августа 2010

Правильная ссылка на учебник Рукопожатие / Нетти, упомянутая в ответе brunodecarvalho: http://bruno.factor45.org/blag/2010/07/15/handshaking-tutorial-with-netty/
Я бы добавил это в качестве комментария к его вопросу, но у меня нет минимально необходимой репутации для этого.

1 голос
/ 22 апреля 2010

Я думаю, вам нужно читать по сокетам ....

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

0 голосов
/ 05 августа 2010

Если вы хотите заново изобрести колесо и не хотите использовать промежуточное ПО ...

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

...