#include "SharedState.h" #include "HttpSession.h" #include "ServiceLogic.h" #include "WeChatContext/CorporationContext.h" #include "WebsocketSession.h" SharedState::SharedState(boost::asio::io_context &ioContext, std::string doc_root) : m_ioContext(ioContext), m_router{std::make_shared>()}, m_docRoot(std::move(doc_root)) { m_router->insert("/", [](HttpSession &session, const Request &request, const TemplateMatches &matches) { // Send content message to client and wait to receive next request session.reply(ServiceLogic::make_200(request, "Main page\n", "text/html")); }); m_router->insert("/wechat/{session*}", [this](HttpSession &session, const Request &request, const TemplateMatches &matches) { ServiceLogic::onWechat(shared_from_this(), request, [&session](auto &&response) { session.reply(std::move(response)); }); }); // m_router->all(R"(^/download/.+$)", [this](HttpSession::RequestType request, HttpSession::ContextType context) { // ServiceLogic::onDownload(shared_from_this(), std::move(request), // [&context](auto &&response) { context.send(std::move(response)); }); // }); // m_router->all(R"(^/blog/list$)", [this](HttpSession::RequestType request, HttpSession::ContextType context) { // ServiceLogic::onGetBlogList(shared_from_this(), std::move(request), // [&context](auto &&response) { context.send(response); }); // }); // m_router->all(R"(^/blog/image/.+$)", [this](HttpSession::RequestType request, HttpSession::ContextType context) { // ServiceLogic::onGetBlogImage(shared_from_this(), std::move(request), // [&context](auto &&response) { context.send(std::move(response)); }); // }); // m_router->all(R"(^/blog/content.+$)", [this](HttpSession::RequestType request, HttpSession::ContextType context) // { // ServiceLogic::onGetBlogContent( // shared_from_this(), std::move(request), [&context](auto &&response) { context.send(std::move(response)); // }, // "/blog/content"); // }); m_router->insert( "/trigger-ci.hook", [this](HttpSession &session, const Request &request, const TemplateMatches &matches) { LOG(info) << "webhook: " << request; session.reply(ServiceLogic::make_200(request, "Main page\n", "text/html")); }); m_router->insert("/notify", [this](HttpSession &session, const Request &request, const TemplateMatches &matches) { auto corp = Amass::Singleton::instance(); corp->notify(request); session.reply( ServiceLogic::make_200(request, "notify successed.\n", "text/html")); }); } const SharedState::Handler *SharedState::find(boost::urls::segments_encoded_view path, TemplateMatchStorageBase &matches) const noexcept { return m_router->find(path, matches); } std::string_view SharedState::galleryRoot() const noexcept { return m_galleryRoot; } void SharedState::setFileRoot(const std::string_view &root) { if (m_fileRoot == root) return; m_fileRoot = root; } std::string_view SharedState::notebookRoot() const { return m_notebookRoot; } void SharedState::setNotebookRoot(const std::string_view &root) { if (m_notebookRoot == root) return; m_notebookRoot = root; } void SharedState::join(WebSocketSession *session) { std::lock_guard lock(mutex_); sessions_.insert(session); } void SharedState::leave(WebSocketSession *session) { std::lock_guard lock(mutex_); sessions_.erase(session); } void SharedState::send(std::string message) { // Put the message in a shared pointer so we can re-use it for each client auto const ss = std::make_shared(std::move(message)); // Make a local list of all the weak pointers representing // the sessions, so we can do the actual sending without // holding the mutex: std::vector> v; { std::lock_guard lock(mutex_); v.reserve(sessions_.size()); for (auto p : sessions_) v.emplace_back(p->weak_from_this()); } // For each session in our local list, try to acquire a strong // pointer. If successful, then send the message on that session. for (auto const &wp : v) if (auto sp = wp.lock()) sp->send(ss); }