Сокеты на примере игр

Вы задумывались, что когда вы играете в Доту, Кс или Apex, то вы видите у себя на компьютере то же, что и другие игроки в режиме реального времени? Расположение на карте, когда кто-то стреляет или использует способности - все эти данные синхронизированы между всеми игроками одновременно.

Сокеты на примере игр
2323

Смешались в кучу кони, люди...

Есть модель сетевого взаимодействия OSI, разбитая для удобства на уровни абстракции от железа. "Сайтики" в браузере работают на протоколе TCP транспортного уровня и различных версий HTTP прикладного уорвня поверх него по принципу запрос-ответ (request-response). Каждый раз, когда веб-клиент (например, браузер) хочет узнать новые данные, устанавливается (новое) TCP соединение с сервером, происходит диалог, и соединение закрывается. Это очень долго для интерактивных применений.

Плюсы TCP в том, что он гарантирует доставку байтов в обе стороны, за это приходится платить высоким общим временем "доставки последнего байта сообщения" (end-to-end latency). Особенность HTTP в том, что в оригинале это протокол передачи текста, а передавать бинарные данные по нему сложно/дорого, поэтому изобрели разные костыли, чтоб немножко сломать абстракцию, но улучшить производительность.

Там, где требуется низкая задержка (latency), придумали костыли (например, не закрывать TCP соединение после окончания запроса, так работает WebSockets) или вообще отказались от "дорогого" TCP.

В интерактивных приложениях, например играх, часто используют UDP как альтернативу TCP на траспортном уровне. Он не гарантирует доставку байтов до адресата, но при этом серверу не надо держать по сокету на клиент. Получается экономичнее и быстрее. Минус — обеспечивать целостность полученных данных надо самим приложениям, не надеясь на транспортный уровень.

В качестве прикладного протокола передачи обычно используют какой-нибудь бинарный протокол типа Protobuff, CBOR, BSON и кучу других вариантов, или пишут что-то своё на коленке. Плюсы: они все быстрее в обработке, чем текстовые типа HTTP.

Теперь про количество соединений. Современные ОС абстрагируют от нас все, что ниже прикладного уровня. В замен приложения получают абстрактный _сокет_ — дырку, из которой можно читать и куда можно писать. Таких сокетов на всю ОС ограниченное количество, что зависит от реализации, но можно говорить о _десятках тысяч_ доступных сокетов.

Вопрос не в том, чтоб открыть и держать все эти сокеты доступными, а в том, что получать и передавать данные ото всех клиентов сразу не получится, потому что сетевая карта имеет ограниченную пропускную способность. То есть если наши клиенты постоянно хотят обмениваться данными с сервером, чем выше количество клиентов (больше даннвх требует обработки), тем дольше будет физическое время ожидания отправки и получения байтов из сети со стороны сервера. Это называется congestion. И связано с тем, что сокеты пишут и читают из специальной очереди на сетевой карте (или не одной, но принципа не меняет). И чем больше мы хотим писать и читать, тем длинее очереди, и, значит, увеличивается задержка.

То есть, если у нас есть например Веселая Ферма, клиенты которой просто есть и редко (речь про секунды и минуты) хотят получить данные или передать, то с помощью специальных техник один сервер с одной сетевой картой может обрабатывать _сотни тысяч_ клиентов игры. Конечно, если они ВСЕ СРАЗУ захотят писать серверу, мы в лучшем случае будем долго это все обрабатывать (часы). В худшем - все развалится. Это хорошо видно на запусках популярных игр. Из последнего — Диабло 4 с очередями на вход.

Другое дело приложения с высоким трафиком данных. Кроме того, что это трафик нужно получить и отправить с приемлемой задержкой (не всем нравится ждать реакции на выстрел больше 200 мс), так ещё и обработать все это надо. Поэтому в шутерах, гоночках и всем сложнее пасьянса есть как технические, так и геймдизайнерские ограничения на количество игроков на сессию/сервер/... И действительно ограничения тут обычно порядка 100 клиентов на одну сессию.

Как-то так.

2
Ответить

Вот это мощно)

Ответить