Я не думаю, что есть какой-либо способ избежать тайм-аутов и повторных попыток при сопоставлении узлов, учитывая, что 1) существует неизвестная и переменная задержка в сети, и 2) соединения могут присоединяться и выходить в неизвестные моменты времени.
Таким образом, любой узел, пытающийся подключиться к другому узлу, должен сохранять следующие параметры с состоянием:
- Я сопоставлен с другим узлом
- У меня есть запрос на совпадение
- Мой невыполненный запрос на совпадение с узлом X
Он должен отклонять входящие запросы на совпадение, если один из первых двух является истинным (если только входящий запрос не поступил от узла X, и у меня нет ожидающего запроса к тому же узлу). Он может запросить совпадение, только если оба являются ложными.
Кроме того, после сопоставления им может потребоваться опросить своего партнера или наблюдать за сообщениями о разъединении и ответить соответствующим образом (вернитесь в фазу сопоставления или завершите работу, в зависимости от того, что требуется приложению).
В этом случае вы можете, по крайней мере, уменьшить объем сетевого трафика, необходимый для синхронизации узлов, создав алгоритм сортировки, чтобы все узлы заранее знали, кто их лучшие соответствия, и пытались подключиться напрямую к их лучшим соответствует минимальному сетевому трафику (нет сообщений широковещательной рассылки, нет случайных попыток).
Ключом к этому будет peerID, который автоматически получает каждый узел в NetGroup. Когда узел получает сообщение NeighborConnect, он также содержит уникальный peerID соседнего узла. Другими словами, каждый узел имеет уникальное имя (которое в основном является большим случайным числом) и знает уникальные имена всех других узлов.
Этот peerID длинный, что-то вроде 256 бит. С его помощью вы можете создать порядок сортировки - возможно, что-то вроде: рассматривая первые 32-битные как целые числа, XOR для peerID удаленного узла с вашим собственным peerID и сортируйте удаленные узлы от самого низкого до самого высокого.
Так что теперь у каждого узла примерно одинаковое представление о том, к кому они собираются подключаться (даже если будут различия, например, в зависимости от сообщений отключения / подключения, распространяющихся через группу). Узлы будут проходить через отсортированный список, пытаясь соединиться с лучшими совпадениями, вероятно, с некоторым случайным таймаутом между неудачными попытками соединения.
Возможно, это не идеальное решение - возможно, существует лучшее, но я думаю, что это лучше, чем произвольно использовать узлы или использовать широковещательные сообщения.