parent
836c8e0c44
commit
71485e7975
@ -1,5 +1,6 @@
|
||||
add_library(Base
|
||||
DataStructure.h DataStructure.cpp
|
||||
HttpSession.h HttpSession.cpp
|
||||
)
|
||||
|
||||
get_filename_component(PARENT_DIR ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
|
||||
@ -9,4 +10,6 @@ target_include_directories(Base
|
||||
|
||||
target_link_libraries(Base
|
||||
PRIVATE OpenSSL::Crypto
|
||||
PUBLIC Kylin::Router
|
||||
PUBLIC Kylin::Core
|
||||
)
|
@ -2,10 +2,22 @@
|
||||
#define __MESSAGES_H__
|
||||
|
||||
#include "Core/MessageManager.h"
|
||||
#include "Router/matches.hpp"
|
||||
#include <boost/beast/http/string_body.hpp>
|
||||
#include <boost/callable_traits/return_type.hpp>
|
||||
|
||||
namespace Older {
|
||||
struct NotifyServerChan {
|
||||
using Signature = void(const boost::beast::http::request<boost::beast::http::string_body> &);
|
||||
};
|
||||
|
||||
class HttpSession;
|
||||
using HttpRequest = boost::beast::http::request<boost::beast::http::string_body>;
|
||||
using RequestHandler = std::function<void(HttpSession &, const HttpRequest &, const boost::urls::matches &)>;
|
||||
|
||||
struct RegisterUrlHandler {
|
||||
using Signature = void(std::string_view url, RequestHandler &&handler);
|
||||
};
|
||||
} // namespace Older
|
||||
|
||||
#endif // __MESSAGES_H__
|
@ -10,37 +10,11 @@ find_package(OpenSSL REQUIRED)
|
||||
|
||||
add_subdirectory(3rdparty)
|
||||
add_subdirectory(Base)
|
||||
add_subdirectory(Server)
|
||||
add_subdirectory(WebRTC)
|
||||
add_subdirectory(WeChat)
|
||||
add_subdirectory(UnitTest)
|
||||
|
||||
add_executable(Older main.cpp
|
||||
WebRTC/SignalServer.h WebRTC/SignalServer.cpp
|
||||
WebRTC/WebSocketSignalSession.h WebRTC/WebSocketSignalSession.cpp
|
||||
|
||||
WeChat/Corporation/Context.h WeChat/Corporation/Context.cpp
|
||||
|
||||
Application.h Application.cpp
|
||||
Database.h Database.cpp
|
||||
HttpSession.h HttpSession.cpp
|
||||
ResponseUtility.h ResponseUtility.cpp
|
||||
ServiceLogic.h ServiceLogic.inl ServiceLogic.cpp
|
||||
SessionStore.h SessionStore.cpp
|
||||
Settings.h Settings.cpp
|
||||
)
|
||||
|
||||
target_include_directories(Older
|
||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
target_link_libraries(Older
|
||||
PRIVATE Base
|
||||
PRIVATE Kylin::Core
|
||||
PRIVATE Kylin::Http
|
||||
PRIVATE Kylin::Router
|
||||
PRIVATE Kylin::Nng
|
||||
PRIVATE Boost::json
|
||||
PRIVATE sqlite3
|
||||
)
|
||||
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(Kylin
|
||||
GIT_REPOSITORY ssh://git@gitea.amass.fun:2022/amass/Kylin.git
|
||||
|
@ -1,10 +1,10 @@
|
||||
#include "Application.h"
|
||||
#include "Base/HttpSession.h"
|
||||
#include "Base/Messages.h"
|
||||
#include "Core/IoContext.h"
|
||||
#include "Core/MessageManager.h"
|
||||
#include "Core/Singleton.h"
|
||||
#include "Database.h"
|
||||
#include "HttpSession.h"
|
||||
#include "Nng/Asio.h"
|
||||
#include "Nng/Message.h"
|
||||
#include "Nng/Socket.h"
|
||||
@ -32,7 +32,7 @@ public:
|
||||
asyncReply();
|
||||
});
|
||||
}
|
||||
std::shared_ptr<boost::urls::router<Application::RequestHandler>> router;
|
||||
std::shared_ptr<boost::urls::router<RequestHandler>> router;
|
||||
std::shared_ptr<boost::asio::ip::tcp::acceptor> acceptor;
|
||||
std::unique_ptr<Nng::Socket> reply;
|
||||
};
|
||||
@ -56,7 +56,7 @@ Application::Application() : m_d{new ApplicationPrivate()} {
|
||||
|
||||
m_signalServer = std::make_shared<SignalServer>(*this);
|
||||
|
||||
m_d->router->insert("/api/v1/notify", [this](HttpSession &session, const Request &request, const matches &matches) {
|
||||
m_d->router->insert("/api/v1/notify", [this](HttpSession &session, const HttpRequest &request, const matches &matches) {
|
||||
auto manager = Singleton<MessageManager>::instance();
|
||||
if (manager) {
|
||||
manager->publish<NotifyServerChan>(request);
|
||||
@ -64,7 +64,7 @@ Application::Application() : m_d{new ApplicationPrivate()} {
|
||||
session.reply(ServiceLogic::make_200<boost::beast::http::string_body>(request, "notify successed.\n", "text/html"));
|
||||
});
|
||||
|
||||
m_d->reply = std::make_unique<Nng::Socket>(*m_ioContext->ioContext(), Nng::Reply);
|
||||
m_d->reply = std::make_unique<Nng::Socket>(*m_ioContext->ioContext(), Nng::Protocol::Reply);
|
||||
m_d->reply->listen("tcp://127.0.0.1:8985");
|
||||
m_d->asyncReply();
|
||||
}
|
@ -1,9 +1,8 @@
|
||||
#ifndef __APPLICATION_H__
|
||||
#define __APPLICATION_H__
|
||||
|
||||
#include "Router/matches.hpp"
|
||||
#include "Base/Messages.h"
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/beast/http/string_body.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace Core {
|
||||
@ -29,8 +28,6 @@ class SignalServer;
|
||||
class Application : public std::enable_shared_from_this<Application> {
|
||||
public:
|
||||
using Pointer = std::shared_ptr<Application>;
|
||||
using Request = boost::beast::http::request<boost::beast::http::string_body>;
|
||||
using RequestHandler = std::function<void(HttpSession &, const Request &, const boost::urls::matches &)>;
|
||||
Application();
|
||||
~Application();
|
||||
boost::asio::io_context &ioContext();
|
21
Server/CMakeLists.txt
Normal file
21
Server/CMakeLists.txt
Normal file
@ -0,0 +1,21 @@
|
||||
add_executable(Older main.cpp
|
||||
Application.h Application.cpp
|
||||
Database.h Database.cpp
|
||||
ResponseUtility.h ResponseUtility.cpp
|
||||
ServiceLogic.h ServiceLogic.inl ServiceLogic.cpp
|
||||
SessionStore.h SessionStore.cpp
|
||||
Settings.h Settings.cpp
|
||||
)
|
||||
|
||||
target_include_directories(Older
|
||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
target_link_libraries(Older
|
||||
PRIVATE WebRTC
|
||||
PRIVATE WeChat
|
||||
PRIVATE Kylin::Http
|
||||
PRIVATE Kylin::Nng
|
||||
PRIVATE Boost::json
|
||||
PRIVATE sqlite3
|
||||
)
|
@ -1,7 +1,7 @@
|
||||
#include "ServiceLogic.h"
|
||||
#include "Base/HttpSession.h"
|
||||
#include "Core/Singleton.h"
|
||||
#include "Database.h"
|
||||
#include "HttpSession.h"
|
||||
#include "SessionStore.h"
|
||||
#include "Settings.h"
|
||||
#include <sstream>
|
||||
@ -57,7 +57,7 @@ void staticFilesDeploy() {
|
||||
using namespace boost::urls;
|
||||
auto application = Singleton<Older::Application>::instance();
|
||||
// clang-format off
|
||||
application->insertUrl("/{path*}", [](Older::HttpSession &session, const Older::Application::Request &request, const matches &matches) {
|
||||
application->insertUrl("/{path*}", [](Older::HttpSession &session, const Older::HttpRequest &request, const matches &matches) {
|
||||
using namespace boost::beast;
|
||||
url_view view(request.target());
|
||||
auto target = view.path();
|
||||
@ -112,7 +112,7 @@ void visitAnalysis() {
|
||||
// clang-format on
|
||||
|
||||
auto application = Singleton<Older::Application>::instance();
|
||||
application->insertUrl("/api/v1/visit_analysis", [](Older::HttpSession &session, const Older::Application::Request &request,
|
||||
application->insertUrl("/api/v1/visit_analysis", [](Older::HttpSession &session, const Older::HttpRequest &request,
|
||||
const boost::urls::matches &matches) {
|
||||
using namespace std::chrono;
|
||||
using namespace boost::beast;
|
||||
@ -159,7 +159,7 @@ void visitAnalysis() {
|
||||
session.reply(std::move(s));
|
||||
});
|
||||
|
||||
application->insertUrl("/api/v1/most_viewed_urls", [](Older::HttpSession &session, const Older::Application::Request &request,
|
||||
application->insertUrl("/api/v1/most_viewed_urls", [](Older::HttpSession &session, const Older::HttpRequest &request,
|
||||
const boost::urls::matches &matches) {
|
||||
using namespace boost::beast;
|
||||
int size = 5;
|
||||
@ -198,52 +198,51 @@ void visitAnalysis() {
|
||||
session.reply(std::move(s));
|
||||
});
|
||||
|
||||
application->insertUrl(
|
||||
"/api/v1/latest_viewed_urls",
|
||||
[](Older::HttpSession &session, const Older::Application::Request &request, const boost::urls::matches &matches) {
|
||||
using namespace boost::beast;
|
||||
using namespace std::chrono;
|
||||
int size = 5;
|
||||
std::error_code error;
|
||||
if (!request.body().empty()) {
|
||||
auto rootJson = boost::json::parse(request.body(), error);
|
||||
if (error) {
|
||||
LOG(info) << "<" << request.body() << "> parse json error: " << error.message();
|
||||
} else {
|
||||
auto &root = rootJson.as_object();
|
||||
if (root.contains("size")) {
|
||||
size = root.at("size").as_int64();
|
||||
}
|
||||
application->insertUrl("/api/v1/latest_viewed_urls", [](Older::HttpSession &session, const Older::HttpRequest &request,
|
||||
const boost::urls::matches &matches) {
|
||||
using namespace boost::beast;
|
||||
using namespace std::chrono;
|
||||
int size = 5;
|
||||
std::error_code error;
|
||||
if (!request.body().empty()) {
|
||||
auto rootJson = boost::json::parse(request.body(), error);
|
||||
if (error) {
|
||||
LOG(info) << "<" << request.body() << "> parse json error: " << error.message();
|
||||
} else {
|
||||
auto &root = rootJson.as_object();
|
||||
if (root.contains("size")) {
|
||||
size = root.at("size").as_int64();
|
||||
}
|
||||
}
|
||||
auto database = Singleton<Older::Database>::instance();
|
||||
auto stats = database->latestViewedUrls(size + urlFilter.size());
|
||||
}
|
||||
auto database = Singleton<Older::Database>::instance();
|
||||
auto stats = database->latestViewedUrls(size + urlFilter.size());
|
||||
|
||||
boost::json::array reply;
|
||||
int index = 0;
|
||||
for (auto &stat : stats) {
|
||||
if (std::find(urlFilter.cbegin(), urlFilter.cend(), stat.url) != urlFilter.cend()) continue;
|
||||
boost::json::object object;
|
||||
object["url"] = stat.url;
|
||||
object["time"] = stat.lastViewTime;
|
||||
reply.push_back(std::move(object));
|
||||
index++;
|
||||
if (index >= size) break;
|
||||
}
|
||||
http::response<boost::beast::http::string_body> s{boost::beast::http::status::ok, request.version()};
|
||||
s.set(http::field::server, BOOST_BEAST_VERSION_STRING);
|
||||
s.set(http::field::content_type, "application/json;charset=UTF-8");
|
||||
s.keep_alive(request.keep_alive());
|
||||
s.body() = boost::json::serialize(reply);
|
||||
s.prepare_payload();
|
||||
session.reply(std::move(s));
|
||||
});
|
||||
boost::json::array reply;
|
||||
int index = 0;
|
||||
for (auto &stat : stats) {
|
||||
if (std::find(urlFilter.cbegin(), urlFilter.cend(), stat.url) != urlFilter.cend()) continue;
|
||||
boost::json::object object;
|
||||
object["url"] = stat.url;
|
||||
object["time"] = stat.lastViewTime;
|
||||
reply.push_back(std::move(object));
|
||||
index++;
|
||||
if (index >= size) break;
|
||||
}
|
||||
http::response<boost::beast::http::string_body> s{boost::beast::http::status::ok, request.version()};
|
||||
s.set(http::field::server, BOOST_BEAST_VERSION_STRING);
|
||||
s.set(http::field::content_type, "application/json;charset=UTF-8");
|
||||
s.keep_alive(request.keep_alive());
|
||||
s.body() = boost::json::serialize(reply);
|
||||
s.prepare_payload();
|
||||
session.reply(std::move(s));
|
||||
});
|
||||
}
|
||||
|
||||
void live2dBackend() {
|
||||
using namespace Core;
|
||||
auto application = Singleton<Older::Application>::instance();
|
||||
application->insertUrl("/api/v1/live2d/{path*}", [](Older::HttpSession &session, const Older::Application::Request &request,
|
||||
application->insertUrl("/api/v1/live2d/{path*}", [](Older::HttpSession &session, const Older::HttpRequest &request,
|
||||
const boost::urls::matches &matches) {
|
||||
auto settings = Singleton<Older::Settings>::instance();
|
||||
using namespace boost::beast;
|
||||
@ -287,7 +286,7 @@ void live2dBackend() {
|
||||
void userAccount() {
|
||||
using namespace Core;
|
||||
auto application = Singleton<Older::Application>::instance();
|
||||
application->insertUrl("/api/v1/user/register", [](Older::HttpSession &session, const Older::Application::Request &request,
|
||||
application->insertUrl("/api/v1/user/register", [](Older::HttpSession &session, const Older::HttpRequest &request,
|
||||
const boost::urls::matches &matches) {
|
||||
auto rootJson = boost::json::parse(request.body());
|
||||
auto &root = rootJson.as_object();
|
||||
@ -325,7 +324,7 @@ void userAccount() {
|
||||
session.reply(std::move(s));
|
||||
});
|
||||
|
||||
application->insertUrl("/api/v1/user/login", [](Older::HttpSession &session, const Older::Application::Request &request,
|
||||
application->insertUrl("/api/v1/user/login", [](Older::HttpSession &session, const Older::HttpRequest &request,
|
||||
const boost::urls::matches &matches) {
|
||||
auto rootJson = boost::json::parse(request.body());
|
||||
auto &root = rootJson.as_object();
|
||||
@ -374,7 +373,7 @@ void userAccount() {
|
||||
session.reply(std::move(s));
|
||||
});
|
||||
|
||||
application->insertUrl("/api/v1/user/verify", [](Older::HttpSession &session, const Older::Application::Request &request,
|
||||
application->insertUrl("/api/v1/user/verify", [](Older::HttpSession &session, const Older::HttpRequest &request,
|
||||
const boost::urls::matches &matches) {
|
||||
auto cookies = request.find(http::field::cookie);
|
||||
boost::json::object reply;
|
||||
@ -426,7 +425,7 @@ void userAccount() {
|
||||
session.reply(std::move(s));
|
||||
});
|
||||
|
||||
application->insertUrl("/api/v1/user/logout", [](Older::HttpSession &session, const Older::Application::Request &request,
|
||||
application->insertUrl("/api/v1/user/logout", [](Older::HttpSession &session, const Older::HttpRequest &request,
|
||||
const boost::urls::matches &matches) {
|
||||
http::response<boost::beast::http::string_body> res{boost::beast::http::status::ok, request.version()};
|
||||
try {
|
8
WeChat/CMakeLists.txt
Normal file
8
WeChat/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
add_library(WeChat
|
||||
Corporation/Context.h Corporation/Context.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(WeChat
|
||||
PUBLIC Base
|
||||
PUBLIC Kylin::Core
|
||||
)
|
@ -16,7 +16,7 @@ Context::Context(boost::asio::io_context &ioContext) : m_ioContext(ioContext), m
|
||||
using namespace Core;
|
||||
auto manager = Singleton<MessageManager>::instance();
|
||||
if (manager) {
|
||||
manager->subscribe<NotifyServerChan>(
|
||||
manager->subscribe<Older::NotifyServerChan>(
|
||||
[this](const boost::beast::http::request<boost::beast::http::string_body> &request) { notify(request); });
|
||||
}
|
||||
}
|
||||
|
8
WebRTC/CMakeLists.txt
Normal file
8
WebRTC/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
add_library(WebRTC
|
||||
SignalServer.h SignalServer.cpp
|
||||
WebSocketSignalSession.h WebSocketSignalSession.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(WebRTC
|
||||
PUBLIC Base
|
||||
)
|
@ -1,23 +1,28 @@
|
||||
#include "SignalServer.h"
|
||||
#include "../Application.h"
|
||||
#include "../HttpSession.h"
|
||||
#include "Base/HttpSession.h"
|
||||
#include "Base/Messages.h"
|
||||
#include "Core/Logger.h"
|
||||
#include "Core/Singleton.h"
|
||||
#include "WebSocketSignalSession.h"
|
||||
#include <boost/beast/websocket/rfc6455.hpp>
|
||||
|
||||
namespace Older {
|
||||
SignalServer::SignalServer(Application &app) {
|
||||
using namespace boost::urls;
|
||||
using namespace Core;
|
||||
// clang-format off
|
||||
app.insertUrl("/api/v1/webrtc/signal/{id}", [this](HttpSession &session, const Application::Request &request, const matches &matches) {
|
||||
auto id = matches.at("id");
|
||||
if (boost::beast::websocket::is_upgrade(request)) {
|
||||
auto ws = std::make_shared<WebSocketSignalSession>(session.releaseSocket(), *this, id);
|
||||
ws->run(request);
|
||||
} else {
|
||||
LOG(error) << "webrtc client[" << id << "] not upgrade connection, request: " << std::endl << request;
|
||||
}
|
||||
});
|
||||
auto manager = Singleton<MessageManager>::instance();
|
||||
if (manager) {
|
||||
manager->publish<RegisterUrlHandler>("/api/v1/webrtc/signal/{id}", [this](HttpSession &session, const HttpRequest &request, const matches &matches) {
|
||||
auto id = matches.at("id");
|
||||
if (boost::beast::websocket::is_upgrade(request)) {
|
||||
auto ws = std::make_shared<WebSocketSignalSession>(session.releaseSocket(), *this, id);
|
||||
ws->run(request);
|
||||
} else {
|
||||
LOG(error) << "webrtc client[" << id << "] not upgrade connection, request: " << std::endl << request;
|
||||
}
|
||||
});
|
||||
}
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user