#include "SharedState.h" #include "HttpSession.h" #include "ServiceLogic.h" #include "WebsocketSession.h" #include #include #include SharedState::SharedState(boost::asio::io_context &ioContext) : m_ioContext(ioContext), m_router{std::make_shared>()} { m_router->insert("/", [](HttpSession &session, const Request &request, const boost::urls::matches &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("/device/access/valid",[](HttpSession &session, const Request &request, const boost::urls::matches &matches) { LOG(info) << "request body: " << request.body(); auto requestValue = boost::json::parse(request.body()); auto &requestObject = requestValue.as_object(); boost::json::object root; root["code"] = 0; boost::json::object data; data["sid"]=requestObject.at("sid").as_string(); data["vid"]=requestObject.at("sid").as_string(); data["pass"]=1; data["code"]=0; data["voucherPerson"]="amass"; data["voucherMsg"]="测试验票通过"; data["register"]=1; data["effectTime"]="2024-01-15 00:30:35"; data["expireTime"]="2024-01-20 19:30:35"; root["data"] = std::move(data); using namespace boost::beast; http::response res{http::status::ok, request.version()}; res.set(http::field::server, BOOST_BEAST_VERSION_STRING); res.set(http::field::content_type, "application/json"); res.keep_alive(request.keep_alive()); res.body() = boost::json::serialize(root); res.prepare_payload(); session.reply(std::move(res)); }); m_router->insert( "/device/access/report", [](HttpSession &session, const Request &request, const boost::urls::matches &matches) { // Send content message to client and wait to receive next request session.reply(ServiceLogic::make_200(request, "Main page\n", "text/html")); }); } const SharedState::Handler *SharedState::find(boost::urls::segments_encoded_view path, boost::urls::matches_base &matches) const noexcept { return m_router->find(path, matches); } 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); }