Клиент-серверная разработка - это сложно.

Если мы посмотрим на эволюцию разработки программного обеспечения с начала примерно до 1990-х годов, разработка программного обеспечения в целом стала проще, и конечные пользователи получили все больше возможностей разрабатывать передовое программное обеспечение. Вершиной были среды разработки, такие как HyperCard от Apple и Visual Basic от Microsoft.

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

Проблема с программированием клиент-сервер заключается в том, что оно по своей сути очень сложно. Приложения, которые было легко создавать для конечных пользователей с помощью HyperCard в 1980-х, теперь требуют лучших программистов в области компьютерных наук. Билл Аткинсон, создатель HyperCard, полагал, что, если бы он подумал о сети, HyperCard, возможно, преуспела бы вместо HTML. Однако это упрощенный взгляд, и можно утверждать, что успех HTML объясняется тем, что он перенес логику на сервер, что HyperCard вряд ли могла сделать.

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

Одной амбициозной платформой, которая пыталась упростить программирование клиент-сервер, является платформа Meteor, запущенная в 2012 году. Meteor решает почти все проблемы клиент-сервер, он позволяет запускать один и тот же код как на клиенте, так и на сервере, обновляет данные на сервер может автоматически распространяться на клиента и обновлять DOM. У Meteor есть собственный протокол клиент-сервер, называемый DDP, который скрыт от разработчика. Архитектура продумана, но, к сожалению, опередила свое время, и разработка не успевала за последними разработками в веб-фреймворках. Вдобавок я серьезно критикую Meteor за то, что он остается тяжелым для клиента.

Решение: клиент на стороне сервера (SSC)

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

Предлагаемая мной архитектура серверного клиента (SSC) состоит из клиентской библиотеки JavaScript, которая служит двум целям:

  1. Получает обновления DOM с сервера и обновляет DOM на стороне клиента
  2. Отправляет события от клиента на сервер

По сути, браузер становится похож на причудливый интерфейс терминала. Он просто обрабатывает графические обновления и отправляет ввод от пользователя обратно на сервер.

Сервер будет поддерживать представление DOM каждого подключенного клиента и обрабатывать всю логику, пользовательские события и обновления DOM.

Это значительно упрощает разработку клиент-сервер. Сложность кодирования может быть уменьшена с помощью таких инструментов, как HyperCard и Visual Basic.

Проблемы с SSC

Архитектура SSC ​​привносит ряд проблем. Первый - это задержка. Поскольку вся логика обрабатывается на сервере, время ответа не может быть быстрее, чем задержка соединения. Пользователи в Австралии сталкиваются с задержкой около 300 мс для серверов в США. Это ограничение в 3 кадра в секунду.

Другая проблема - это серверные ресурсы. Сервер должен поддерживать открытые соединения со всеми подключенными клиентами, сервер должен поддерживать полное представление DOM того, что видит клиент, а сервер обрабатывает ВСЮ клиентскую логику. Это значительная нагрузка на память и процессор.

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

Решение проблем SSC

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

Задержка

Я вижу два способа уменьшить задержку.

Во-первых, серверы можно развернуть в облаке в более близких к пользователю местах. Пользователь из Австралии должен подключиться к серверу в Австралии. Тогда задержка уменьшится примерно до 30 мс, или в 10 раз меньше, что приведет к максимальной частоте кадров 30 кадров в секунду, что должно быть приемлемым.

Во-вторых, можно использовать методы, чтобы сделать интерактивные задачи более отзывчивыми. Например, по возможности следует использовать CSS для немедленной обратной связи (например, при наведении курсора). Кроме того, структура SSC ​​может предоставлять стандартизированные реализации общих задач на стороне клиента, которые требуют немедленной обратной связи, которые в настоящее время не предоставляются HTML / CSS, а также не требуют от разработчика сложности клиент-сервер.

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

Ресурсы на стороне сервера

Ресурсы на стороне сервера обязательно увеличатся. Однако в веб-разработке наблюдается тенденция к увеличению серверных ресурсов со временем, как правило, для упрощения разработки. Таким образом, снижение сложности разработки и увеличение ресурсов сервера обычно было приемлемым компромиссом в зависимости от приложения.

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

Возможная архитектура на основе Node.js

Node.js будет предоставлять клиенту базовый HTML-документ с библиотекой JS, которая обрабатывает протокол связи с сервером. Никакой другой JS не отправляется клиенту (хотя это не ограничение и может иметь место, например, если используются веб-компоненты).

Фреймворк SSC на основе узла может быть основан на явном выражении и использовать либо серверные события (SSE), либо веб-сокеты.

Когда создается новое соединение для SSE или веб-сокетов, Node создает новый экземпляр клиента.

Фреймворк будет использовать компонентную архитектуру, аналогичную Angular. Компонент страницы будет представлять всю страницу, и каждый компонент имеет связанный шаблон HTML. Приложение, созданное с использованием этой платформы, должно указывать корневой или начальный компонент страницы. Экземпляр компонента страницы будет создан при первом подключении, и связанный шаблон будет загружен в иерархию DOM с обновлениями DOM, отправленными клиенту, представляющими начальное состояние шаблона компонента страницы. Как и Angular, другие классы компонентов могут быть созданы с их собственными шаблонами.

Шаблоны позволят привязать события компонентов к функциям. Функции реализованы в компоненте и выполняются на сервере. Когда событие происходит на клиенте, он отправляет событие обратно на сервер, и сервер выполняет функцию на соответствующем компоненте. Изменения в DOM в результате обработчика событий затем передаются обратно клиенту для отображения пользователю.

Если используются события на стороне сервера, клиент отправляет один запрос GET, чтобы открыть поток событий с сервера. Однако для отправки обновлений событий от клиента серверу потребуется реализовать отдельный обработчик запросов POST для обработки клиентских событий. В запросе события необходимо создать идентификатор клиента, чтобы экземпляр клиента можно было найти на сервере, а событие было отправлено правильному компоненту.

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

Веб-сокеты более эффективны, однако события на стороне сервера могут соответствовать сценариям, в которых требуется протокол HTTP (или, более конкретно, когда протоколы, отличные от HTTP, ограничены).

Будущее

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