Github User Fetcher 1.0.0
C Application with Server and GUI
Loading...
Searching...
No Matches
server.cpp File Reference

Implements an HTTP server using Boost.Beast and Boost.Asio to serve GitHub user data. More...

#include "server.hpp"
#include "user.hpp"
#include <boost/asio.hpp>
#include <boost/asio/signal_set.hpp>
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
#include <nlohmann/json.hpp>
#include <iostream>
#include <memory>
#include <string>
#include <thread>
#include <vector>

Go to the source code of this file.

Data Structures

class  HttpSession
 Manages a single HTTP session with a client. More...
 

Typedefs

using tcp = net::ip::tcp
 

Functions

void start_http_server (int port)
 Starts the HTTP server on the specified port.
 

Detailed Description

Implements an HTTP server using Boost.Beast and Boost.Asio to serve GitHub user data.

Definition in file server.cpp.

Typedef Documentation

◆ tcp

using tcp = net::ip::tcp

Definition at line 26 of file server.cpp.

Function Documentation

◆ start_http_server()

void start_http_server ( int port)

Starts the HTTP server on the specified port.

Starts the HTTP server.

Sets up an io_context, signal handlers for graceful shutdown, and an asynchronous TCP acceptor to listen for and handle incoming HTTP connections using HttpSession.

The server runs in a multi-threaded fashion, utilizing all available hardware threads.

Parameters
portThe port number on which the HTTP server should listen.

Lambda for accepting incoming connections recursively.

This lambda captures itself and re-issues accept calls until the server is stopped.

Definition at line 130 of file server.cpp.

130 {
131 try {
132 net::io_context ioc{};
133
134 // Set up signal handling for clean shutdown
135 net::signal_set signals(ioc, SIGINT, SIGTERM);
136 signals.async_wait([&](auto, auto) {
137 std::cout << "\nShutting down server...\n";
138 ioc.stop();
139 });
140
141 tcp::acceptor acceptor{ioc, {tcp::v4(), static_cast<unsigned short>(port)}};
142
143 /**
144 * @brief Lambda for accepting incoming connections recursively.
145 *
146 * This lambda captures itself and re-issues accept calls until the server
147 * is stopped.
148 */
149 auto do_accept = [&](auto &&self) -> void {
150 acceptor.async_accept(
151 [&](beast::error_code error_code, tcp::socket socket) {
152 if (!error_code) {
153 std::make_shared<HttpSession>(std::move(socket))->start();
154 }
155 if (!ioc.stopped()) {
156 self(self); // Accept next connection
157 }
158 });
159 };
160
161 do_accept(do_accept);
162
163 std::cout << "Server started on port " << port
164 << ". Visit http://localhost:" << port << "/USERNAME\n";
165 std::cout << "Press Ctrl+C to quit.\n";
166
167 // Run io_context on multiple threads
168 const auto num_threads = std::max(1U, std::thread::hardware_concurrency());
169 std::vector<std::thread> threads;
170 threads.reserve(num_threads - 1);
171
172 for (unsigned i = 0; i < num_threads - 1; ++i) {
173 threads.emplace_back([&ioc]() { ioc.run(); });
174 }
175
176 ioc.run();
177
178 for (auto &thread : threads) {
179 thread.join();
180 }
181 } catch (const std::exception &e) {
182 std::cerr << "Server error: " << e.what() << "\n";
183 }
184}