Каркас проекта: ТЗ, nginx+gameserver(uWebSockets) в Docker, /ws echo
Frontend — чистый HTML/CSS/JS без сборки (резюме, проекты, игра-заглушки). Gameserver — C++ на uWebSockets (CMake FetchContent), протокол hello/lobby.list_rooms/error проверен end-to-end.
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(cactoz_gameserver CXX C)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
include(FetchContent)
|
||||
|
||||
FetchContent_Declare(
|
||||
uwebsockets
|
||||
GIT_REPOSITORY https://github.com/uNetworking/uWebSockets.git
|
||||
GIT_TAG v20.79.0
|
||||
)
|
||||
FetchContent_MakeAvailable(uwebsockets)
|
||||
|
||||
# uWebSockets pulls uSockets in via a git submodule, which plain FetchContent
|
||||
# does not check out. Fetch the exact commit uWebSockets v20.79.0 pins instead.
|
||||
FetchContent_Declare(
|
||||
usockets_src
|
||||
GIT_REPOSITORY https://github.com/uNetworking/uSockets.git
|
||||
GIT_TAG 86097c490263ab662d62e8e7b541390bdec7d149
|
||||
)
|
||||
FetchContent_MakeAvailable(usockets_src)
|
||||
|
||||
FetchContent_Declare(
|
||||
json
|
||||
GIT_REPOSITORY https://github.com/nlohmann/json.git
|
||||
GIT_TAG v3.12.0
|
||||
)
|
||||
FetchContent_MakeAvailable(json)
|
||||
|
||||
file(GLOB USOCKETS_SOURCES
|
||||
${usockets_src_SOURCE_DIR}/src/*.c
|
||||
${usockets_src_SOURCE_DIR}/src/eventing/*.c
|
||||
)
|
||||
add_library(usockets STATIC ${USOCKETS_SOURCES})
|
||||
target_include_directories(usockets PUBLIC ${usockets_src_SOURCE_DIR}/src)
|
||||
target_compile_definitions(usockets PUBLIC LIBUS_NO_SSL LIBUS_USE_EPOLL)
|
||||
|
||||
add_executable(gameserver
|
||||
src/main.cpp
|
||||
)
|
||||
target_include_directories(gameserver PRIVATE
|
||||
${uwebsockets_SOURCE_DIR}/src
|
||||
src
|
||||
)
|
||||
target_link_libraries(gameserver PRIVATE usockets nlohmann_json::nlohmann_json pthread z)
|
||||
@@ -0,0 +1,15 @@
|
||||
FROM debian:bookworm AS build
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
build-essential cmake git ca-certificates zlib1g-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
WORKDIR /app
|
||||
COPY CMakeLists.txt ./
|
||||
COPY src ./src
|
||||
RUN cmake -B build -DCMAKE_BUILD_TYPE=Release && cmake --build build -j"$(nproc)"
|
||||
|
||||
FROM debian:bookworm-slim
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends zlib1g \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
COPY --from=build /app/build/gameserver /usr/local/bin/gameserver
|
||||
EXPOSE 9001
|
||||
CMD ["gameserver"]
|
||||
@@ -0,0 +1,49 @@
|
||||
// Каркас (этап 1 из TZ.md): проверка связки nginx <-ws-> gameserver.
|
||||
// Лобби/комнаты/игровая логика — следующие этапы.
|
||||
|
||||
#include <App.h>
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
struct PerSocketData {};
|
||||
|
||||
int main() {
|
||||
uWS::App()
|
||||
.ws<PerSocketData>("/ws", {
|
||||
.open = [](auto *ws) {
|
||||
std::cout << "client connected\n";
|
||||
},
|
||||
.message = [](auto *ws, std::string_view message, uWS::OpCode) {
|
||||
json response;
|
||||
try {
|
||||
json request = json::parse(message);
|
||||
std::string type = request.value("type", "");
|
||||
|
||||
if (type == "hello") {
|
||||
response = {{"type", "hello.ack"}, {"payload", {{"player_id", "stub"}}}};
|
||||
} else if (type == "lobby.list_rooms") {
|
||||
response = {{"type", "lobby.rooms"}, {"payload", {{"rooms", json::array()}}}};
|
||||
} else {
|
||||
response = {{"type", "error"},
|
||||
{"payload", {{"code", "unknown_type"}, {"message", "unknown message type: " + type}}}};
|
||||
}
|
||||
} catch (const std::exception &e) {
|
||||
response = {{"type", "error"}, {"payload", {{"code", "bad_json"}, {"message", e.what()}}}};
|
||||
}
|
||||
ws->send(response.dump(), uWS::OpCode::TEXT);
|
||||
},
|
||||
.close = [](auto *ws, int, std::string_view) {
|
||||
std::cout << "client disconnected\n";
|
||||
},
|
||||
})
|
||||
.listen(9001, [](auto *token) {
|
||||
if (token) {
|
||||
std::cout << "gameserver listening on :9001\n";
|
||||
} else {
|
||||
std::cerr << "failed to listen on :9001\n";
|
||||
}
|
||||
})
|
||||
.run();
|
||||
}
|
||||
Reference in New Issue
Block a user