108 lines
4.7 KiB
C++
108 lines
4.7 KiB
C++
|
#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<UrlRouter<Handler>>()}, 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<boost::beast::http::string_body>(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<boost::beast::http::string_body>(request, "Main page\n", "text/html"));
|
|||
|
});
|
|||
|
|
|||
|
m_router->insert("/notify", [this](HttpSession &session, const Request &request, const TemplateMatches &matches) {
|
|||
|
auto corp = Amass::Singleton<CorporationContext>::instance();
|
|||
|
corp->notify(request);
|
|||
|
session.reply(
|
|||
|
ServiceLogic::make_200<boost::beast::http::string_body>(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<std::mutex> lock(mutex_);
|
|||
|
sessions_.insert(session);
|
|||
|
}
|
|||
|
|
|||
|
void SharedState::leave(WebSocketSession *session) {
|
|||
|
std::lock_guard<std::mutex> 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::string const>(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<std::weak_ptr<WebSocketSession>> v;
|
|||
|
{
|
|||
|
std::lock_guard<std::mutex> 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);
|
|||
|
}
|