88 lines
3.6 KiB
C++
88 lines
3.6 KiB
C++
|
#include "SharedState.h"
|
|||
|
#include "HttpSession.h"
|
|||
|
#include "ServiceLogic.h"
|
|||
|
#include "WebsocketSession.h"
|
|||
|
#include <boost/json/object.hpp>
|
|||
|
#include <boost/json/serialize.hpp>
|
|||
|
#include <boost/json/parse.hpp>
|
|||
|
|
|||
|
SharedState::SharedState(boost::asio::io_context &ioContext)
|
|||
|
: m_ioContext(ioContext), m_router{std::make_shared<boost::urls::router<Handler>>()} {
|
|||
|
|
|||
|
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<boost::beast::http::string_body>(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<http::string_body> 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<boost::beast::http::string_body>(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<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);
|
|||
|
}
|