В этой статье рассмотрим реализацию бэкенда с применением C++ Boost.Beast библиотеки на примере синхронного сервера. Та же функциональность, что и в прошлой статье — получаем от бэкенда случайное число от 0 до 8 включительно. Оказалось, что поднимать контейнер для Beast ничуть не сложнее, чем для Flask'а. Главное сразу найти хороший подходящий пример. Здесь я взял Dockerfile для своего проекта.
Картинка взята из презентации к этому докладу для привлечения внимания, а также для повышения настроения и мотивации тем, кто не знает C++.
Установка проекта
Клонируем проект на свой компьютер:
git clone https://github.com/nomhoi/tic-tac-toe-part5.git
Запускаем контейнеры:
cd tic-tac-toe-part5
docker-compose up -d
Выполняем сборку веб-приложения:
cd front
npm install
npm run-script build
Открываем броузер по адресу http://localhost.
Docker контейнеры
Сервис flask заменили на сервис beast.
docker-compose.yml:
version: '3.6'
services:
nginx:
image: nginx:alpine
container_name: nginx
volumes:
- ./front/public:/usr/share/nginx/html
- ./default.conf:/etc/nginx/conf.d/default.conf:ro
ports:
- "80:80"
depends_on:
- beast
networks:
- backend
beast:
container_name: beast
build:
context: beast/
dockerfile: Dockerfile
ports:
- "8080:8080"
networks:
- backend
networks:
backend:
name: backend
Фронтенд
Здесь поменяли только настройку в конфигурационном файле nginx'a default.conf.
location /number {
proxy_pass http://beast:8080;
}
Бэкенд
Dockerfile был взят здесь: https://github.com/vinniefalco/CppCon2018.
FROM ubuntu:bionic AS build
# Install tools required for the project
RUN apt-get update && apt-get install gcc -y && apt-get install g++ -y && apt-get install cmake -y && apt-get install wget -y
# Install Boost
RUN cd /home && wget http://downloads.sourceforge.net/project/boost/boost/1.70.0/boost_1_70_0.tar.gz && tar xfz boost_1_70_0.tar.gz && rm boost_1_70_0.tar.gz && cd boost_1_70_0 && ./bootstrap.sh --with-libraries=system && ./b2 install
# Copy the entire project and build it
COPY ./app /cpp/src/project/
WORKDIR /cpp/src/project/
RUN g++ http_server_sync.cpp -o http_server_sync -lpthread
FROM ubuntu:bionic
COPY --from=build /cpp/src/project /app/
ENTRYPOINT ["/app/http_server_sync", "0.0.0.0", "8080", "/app/wwwroot"]
EXPOSE 8080
Как видим, используется технология многоэтапной сборки. На первом этапе выполняется установка нужных пакетов и библиотеки Boost, выполняется сборка сервера http_server_sync. На втором этапе готовый сервер копируется в финальный контейнер и там запускается.
Исходный код синхронного сервера взял здесь. Добавил функцию handle_number_request для обработки запроса по адресу /number.
// Return a random number
template<
class Body, class Allocator,
class Send>
void
handle_number_request(
beast::string_view doc_root,
http::request<Body, http::basic_fields<Allocator>>&& req,
Send&& send)
{
http::response<http::string_body> res;
res.version(11); // HTTP/1.1
res.result(http::status::ok);
res.set(http::field::server, "Beast");
res.body() = std::to_string(rand() % 9);
res.prepare_payload();
return send(std::move(res));
}
В тело ответа пишем случайное число от 0 до 8 включительно.
Заключение
Как видим, Flask нам помог быстро получить общее представление в целом о взаимодействии между фронтендом и бэкендом, мы быстро получили каркас всего приложения. При разработке бэкенда на Beast нам уже было понятно, как устроено взаимодействие и сосредоточились только на поиске подходящего контейнера и написании самого бэкенд-сервера.
В качестве домашнего задания можно попробовать переделать сервис nginx с использованием многоэтапной сборки, чтобы сборка фронтенда выполнялась на первом этапе. Сейчас сервис nginx настроен так, чтобы было удобнее вести разработку фронтенда, без лишней сборки.
Второе домашнее задание: попробовать убрать сервис nginx, и поднять фронтенд в сервисе beast. Мне кажется, должно получиться.
Выкладывайте в комментариях свои решения.
Третье задание: помедитировать на тему масштабируемости — вертикальной и горизонтальной. Как скомбинировать эти два языка, C++ и Python, в одном веб-фреймворке для решения этого вопроса.