Двунаправленная связь с 1 разъемом-как бороться с коллизиями?
У меня есть одно приложение. она состоит из" менеджера "и"работника". В настоящее время работник всегда инициирует соединение, говорит что-то менеджеру, и менеджер отправляет ответ.
Поскольку между менеджером и работником существует много коммуникаций, я рассматриваю возможность открытия сокета между ними и осуществления связи. Я также надеюсь начать взаимодействие с обеих сторон, что позволит менеджеру сказать что-то работнику, когда он захочет.
Однако я немного запутался в том, как справляться с "столкновениями". Скажем, менеджер решает сказать что-то рабочему, и в то же время рабочий решает сказать что-то менеджеру. Что же будет дальше? Как следует поступать в такой ситуации?
P. S. Я планирую использовать Нетти для фактической реализации.
5 ответов:
" я также надеюсь инициировать взаимодействие с обеих сторон-позволяя менеджеру сказать что-то работнику, когда он захочет."
Простой ответ. Не надо.
Учитесь на существующих протоколах: есть клиент и сервер. Все будет хорошо складываться. Работник может быть сервером, а менеджер-клиентом. Менеджер может сделать множество запросов. Работник отвечает на запросы по мере их поступления.
Peer-to-peer может быть сложным без реального значения для сложность.
Я бы выбрал постоянный двунаправленный канал между сервером и клиентом.
Если все, что у вас будет, - это один сервер и один клиент, то проблемы коллизии нет... Если сервер принимает соединение, он знает, что это клиент, и наоборот. Оба могут читать и писать на одном и том же сокете.
Теперь, если у вас есть несколько клиентов и ваш сервер должен отправить запрос конкретно клиенту X, то вам нужно рукопожатие !
Когда клиент загружается, он подключается к серверу. Как только это соединение установлено, клиент идентифицирует себя как клиент X (сообщение рукопожатия). Теперь сервер знает, что у него есть сокет, открытый для клиента X, и каждый раз, когда ему нужно отправить сообщение клиенту X, он повторно использует этот сокет.
Вам повезло, я только что написал учебник (включая пример проекта) по этой конкретной проблеме. Используя Нетти! :)
Вот ссылка: http://bruno.linker45.eu/2010/07/15/handshaking-tutorial-with-netty/
Обратите внимание, что в этом решении сервер не пытается подключиться к клиенту. Это всегда клиент, который подключается к серверу. Если вы думаете об открытии сокета каждый раз, когда вы хотите отправить сообщение, вы должны пересмотреть постоянные соединения, поскольку они избегают накладных расходов на установление соединения, следовательно, ускоряя скорость передачи данных в N раз.
Я думаю, вам нужно прочитать о сокетах....
На самом деле у вас нет таких проблем....Помимо того, как реагировать на прием и отправку, как правило, это делается через поток ваших сообщений... в зависимости от приложения вы можете использовать несколько подходов к этому.
Правильная ссылка на учебник рукопожатия / Нетти, упомянутый в ответе брунодекарвальо, - это http://bruno.factor45.org/blag/2010/07/15/handshaking-tutorial-with-netty/
Я бы добавил Это в качестве комментария к его вопросу, но у меня нет минимально необходимой репутации, чтобы сделать это.
Если вы хотите заново изобрести колесо и не хотите использовать промежуточное ПО...
Разработайте свой протокол таким образом, чтобы ответы другого однорангового узла на ваши запросы всегда были легко отличимы от запросов другого однорангового узла. Затем тщательно выберите стратегию сетевого ввода-вывода. Любой код, ответственный за чтение из сокета, должен сначала определить, являются ли входящие данные ответом на данные, которые были отправлены, или это новый запрос от узла (глядя на заголовок данных, и если вы недавно сделали запрос). Кроме того, необходимо поддерживать правильную очередь, чтобы при отправке ответов на запросы однорангового узла она была должным образом отделена от новых запросов, которые вы выдаете.