update.
Some checks failed
Deploy / Build (push) Failing after 1m22s

This commit is contained in:
luocai 2025-05-14 17:14:33 +08:00
parent 836c8e0c44
commit 71485e7975
24 changed files with 122 additions and 95 deletions

View File

@ -1,5 +1,6 @@
add_library(Base add_library(Base
DataStructure.h DataStructure.cpp DataStructure.h DataStructure.cpp
HttpSession.h HttpSession.cpp
) )
get_filename_component(PARENT_DIR ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) get_filename_component(PARENT_DIR ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
@ -9,4 +10,6 @@ target_include_directories(Base
target_link_libraries(Base target_link_libraries(Base
PRIVATE OpenSSL::Crypto PRIVATE OpenSSL::Crypto
PUBLIC Kylin::Router
PUBLIC Kylin::Core
) )

View File

@ -2,10 +2,22 @@
#define __MESSAGES_H__ #define __MESSAGES_H__
#include "Core/MessageManager.h" #include "Core/MessageManager.h"
#include "Router/matches.hpp"
#include <boost/beast/http/string_body.hpp>
#include <boost/callable_traits/return_type.hpp> #include <boost/callable_traits/return_type.hpp>
namespace Older {
struct NotifyServerChan { struct NotifyServerChan {
using Signature = void(const boost::beast::http::request<boost::beast::http::string_body> &); 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__ #endif // __MESSAGES_H__

View File

@ -10,37 +10,11 @@ find_package(OpenSSL REQUIRED)
add_subdirectory(3rdparty) add_subdirectory(3rdparty)
add_subdirectory(Base) add_subdirectory(Base)
add_subdirectory(Server)
add_subdirectory(WebRTC)
add_subdirectory(WeChat)
add_subdirectory(UnitTest) 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) include(FetchContent)
FetchContent_Declare(Kylin FetchContent_Declare(Kylin
GIT_REPOSITORY ssh://git@gitea.amass.fun:2022/amass/Kylin.git GIT_REPOSITORY ssh://git@gitea.amass.fun:2022/amass/Kylin.git

View File

@ -1,10 +1,10 @@
#include "Application.h" #include "Application.h"
#include "Base/HttpSession.h"
#include "Base/Messages.h" #include "Base/Messages.h"
#include "Core/IoContext.h" #include "Core/IoContext.h"
#include "Core/MessageManager.h" #include "Core/MessageManager.h"
#include "Core/Singleton.h" #include "Core/Singleton.h"
#include "Database.h" #include "Database.h"
#include "HttpSession.h"
#include "Nng/Asio.h" #include "Nng/Asio.h"
#include "Nng/Message.h" #include "Nng/Message.h"
#include "Nng/Socket.h" #include "Nng/Socket.h"
@ -32,7 +32,7 @@ public:
asyncReply(); 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::shared_ptr<boost::asio::ip::tcp::acceptor> acceptor;
std::unique_ptr<Nng::Socket> reply; std::unique_ptr<Nng::Socket> reply;
}; };
@ -56,7 +56,7 @@ Application::Application() : m_d{new ApplicationPrivate()} {
m_signalServer = std::make_shared<SignalServer>(*this); 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(); auto manager = Singleton<MessageManager>::instance();
if (manager) { if (manager) {
manager->publish<NotifyServerChan>(request); 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")); 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->reply->listen("tcp://127.0.0.1:8985");
m_d->asyncReply(); m_d->asyncReply();
} }

View File

@ -1,9 +1,8 @@
#ifndef __APPLICATION_H__ #ifndef __APPLICATION_H__
#define __APPLICATION_H__ #define __APPLICATION_H__
#include "Router/matches.hpp" #include "Base/Messages.h"
#include <boost/asio/io_context.hpp> #include <boost/asio/io_context.hpp>
#include <boost/beast/http/string_body.hpp>
#include <memory> #include <memory>
namespace Core { namespace Core {
@ -29,8 +28,6 @@ class SignalServer;
class Application : public std::enable_shared_from_this<Application> { class Application : public std::enable_shared_from_this<Application> {
public: public:
using Pointer = std::shared_ptr<Application>; 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();
~Application(); ~Application();
boost::asio::io_context &ioContext(); boost::asio::io_context &ioContext();

21
Server/CMakeLists.txt Normal file
View 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
)

View File

@ -1,7 +1,7 @@
#include "ServiceLogic.h" #include "ServiceLogic.h"
#include "Base/HttpSession.h"
#include "Core/Singleton.h" #include "Core/Singleton.h"
#include "Database.h" #include "Database.h"
#include "HttpSession.h"
#include "SessionStore.h" #include "SessionStore.h"
#include "Settings.h" #include "Settings.h"
#include <sstream> #include <sstream>
@ -57,7 +57,7 @@ void staticFilesDeploy() {
using namespace boost::urls; using namespace boost::urls;
auto application = Singleton<Older::Application>::instance(); auto application = Singleton<Older::Application>::instance();
// clang-format off // 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; using namespace boost::beast;
url_view view(request.target()); url_view view(request.target());
auto target = view.path(); auto target = view.path();
@ -112,7 +112,7 @@ void visitAnalysis() {
// clang-format on // clang-format on
auto application = Singleton<Older::Application>::instance(); 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) { const boost::urls::matches &matches) {
using namespace std::chrono; using namespace std::chrono;
using namespace boost::beast; using namespace boost::beast;
@ -159,7 +159,7 @@ void visitAnalysis() {
session.reply(std::move(s)); 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) { const boost::urls::matches &matches) {
using namespace boost::beast; using namespace boost::beast;
int size = 5; int size = 5;
@ -198,52 +198,51 @@ void visitAnalysis() {
session.reply(std::move(s)); session.reply(std::move(s));
}); });
application->insertUrl( application->insertUrl("/api/v1/latest_viewed_urls", [](Older::HttpSession &session, const Older::HttpRequest &request,
"/api/v1/latest_viewed_urls", const boost::urls::matches &matches) {
[](Older::HttpSession &session, const Older::Application::Request &request, const boost::urls::matches &matches) { using namespace boost::beast;
using namespace boost::beast; using namespace std::chrono;
using namespace std::chrono; int size = 5;
int size = 5; std::error_code error;
std::error_code error; if (!request.body().empty()) {
if (!request.body().empty()) { auto rootJson = boost::json::parse(request.body(), error);
auto rootJson = boost::json::parse(request.body(), error); if (error) {
if (error) { LOG(info) << "<" << request.body() << "> parse json error: " << error.message();
LOG(info) << "<" << request.body() << "> parse json error: " << error.message(); } else {
} else { auto &root = rootJson.as_object();
auto &root = rootJson.as_object(); if (root.contains("size")) {
if (root.contains("size")) { size = root.at("size").as_int64();
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; boost::json::array reply;
int index = 0; int index = 0;
for (auto &stat : stats) { for (auto &stat : stats) {
if (std::find(urlFilter.cbegin(), urlFilter.cend(), stat.url) != urlFilter.cend()) continue; if (std::find(urlFilter.cbegin(), urlFilter.cend(), stat.url) != urlFilter.cend()) continue;
boost::json::object object; boost::json::object object;
object["url"] = stat.url; object["url"] = stat.url;
object["time"] = stat.lastViewTime; object["time"] = stat.lastViewTime;
reply.push_back(std::move(object)); reply.push_back(std::move(object));
index++; index++;
if (index >= size) break; if (index >= size) break;
} }
http::response<boost::beast::http::string_body> s{boost::beast::http::status::ok, request.version()}; 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::server, BOOST_BEAST_VERSION_STRING);
s.set(http::field::content_type, "application/json;charset=UTF-8"); s.set(http::field::content_type, "application/json;charset=UTF-8");
s.keep_alive(request.keep_alive()); s.keep_alive(request.keep_alive());
s.body() = boost::json::serialize(reply); s.body() = boost::json::serialize(reply);
s.prepare_payload(); s.prepare_payload();
session.reply(std::move(s)); session.reply(std::move(s));
}); });
} }
void live2dBackend() { void live2dBackend() {
using namespace Core; using namespace Core;
auto application = Singleton<Older::Application>::instance(); 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) { const boost::urls::matches &matches) {
auto settings = Singleton<Older::Settings>::instance(); auto settings = Singleton<Older::Settings>::instance();
using namespace boost::beast; using namespace boost::beast;
@ -287,7 +286,7 @@ void live2dBackend() {
void userAccount() { void userAccount() {
using namespace Core; using namespace Core;
auto application = Singleton<Older::Application>::instance(); 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) { const boost::urls::matches &matches) {
auto rootJson = boost::json::parse(request.body()); auto rootJson = boost::json::parse(request.body());
auto &root = rootJson.as_object(); auto &root = rootJson.as_object();
@ -325,7 +324,7 @@ void userAccount() {
session.reply(std::move(s)); 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) { const boost::urls::matches &matches) {
auto rootJson = boost::json::parse(request.body()); auto rootJson = boost::json::parse(request.body());
auto &root = rootJson.as_object(); auto &root = rootJson.as_object();
@ -374,7 +373,7 @@ void userAccount() {
session.reply(std::move(s)); 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) { const boost::urls::matches &matches) {
auto cookies = request.find(http::field::cookie); auto cookies = request.find(http::field::cookie);
boost::json::object reply; boost::json::object reply;
@ -426,7 +425,7 @@ void userAccount() {
session.reply(std::move(s)); 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) { const boost::urls::matches &matches) {
http::response<boost::beast::http::string_body> res{boost::beast::http::status::ok, request.version()}; http::response<boost::beast::http::string_body> res{boost::beast::http::status::ok, request.version()};
try { try {

8
WeChat/CMakeLists.txt Normal file
View File

@ -0,0 +1,8 @@
add_library(WeChat
Corporation/Context.h Corporation/Context.cpp
)
target_link_libraries(WeChat
PUBLIC Base
PUBLIC Kylin::Core
)

View File

@ -16,7 +16,7 @@ Context::Context(boost::asio::io_context &ioContext) : m_ioContext(ioContext), m
using namespace Core; using namespace Core;
auto manager = Singleton<MessageManager>::instance(); auto manager = Singleton<MessageManager>::instance();
if (manager) { if (manager) {
manager->subscribe<NotifyServerChan>( manager->subscribe<Older::NotifyServerChan>(
[this](const boost::beast::http::request<boost::beast::http::string_body> &request) { notify(request); }); [this](const boost::beast::http::request<boost::beast::http::string_body> &request) { notify(request); });
} }
} }

8
WebRTC/CMakeLists.txt Normal file
View File

@ -0,0 +1,8 @@
add_library(WebRTC
SignalServer.h SignalServer.cpp
WebSocketSignalSession.h WebSocketSignalSession.cpp
)
target_link_libraries(WebRTC
PUBLIC Base
)

View File

@ -1,23 +1,28 @@
#include "SignalServer.h" #include "SignalServer.h"
#include "../Application.h" #include "Base/HttpSession.h"
#include "../HttpSession.h" #include "Base/Messages.h"
#include "Core/Logger.h" #include "Core/Logger.h"
#include "Core/Singleton.h"
#include "WebSocketSignalSession.h" #include "WebSocketSignalSession.h"
#include <boost/beast/websocket/rfc6455.hpp> #include <boost/beast/websocket/rfc6455.hpp>
namespace Older { namespace Older {
SignalServer::SignalServer(Application &app) { SignalServer::SignalServer(Application &app) {
using namespace boost::urls; using namespace boost::urls;
using namespace Core;
// clang-format off // clang-format off
app.insertUrl("/api/v1/webrtc/signal/{id}", [this](HttpSession &session, const Application::Request &request, const matches &matches) { auto manager = Singleton<MessageManager>::instance();
auto id = matches.at("id"); if (manager) {
if (boost::beast::websocket::is_upgrade(request)) { manager->publish<RegisterUrlHandler>("/api/v1/webrtc/signal/{id}", [this](HttpSession &session, const HttpRequest &request, const matches &matches) {
auto ws = std::make_shared<WebSocketSignalSession>(session.releaseSocket(), *this, id); auto id = matches.at("id");
ws->run(request); if (boost::beast::websocket::is_upgrade(request)) {
} else { auto ws = std::make_shared<WebSocketSignalSession>(session.releaseSocket(), *this, id);
LOG(error) << "webrtc client[" << id << "] not upgrade connection, request: " << std::endl << request; ws->run(request);
} } else {
}); LOG(error) << "webrtc client[" << id << "] not upgrade connection, request: " << std::endl << request;
}
});
}
// clang-format on // clang-format on
} }