Подтвердить что ты не робот

Как я должен архивировать мой (главным образом) текстовый игровой сервер?

Думайте MUDs/MUCK, но, возможно, с аватарами или языковыми иллюстрациями. Мой язык выбора рубин.

Мне нужно обрабатывать несколько постоянных соединений с асинхронной передачей данных между сервером и его различными клиентами. Единая база данных должна быть обновлена ​​на основе активности, происходящей на клиентских сеансах. Активность в каждом сеансе клиента может потребовать немедленного обновления нескольких других клиентов (пользователь входит в комнату, пользователь отправляет другому пользователю личное сообщение).

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

Per emboss отличный ответ, я начал смотреть на внутренности определенных HTTP-серверов, поскольку веб-приложения обычно могут избегать проблем с потоками из-за того, насколько тщательно проблема абстрагируется самими серверами.

Я не хочу использовать EventMachine или GServer, потому что я еще не понимаю, что они делают. Когда у меня есть общее представление о том, как они работают, какие проблемы они решают и почему они полезны, я буду чувствовать себя комфортно с ним. Моя цель здесь заключается не в том, чтобы "написать игру", а "написать игру и узнать, как работают некоторые элементы более низкого уровня". Я также не понимаю границ определенных терминов; например, является ли "приложения с подключением к вводу/выводу" дополнением к "приложениям, управляемым событиями"? И наоборот?

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

Любые книги, электронные книги, онлайн-ресурсы, примеры проектов или другие лакомые кусочки, которые вы можете предложить, - это то, что я действительно переживаю.

То, как я делаю сейчас, - это использовать IO#select для блокировки списка подключенных сокетов с таймаутом 0,1 секунд. Это заставляет любую информацию считывать в потокобезопасную очередь чтения, а затем всякий раз, когда она попадает в таймаут, она извлекает данные из потоковой очереди записи. Я не уверен, что тайм-аут должен быть короче. Существует второй поток, который опросает очередь чтения потоков сокета и обрабатывает "запросы". Это лучше, чем то, как я работал вначале, но все же может быть не идеальным.

Я разместил этот вопрос в Hacker News и связался с несколькими ресурсами, над которыми я работаю; ничего подобного было бы здорово:

4b9b3361

Ответ 1

Хотя вам, вероятно, не нравится это слышать, я бы порекомендовал сначала начать исследование HTTP-серверов. Хотя программирование для них казалось скучным, синхронным и непостоянным для вас, это было только потому, что создатели серверов сделали свою работу, чтобы скрыть детали от вас так колоссально хорошо - если вы думаете об этом, веб-сервер так не синхронный (это не значит, что миллионы людей должны дождаться, пока прочитаете этот пост, пока не закончите... concurrency:)... и потому, что эти звери делают свою работу так хорошо (да, я знаю, что мы много кричим на них, но в конце концов большинство HTTP-серверов являются выдающимися компонентами программного обеспечения), это определенная отправная точка для изучения, если вы хотите узнать об эффективной многопоточности. Операционные системы и реализации языков программирования или игр - еще один хороший источник, но, возможно, немного дальше от того, что вы намереваетесь достичь.

Если вы действительно собираетесь загрязнять свои пальцы, я бы предложил сначала ориентироваться на что-то вроде WEBrick - он поставляется с Ruby и полностью реализована в Ruby, поэтому вы узнаете все о концепциях потоков Ruby. Но будьте осторожны, вы никогда не приблизитесь к производительности решения для стойки, которое находится поверх веб-сервера, который реализован на C, например thin.

Итак, если вы действительно хотите быть серьезным, вам придется свернуть свою собственную реализацию сервера в C (++) и, возможно, сделать ее поддержкой Rack, если вы собираетесь поддерживать HTTP. Я бы сказал, что я бы сказал, особенно если вы хотите, чтобы ваш конечный результат был конкурентоспособным. C-код может быть невероятно быстрым, но все это легко, чтобы быть невероятно медленным, а также в природе низкоуровневых вещей. И мы еще не обсуждали управление памятью и безопасность. Но если это действительно ваше желание, идите на это, но я сначала буду копаться в известных реализациях сервера, чтобы получить вдохновение. Посмотрите, как они работают с потоками (объединение) и как они реализуют "сеансы" (вы хотите настойчивость). Все, что вы хотите, может быть сделано с помощью HTTP, даже лучше, когда используется с умным интерфейсом REST, существующие приложения, которые поддерживают все перечисленные вами функции, являются живыми доказательствами для этого. Так что движение в этом направлении было бы не совсем неправильным.

Если вы все еще хотите придумать свой собственный собственный протокол, используйте его на TCP/IP как самый низкий приемлемый общий знаменатель. Выйдя за рамки этого, вы окажетесь в проекте, который, возможно, все еще будут кодировать ваши внуки. Это действительно так низко, как я бы осмелился пойти, когда дело доходит до сетевого программирования.

Если вы используете его как библиотеку или нет, загляните в EventMachine и его концептуальную модель. С точки зрения управления событиями ( "неблокирование" ) IO в вашем путешествии было бы небрежным в контексте изучения/переосмысления правильных колес. Закуска для управляемых событиями программ, объясняющая преимущества node.js как веб-сервера .

Основываясь на ваших требованиях: асинхронная связь, несколько "подписчиков" реагируют на "события", которые публикуются централизованно; это действительно хороший кандидат на основанную на событиях/основанную на сообщениях архитектуру.


Некоторые книги, которые могут быть полезны в вашем путешествии (только для Linux/C, но концепции универсальны):

(Это были классики)

  • Интерфейс программирования Linux - если вы только намереваетесь купить одну книгу, пусть это будет, я еще не полностью готов, но это действительно потрясающе и охватывает все темы, которые вам нужно знать о вашем приключении.

Проекты, которые вы можете проверить:

Ответ 3

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

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

Время отклика также играет большую роль - я не думаю, что это такое большое дело с играми в стиле MUD, но для веб-серверов или игр FPS это огромная проблема.

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

Threading действительно является реальной проблемой, и она создает сложный для тестирования код, поэтому, в то время как ответ dash-tom-bang действительно немного не соответствует теме, тестируемость является серьезной проблемой.

Ответ 4

Правильный способ - использовать тестовую разработку. Затем вы обнаружите, что вам нужно изобретать в тот момент, когда вам нужно его изобретать.

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