#include "Gallery_WebSocket_Controller.h" #include "Gallery_Plot_Session.h" #include "Web_Event_Adapter.h" #include #include #include #include namespace renderive::web { void Gallery_WebSocket_Controller::handleNewConnection( const drogon::HttpRequestPtr&, const drogon::WebSocketConnectionPtr& connection) { connection->setContext(std::make_shared()); connection->setPingMessage("renderive-gallery", std::chrono::seconds(20)); LOG_INFO << "Renderive Gallery WebSocket connected: " << connection->peerAddr().toIpPort(); } void Gallery_WebSocket_Controller::handleNewMessage( const drogon::WebSocketConnectionPtr& connection, std::string&& message, const drogon::WebSocketMessageType& type) { if (type == drogon::WebSocketMessageType::Ping || type == drogon::WebSocketMessageType::Pong || type == drogon::WebSocketMessageType::Close) { return; } if (type != drogon::WebSocketMessageType::Text) { connection->shutdown(drogon::CloseCode::kInvalidMessage, "Renderive Gallery accepts text events only"); return; } if (message.size() > 64 * 1024) { connection->shutdown(drogon::CloseCode::kMessageTooBig, "Renderive Gallery event is too large"); return; } const auto event = Web_Event_Adapter::decode(message); if (!event) { connection->shutdown(drogon::CloseCode::kWrongMessageContent, "Invalid Renderive Gallery event"); return; } const auto session = connection->getContext(); if (!session) { connection->shutdown(drogon::CloseCode::kUnexpectedCondition, "Renderive Gallery session is unavailable"); return; } try { if (auto response = session->handle(*event)) { const auto message_type = response->type == Web_Response_Type::Pixels ? drogon::WebSocketMessageType::Binary : drogon::WebSocketMessageType::Text; connection->send(response->payload.data(), response->payload.size(), message_type); } } catch (...) { static_cast(::renderive::error::capture( "handling Gallery WebSocket request", std::current_exception())); LOG_ERROR << "Renderive Gallery session failed"; connection->shutdown(drogon::CloseCode::kUnexpectedCondition, "Renderive Gallery rendering failed"); } } void Gallery_WebSocket_Controller::handleConnectionClosed( const drogon::WebSocketConnectionPtr& connection) { LOG_INFO << "Renderive Gallery WebSocket closed: " << connection->peerAddr().toIpPort(); connection->clearContext(); } } // namespace renderive::web