scar-chat7/server/server.cpp

119 lines
3.6 KiB
C++
Raw Permalink Normal View History

2025-12-07 12:00:44 -07:00
#include "server.h"
#include <iostream>
#include <fstream>
namespace scar {
Server::Server(const ServerConfig& config)
: ssl_context_(boost::asio::ssl::context::tlsv12_server),
acceptor_(io_context_),
config_(config) {
// Load SSL certificate and key
try {
std::ifstream cert_file(config_.certPath());
std::ifstream key_file(config_.keyPath());
if (!cert_file.is_open()) {
throw std::runtime_error("Cannot open certificate file: " + config_.certPath());
}
if (!key_file.is_open()) {
throw std::runtime_error("Cannot open key file: " + config_.keyPath());
}
ssl_context_.use_certificate_chain_file(config_.certPath());
ssl_context_.use_private_key_file(config_.keyPath(), boost::asio::ssl::context::pem);
} catch (const std::exception& e) {
std::cerr << "SSL configuration error: " << e.what() << std::endl;
throw;
}
// Initialize database
database_ = std::make_shared<Database>(config_.dbPath());
if (!database_->initialize()) {
throw std::runtime_error("Failed to initialize database");
}
// Create authenticator
authenticator_ = std::make_shared<Authenticator>(database_, config_.jwtSecret());
// Setup acceptor
boost::asio::ip::tcp::endpoint endpoint(
boost::asio::ip::make_address(config_.host()),
config_.port()
);
acceptor_.open(endpoint.protocol());
acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
acceptor_.bind(endpoint);
acceptor_.listen();
std::cout << "Server listening on " << config_.host() << ":" << config_.port() << std::endl;
}
void Server::run() {
doAccept();
io_context_.run();
}
void Server::stop() {
io_context_.stop();
}
void Server::doAccept() {
acceptor_.async_accept(
[this](const boost::system::error_code& error, boost::asio::ip::tcp::socket socket) {
if (!error) {
std::cout << "New connection from " << socket.remote_endpoint() << std::endl;
auto ssl_socket = boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(
std::move(socket), ssl_context_
);
auto session = std::make_shared<Session>(
std::move(ssl_socket),
authenticator_,
this
);
session->start();
}
doAccept();
});
}
void Server::addSession(std::shared_ptr<Session> session) {
std::lock_guard<std::mutex> lock(sessions_mutex_);
sessions_.insert(session);
std::cout << "Session added. Total sessions: " << sessions_.size() << std::endl;
}
void Server::removeSession(std::shared_ptr<Session> session) {
std::lock_guard<std::mutex> lock(sessions_mutex_);
sessions_.erase(session);
std::cout << "Session removed. Total sessions: " << sessions_.size() << std::endl;
}
void Server::broadcastMessage(const TextMessage& message) {
std::lock_guard<std::mutex> lock(sessions_mutex_);
for (auto& session : sessions_) {
if (session->isAuthenticated()) {
session->send(message);
}
}
}
void Server::broadcastToOthers(const Message& message, std::shared_ptr<Session> exclude) {
std::lock_guard<std::mutex> lock(sessions_mutex_);
for (auto& session : sessions_) {
if (session != exclude && session->isAuthenticated()) {
session->send(message);
}
}
}
2025-12-07 12:00:44 -07:00
} // namespace scar