ECS 1 905 Опубликовано: 27 марта, 2021 Проблема: мы с друзьями живём в различных измерениях или на огромном расстоянии друг от друга, из-за чего беспроводные модемы использовать невозможно. При этом нам нужна система, позволяющая отправлять приватные сообщения конкретному человеку, зная адрес получателя. Очевидным решением будет использование связанных плат, но что если нужно работать более чем с 1 получателем? Связанные платы, увы, лимитированы. Что если мы играем с GalactiCraft, имеем базу на Земле, и кровь из носу хочется контролировать добычу камня на Луне, реакторы на Марсе и ферму урана на Венере с одного компьютера? Решение: объединить множество связанных плат в кластер! Принцип работы системы проще пареной репы: каждый новый клиент, подключаемый к сети, должен предоставить 1 из 2 скрафченных связанных плат. Первую мы вставляем в кластер, а вторую - в компьютер клиента. Чтобы отослать сообщение другому клиенту кластера, нужно знать имя канала его связанной платы. Далее - дело техники: если сервер получает сообщение от связанной платы, то осуществляется поиск платы-получателя в нём же. Если плата-получатель не найдена, то сообщение перенаправляется через широковещательный пакет проводного модема всем серверам кластера, чтобы те в свою очередь попытались найти получателя. Если получатель найден - ему отсылается имя канала отправителя и само сообщение. Теперь подумаем, как лучше объединить связанные платы. Каждая плата может быть вставлена только в Tier 3 слот компьютера или сервера. Оптимальным решением для экономии пространства будет использование серверных стоек, т.к. каждый Tier 3 сервер имеет целых 2 Tier 3 слота. Поэтому каждый сервер сможет обслуживать максимум 2 клиента сети. В итоге схема расположения стоек и конфигурация серверов должна быть примерно такой: Процессор не важен, память не важна, и требования если не нулевые, то минимальные. Разумеется, каждый сервер будет работать на микропрограмме EEPROM, ибо крафтить для этого жёсткие диски было бы нецелесообразно. Берем код и прошиваем столько EEPPROM'ов, сколько требуется: https://gist.github.com/IgorTimofeev/15b75915caa93a344c2be25dac308138 После включения сервер будет доступен для взаимодействия. Как же отправить сообщение получателю? Используем функцию tunnel.send(), и первым аргументом указываем имя канала получателя. Его можно получить через tunnel.getChannel(): local tunnel = require("component").tunnel local receiver = "867a85de-ae4c-4359-b06f-0d30c5dad6f1" tunnel.send(receiver, "Привет") Это всё замечательно - но где же практический пример? Давайте запустим чат! Да простят меня боги, старые и новые, но я буду использовать MineOS, т.к. общаться через GUI мне банально удобнее. Во всех компьютерах сети создаем новое приложение, открываем файл Main.lua для редактирования: Берём исходник чата: https://gist.github.com/IgorTimofeev/724992e8641245a51cef57ac883f541f Вставляем его содержимое вместо имеющегося в Main.lua и запускаем приложение. Для отсылки сообщения необходимо ввести канал связанной платы получателя, а также отправляемый текст. Вот пример интеллектуальной беседы двух величайших умов современности: Кроме того, каждый сервер кластера поддерживает протокол для обновления прошивки по сети, а также удаленного отключения и запуска всех серверов. Для этого вам потребуется отдельный компьютер, находящийся в локальной сети с кластером. Для удобства я также накатал мини-приложение: https://gist.github.com/IgorTimofeev/0fe93bd4549aa32161b9dbbba59425e8 Подытоживая, хотелось бы отметить, что этот софт находится в разделе "программы новичков", он не преследует никаких глобальных целей и не реализует "киллер-фич", ориентируясь больше на прикладное использование. Разумеется, серверную часть можно улучшить по своему вкусу, добавив поддержку широковещательных пакетов, PING-систему и системные события по типу дисконнекта/доступности серверов, а для клинетского чата можно реализовать систему контактов и отсылку медиа-файлов. Было бы время и желание... Однако в своё время даже такой функционал неплохо сохранил нам нервы во время войн с серверной цензурой, а также экономил время, которое потребовалось для длительных полётов на разбросанные по уголкам вселенной базы. Надеюсь, для кого-нибудь эта схема будет так же полезна, как и для нас c: 7 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 155 Опубликовано: 27 марта, 2021 Архитектура этой сети похожа на упрощение OpenNet. В OpenNet также был слой на проводных платах и слой на связанных. И кроме этого имелся слой на беспроводных платах. В OpenNet, правда, использовались обычные компьютеры, а не серверы, поэтому система была более громоздкой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
ECS Автор темы 1 905 Опубликовано: 27 марта, 2021 42 минуты назад, eu_tomat сказал: Архитектура этой сети похожа на упрощение OpenNet. В OpenNet также был слой на проводных платах и слой на связанных. И кроме этого имелся слой на беспроводных платах. В OpenNet, правда, использовались обычные компьютеры, а не серверы, поэтому система была более громоздкой. Да, принцип схож. Однако эта схема локальна и служит для обмена сообщениями среди ограниченной группы машин, да и работает на любом мусоре - были бы слоты под карты. Как следствие, никто не будет спамить широковещательными пакетами на беспроводные точки, из-за чего связь не отвалится, и проблема "дудосеров с 9 планшетами" около роутера 2 уровня просто не возникнет. Как бы выразиться поточнее... тут возникает щекотливая ситуация, когда с точки зрения интересности отыгрыша роли на IT-сервере использование OpenNet или ZN реально веселее. Также это помогает изучить нюансы работы реальных сетей на примитивном игровом уровне. А с точки зрения практичности для клана с десятком компьютеризированных электростанций/ферм в различных мирах централизованная и приватная схема надёжнее и быстрее. Имхо, пока не настанет всесерверная утопия, пока не передохнут диссиденты-дудосеры, игроки будут ориентироваться на локальные сети 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
eu_tomat 2 155 Опубликовано: 27 марта, 2021 5 минут назад, ECS сказал: А с точки зрения практичности для клана с десятком компьютеризированных электростанций/ферм в различных мирах централизованная и приватная схема надёжнее и быстрее. Имхо, пока не настанет всесерверная утопия, пока не передохнут диссиденты-дудосеры, игроки будут ориентироваться на локальные сети Полностью согласен. Я сам на игровых серверах использую исключительно приватные сети, а широковещательные пакеты в беспроводных сетях посылаю только для аварийной коммуникации, когда секретность перестаёт быть приоритетной. Дудосеры вряд ли исчезнут, они тоже отыгрывают роль в игровом процессе, внося дополнительное разнообразие. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
AlexCatze 58 Опубликовано: 27 марта, 2021 Не могу не задать свой любимый вопрос. Что будет, если я попробую отправить пакет больше 8 килобайт? Такой вариант предусмотрен, или мне самому нужно разбивать и собирать большие пакеты? 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
ECS Автор темы 1 905 Опубликовано: 27 марта, 2021 1 час назад, AlexCatze сказал: Не могу не задать свой любимый вопрос. Что будет, если я попробую отправить пакет больше 8 килобайт? Такой вариант предусмотрен, или мне самому нужно разбивать и собирать большие пакеты? Это не позволит сделать tunnel.send() на клиенте и сдохнет с ошибкой "packet too big". Разбивать нужно самому, конечно, т.к. взаимодействие с серваком находится на сетевом уровне модели OSI. Пакетная передача, шифрование, туннелирование и т.п. - это всё же чутка иная задача, обычно перекладываемая на библиотеки, и в 99% случаев не возникающая у "программ новичков" Если всё же требуется гарантированная стойкость своей личной сети, чтобы сервер также учитывал размеры входящих пакетов, то изменить прошивку не составит труда: local maxPacketSize = 8192 ... -- 8 extra bytes for safety local packetSize = 8 for i = 6, #e do -- Two bytes overhead for each value packetSize = packetSize + tostring(e[6]):len() + 2 end -- Everything is ok, packet size is within the limits if packetSize <= maxPacketSize then -- Linked card with target channel is connected to this computer if tunnelChannels[e[6]] then tunnelChannels[e[6]].send(tunnelAddresses[e[2]].getChannel(), table.unpack(e, 7)) -- Notify other network server to search the target linked card else modem.broadcast(modemPort, "r", e[6], tunnelAddresses[e[2]].getChannel(), table.unpack(e, 7)) end -- Do something when packet size is beyond limits else tunnelAddresses[e[2]].send("packet is too big, server limit is " .. maxPacketSize) end В результате отправитель получит: Могу вставить эту фичу в сырцы, не вопрос Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Zer0Galaxy 2 187 Опубликовано: 28 марта, 2021 13 часа назад, eu_tomat сказал: В OpenNet, правда, использовались обычные компьютеры, а не серверы, поэтому система была более громоздкой. В последней в реализации OpenNet уже использовались сервера. Вот только мне помнится, что я вставлял по три связанных карты в сервер. Таким образом один кубик серверной стойки объединял до двенадцати связанных карт. Ах да, я же использовал креативные сервера. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах