Полный исходный код этого проекта можно найти здесь. Играйте в игру здесь!

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

Мы с Дэниелом постоянно обсуждаем его побочные проекты и игровые идеи, и однажды он показал мне свою веб-версию Codenames. Это было здорово, он добавил потрясающие функции, такие как добавление третьей команды, использование большего игрового поля и даже использование специальных словарей, таких как слова из Cards Against Humanity - этот, вероятно, даст интересные подсказки! Мне понравилась эта идея, но у его версии был один недостаток… все взаимодействия были ручными, то есть агентам и мастерам шпионов приходилось обновлять свои доски самостоятельно по ходу игры.

Выполнив довольно небольшой объем работы с веб-приложениями в реальном времени в прошлом и будучи довольно новичком в современных фреймворках Javascript, я решил, что это идеальное время, чтобы изучить и укрепить свои навыки в Vue.js и веб-сокетах. Я когда-либо использовал веб-сокеты для связи между сервером и браузером только в проекте с открытым исходным кодом, созданном мной и моим бывшим коллегой и новым автором блога Рональдом Эддингсом.

Мы спроектировали и построили модульное приложение / платформу для проверки узлов в сети с поддержкой IPv6, названную IPv6 Framework. Это приложение запускало сетевой сниффер, используя Flask и Scapy на сервере, и, когда оно получало пакеты, соответствующие нашим фильтрам, оно передавало объект JSON на интерфейс через Socket.io. Здесь не происходит ничего слишком сумасшедшего… ни комнат, ни пользователей; просто сервер, который приятно разговаривает с клиентом. На этом мой опыт работы с веб-сокетами закончился… до сих пор.

Хватит болтать о прошлых проектах или о том, как этот проект был реализован, давайте приступим к работе и создадим это приложение!

Планирование

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

Для начала мы знаем, что приложение будет состоять из двух отдельных частей: внешнего интерфейса Vue.js и внутреннего интерфейса Flask. Кроме того, мы будем использовать Vuetify, чтобы придать нашему интерфейсу немного индивидуальности, а также socket.io, чтобы позволить нашему интерфейсу общаться с нашим сервером.

Серверная архитектура

При планировании сервера я решил использовать исходный репозиторий Flask. Имея за плечами некоторый опыт работы с Flask-SocketIO, я знал, что довольно легко что-то настроить и запустить. Поскольку мы используем Flask для обработки наших веб-сокетов и Vue для интерфейса, я отказался от типичного подхода Flask к рендерингу шаблонов с использованием Jinja2 - за исключением обслуживания встроенного производственного кода. Вместо этого Vue будет обрабатывать весь код отображения, а Flask, по сути, был API веб-сокета.

Клиентская архитектура

Для нашего интерфейса мы будем использовать webpack для размещения сервера разработки с горячей перезагрузкой, чтобы мы могли видеть обновления нашего кода в режиме реального времени в браузере. Но это еще не все - при правильной настройке webpack возьмет модули кода, которые вы используете, и объединит их в более компактный файл. Например, если вы хотите использовать Vue, но вам нужно всего несколько функций из него, webpack будет упаковывать эти функции только в скомпилированный файл javascript.

Используя webpack, мы создадим интерфейс, используя Vue.js, легкий, но надежный фреймворк javascript. Vue обычно упоминается в тех же предложениях, что и React и Angular, поскольку это более легкая и легкая в освоении альтернатива обоим фреймворкам. Vue имеет множество функций, которые делают его идеальным для этого проекта, включая реактивность модели, простые в использовании шаблоны и компоненты, поддержку перехода CSS, гибкую маршрутизацию и компонент централизованного управления состоянием. Эти функции позволяют нам писать гибкий интерфейс, сохраняя при этом наши игровые данные управляемым образом.

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

Собираем все вместе

Уф, количество компонентов, определяющих наше приложение, начинает расти! Чтобы понять всю сложность, вот простая диаграмма, показывающая, как все это взаимосвязано. Я хотел бы сказать, что сделал это на этапе «планирования», но, к сожалению, этот шаг еще не проработан. Тем не менее, это в основном то, что я представлял себе в голове, когда планировал приложение!

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

Обновление 2017/12/05 - Узнайте, как добавить поддержку веб-сокетов на сервер Flask, в Части 2 этой серии!