Согласование общего «сетевого канала» в одноранговой системе - PullRequest
2 голосов
/ 04 ноября 2008

Существует ли общий или установленный алгоритм для одноранговых узлов в сети для выбора уникального "сетевого канала" (или любой другой формы полусекретного идентификатора)?

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

Все объекты создаются примерно в одно и то же время и имеют доступ к (общему) системному времени.

Подходы, о которых я думал:

  1. Время создания экземпляра. Канал выводится (по md5) из времени Unix. Проблема в части " примерно в то же время". Они могут быть созданы прямо на пороге новой секунды.

  2. Случайное ожидание. Заставьте объекты ждать случайное количество и объявить (случайно сгенерированный) номер канала, выбранный первым, чтобы проснуться. Проблема в том, что система имеет малую временную гранулярность, и более чем один объект может проснуться до обработки объявления.

  3. Объедините 1 и 2. Объявите метку времени с высоким разрешением после ожидания случайной суммы и извлеките канал из самой низкой объявленной метки времени.

Это должно быть что-то умнее людей, чем я думал. Есть ли лучший способ сделать это?

Ответы [ 2 ]

1 голос
/ 23 марта 2009

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

Первый метод

Вы можете использовать менее точный таймер, чем каждую секунду, например, что-то вроде этого:

integer time = llGetUnixTime();
integer channel = time - (time % 1000);

Вероятно, все объекты, которые были перезагружены почти в одно и то же время, имеют один и тот же канал в соответствии с приведенным выше кодом, хотя вы, вероятно, захотите убедиться, что время% 1000 не близко к 0 или 1000, и, возможно, использовать время% 10000 в этот случай.

Второй метод

Кроме этого, вы можете создать своего рода протокол обнаружения. Например:

  1. недавно перезаписанный объект здоровается с жестко-закодированным каналом управления
  2. главный сервер для каждой сети в области отвечает номером канала своей сети
  3. объект выбирает сеть, к которой он хочет присоединиться
  4. если никто не отвечает, объект становится сервером для собственной сети, увеличивая канал управления на некоторое число (например, +1)
  5. если объект все равно хочет создать свою собственную сеть, он увеличивает наивысший используемый канал на +1 и создает собственный канал / сеть

Комбинация

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

0 голосов
/ 23 июня 2009

Ваши объекты перезагружаются другим объектом? Если это так, то простое решение - указать номер канала в целочисленном параметре llRezObject. Затем перезаданные (дочерние) объекты могут просто использовать параметр из своих событий on_rez в качестве канала.

Например, родительский элемент rezzer будет делать что-то вроде этого:

integer networkchannel = 3495293;
llRezObject("myobject", rezpos, rezvel, rezrot, networkchannel);

и перезаписанные дочерние объекты будут делать что-то вроде этого:

on_rez(integer networkchannel)
{
    llListen(networkchannel, "", NULL_KEY, "");
}
...