Укрепление эксплуатации: healthcheck'и, лимиты ресурсов, логи, self-hosted шрифты, smoke-проверка в CI
Deploy / deploy (push) Failing after 0s
Deploy / deploy (push) Failing after 0s
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include "Lobby.hpp"
|
||||
#include "Game.hpp"
|
||||
#include "Log.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
@@ -74,6 +75,10 @@ void Lobby::onOpen(WS *ws) {
|
||||
}
|
||||
|
||||
void Lobby::onClose(WS *ws) {
|
||||
if (!ws->getUserData()->room_id.empty()) {
|
||||
logLine("connection closed in-room: " + ws->getUserData()->room_id + " " +
|
||||
ws->getUserData()->nickname);
|
||||
}
|
||||
endActiveGameIfAny(ws->getUserData()->room_id, ws);
|
||||
removePlayerFromRoom(ws);
|
||||
sockets_.erase(ws);
|
||||
@@ -107,6 +112,8 @@ void Lobby::onMessage(WS *ws, std::string_view message) {
|
||||
handleGameReady(ws);
|
||||
} else if (type == "game.input") {
|
||||
handleGameInput(ws, payload);
|
||||
} else if (type == "ping") {
|
||||
send(ws, "pong", {});
|
||||
} else {
|
||||
sendError(ws, "unknown_type", "unknown message type: " + type);
|
||||
}
|
||||
@@ -186,6 +193,8 @@ void Lobby::handleCreateRoom(WS *ws, const json &payload) {
|
||||
std::string room_id = room.id;
|
||||
rooms_[room_id] = std::move(room);
|
||||
|
||||
logLine("room created: " + room_id + " mode=" + mode + " by=" + data->nickname);
|
||||
|
||||
send(ws, "lobby.room_joined", {
|
||||
{"room_id", room_id},
|
||||
{"name", room_id},
|
||||
@@ -227,6 +236,9 @@ void Lobby::handleJoinRoom(WS *ws, const json &payload) {
|
||||
room.players.push_back({data->player_id, data->nickname, ws});
|
||||
data->room_id = room_id;
|
||||
|
||||
logLine("player joined: " + room_id + " " + data->nickname + " (" +
|
||||
std::to_string(room.players.size()) + "/" + std::to_string(kMaxPlayersPerRoom) + ")");
|
||||
|
||||
send(ws, "lobby.room_joined", {
|
||||
{"room_id", room_id},
|
||||
{"name", room_id},
|
||||
@@ -243,6 +255,7 @@ void Lobby::handleLeaveRoom(WS *ws) {
|
||||
sendError(ws, "not_in_room", "you are not in a room");
|
||||
return;
|
||||
}
|
||||
logLine("player left: " + ws->getUserData()->room_id + " " + ws->getUserData()->nickname);
|
||||
endActiveGameIfAny(ws->getUserData()->room_id, ws);
|
||||
removePlayerFromRoom(ws);
|
||||
broadcastRoomsToLobby();
|
||||
@@ -301,7 +314,11 @@ void Lobby::maybeStartGame(const std::string &room_id) {
|
||||
|
||||
room.state = "playing";
|
||||
|
||||
logLine("game started: " + room_id + " mode=" + room.mode + " players=" +
|
||||
std::to_string(room.players.size()));
|
||||
|
||||
auto game = std::make_unique<Game>(room, [this, room_id]() {
|
||||
logLine("game finished: " + room_id);
|
||||
auto rit = rooms_.find(room_id);
|
||||
if (rit != rooms_.end()) {
|
||||
rit->second.state = "waiting";
|
||||
@@ -358,6 +375,7 @@ void Lobby::removePlayerFromRoom(WS *ws) {
|
||||
room.players.end());
|
||||
|
||||
if (room.players.empty()) {
|
||||
logLine("room removed: " + it->first + " (empty)");
|
||||
rooms_.erase(it);
|
||||
} else {
|
||||
broadcastRoomUpdated(room);
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
// События лобби/игр пишутся в stdout — их забирает `docker logs`, это единственный
|
||||
// способ понять в проде, что происходило с комнатами, не заходя в контейнер.
|
||||
inline void logLine(const std::string &message) {
|
||||
std::time_t now = std::time(nullptr);
|
||||
std::tm tm{};
|
||||
localtime_r(&now, &tm);
|
||||
char ts[20];
|
||||
std::strftime(ts, sizeof(ts), "%Y-%m-%d %H:%M:%S", &tm);
|
||||
// endl, а не "\n": stdout в контейнере идёт в пайп и полностью
|
||||
// буферизуется — без сброса docker logs видит строки только на exit
|
||||
std::cout << "[" << ts << "] " << message << std::endl;
|
||||
}
|
||||
+12
-1
@@ -4,12 +4,23 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "Lobby.hpp"
|
||||
#include "Log.hpp"
|
||||
|
||||
int main() {
|
||||
Lobby lobby;
|
||||
|
||||
uWS::App()
|
||||
.ws<PerSocketData>("/ws", {
|
||||
// сообщения у нас мелкие (input/lobby) — 16 МиБ дефолта не нужен,
|
||||
// лимит режет попытки завалить сервер гигантскими фреймами
|
||||
.compression = uWS::DISABLED,
|
||||
.maxPayloadLength = 8 * 1024,
|
||||
// сервер сам шлёт WS-ping в пределах idleTimeout; клиент дополнительно
|
||||
// шлёт application-ping раз в 25с — соединение переживает NAT-таймауты
|
||||
.idleTimeout = 300,
|
||||
.maxBackpressure = 16 * 1024,
|
||||
.closeOnBackpressureLimit = true,
|
||||
.sendPingsAutomatically = true,
|
||||
.open = [&lobby](auto *ws) {
|
||||
lobby.onOpen(ws);
|
||||
},
|
||||
@@ -22,7 +33,7 @@ int main() {
|
||||
})
|
||||
.listen(9001, [](auto *token) {
|
||||
if (token) {
|
||||
std::cout << "gameserver listening on :9001\n";
|
||||
logLine("gameserver listening on :9001");
|
||||
} else {
|
||||
std::cerr << "failed to listen on :9001\n";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user