Добавлен middlefinger24,
опубликован
Вступление
- Как работают онлайн игры?
Разбираясь в этом вопросе, мне захотелось сделать её собственными руками.
Задачей было сделать максимально примитивное приложение, которое работало бы через интернет, позволяя игрокам с разных точек планеты подключаться и делать примитивные игровые действия.
А именно выбирать игровое лобби, писать в чат, и менять позицию своего "персонажа" в игровой локации.
- Это не так сложно как ожидалось.
Далее я поделюсь тем, какие решения в разработке я выбрал и как достиг того что получилось.
Как устроена эта игра?
- Установка подключения и клиент-серверный обмен сообщениями.
При подключении сервер "регистрирует" клиента в своей памяти, назначая ему случайный никнейм на возникший конект.
Далее назначает ему лобби, если лобби на сервере нет, создает его. После этого отправляет клиенту стартовую информацию о лобби в которое он зашел, оповещая в чате всех других игроков, находящихся в этом лобби.
- Реакция на действия игрока
Например, если игрок что-то написал в чат, сервер определит что это за игрок, определит его лобби и добавит его сообщение в хранилище сообщений чата этого лобби, далее транслируя его всем другим клиентам и все они увидят на своем клиенте новое сообщение в чате.
Такая же логика и при клике игрока на канвас, игрок кликает, отправляется сообщение. Сервер его принимает, меняет внутри себя состояние локации 2д локации этого лобби, и транслирует информацию о новом состоянии локации всем игрокам этого лобби.
При отключении соединения, сервер оповещает всех игроков в лобби этого игрока о том что он вышел, и удаляет все данные о нем, обрывая связь.
Как я реализовал обмен сообщениями по сети?
- Выбираем обмен сообщениями через websocket
Она позволяет установить клиенту и серверу постоянное подключение, по которому можно обмениваться сообщениями в реальном времени в двустороннем направлении. От сервера к клиенту, и от клиента к серверу.
- Сообщения формата JSON
Клиентская часть
- Десктопное приложение или html-страница в браузере, сетевой обмен данными один и тот же
- Из чего состоит клиентская часть?
И javascript обработчики этих кнопок и форм ввода.
- "Сердце" кода клиентской части
Javascript дает нам API для работы с вебсокетами, и всего одной строчкой мы создаем websocket подключение, а закулисами под этой строкой происходит множество непонятных нам действий, благодаря которым чипы вашего компьютера могут обмениваться сигналами с чипами серверного компьютера.
вот так мы устанавливаем websocket соединение по адресу
const socket = new WebSocket('ws://localhost:8080/ws'); // - замените url на адрес и порт своего сервера
А этой функцией мы читаем пришедшие по этому соединению сообдения
//слушаем сервер
socket.onmessage = function(event) {
const message = JSON.parse(event.data);
//далее пишем реакцию вашего клиента на полученное сообщение
}
А вот такой строкой мы отправляем сообщение серверу
socket.send(JSON.stringify(jsonChatMessage));
Я буду приводить вам только самые важные строки кода, на которых держится все мое приложение. Весь остальной код это уже попытка их организовать во что-то большее и сложное.
Серверная часть
- Выбор технологий для серверной части
- Главные моменты в серверном коде, благодаря которому обмен сообщениями возможен
Если клиент обратится по url сервера, сервер даст ему html страничку.
fs := http.FileServer(http.Dir(basePath))
mux.Handle("/", http.StripPrefix("/", fs))
Как только html страница будет получена клиентом, она обратится по другому url к серверу, чтобы установить websocket соединение
mux.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
transport.ServeWs(MyHub, MyConnectionsManages, w, r)
})
Клиент в браузер вводит url, функция-обработчик на стороне сервера на это реагирует и отправляет что-то в ответ клиенту.
Теперь рассмотрим как на стороне сервера формируется подключение по websocket в обработчике websocket url
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println("Ошибка установки соединения WebSocket:", err)
return
}
defer conn.Close()
- Подключение также создается одной строкой, или выдаст ошибку если что-то пошло не так внутри.
Этой строкой кода, сервер будет читать входящие сообщения по этому соединению
err := wsCon.conn.ReadJSON(&msgData)
if err != nil {
log.Printf("Error reading JSON: %v", err)
break
} else {
cm.DistributeMessage(wsCon.Name, msgData)
}
Получили, проверили на ошибки? Все хорошо? Делаем какие-то вычисления с этим сообщением
Вот так отправляем сообщение клиенту
err := conn.conn.WriteMessage(websocket.TextMessage, messageJSON)
- Все так просто?
Как вы можете наблюдать, все устроено довольно просто, а умные люди, разрабатывающие языки программирования и сетевые библиотеки для них, уже написали для нас свои API, благодаря которым все сложные сетевые взаимодействия превращаются для нас в 2-3 строки кода.
Как организована серверная логика?
- Механизмы, координирующие множество подключений и сообщений
Все пришедшие от него JSON сообщения конвертируются в структуры golang написанные мной чтобы сервер мог ими манипулировать.
Специальные утилиты такие как connections manager и exchanger работают как посредники между пулом всех активных соединений hub и конкретным websocket соединением, определяя кого в какое лобби назначить, или кому какое сообщение в данный момент отправить и так далее.
- Конкурентный доступ к данным
Как получилось сделать игру доступную в интернете?
- Докер вездесущий
Загрузил его на docker hub.
- Дешевые хостинги
После этого установил на нее докер, скачал с docker hub свой образ и собственно, запустил контейнер на основе этого образа, поигравшись с портами и другими конфигами. Немного усилий и приложение доступно в интернете.
Полезные ссылки
В конечном итоге у меня все получилось и в эту игру вы можете сыграть прямо сейчас, попрыгать кубом по канвасу, и початиться с друзьями в разных лобби:
- Сыграть в поделку
Торопитесь, через месяц хостинг игры закончится
- Исходный код проекта:
`
ОЖИДАНИЕ РЕКЛАМЫ...
Чтобы оставить комментарий, пожалуйста, войдите на сайт.
сочная выжимка самых важных строк кода
и репецт как повторить
только сильные преодолеют стену
Отредактирован ScorpioT1000
текста в статье буквально кот наплакал
все самое важное, 6 строчек кода на которых все стоит