优化;删除预编译字节码
This commit is contained in:
@@ -1,80 +0,0 @@
|
||||
|
||||
#include "bytecodemanager.h"
|
||||
#if ENABLE_BYTECODE == 1
|
||||
#include "fastweb.h"
|
||||
#include "utils/luautils.h"
|
||||
#include "util/file.h"
|
||||
#include "util/system.h"
|
||||
#include "core/config.h"
|
||||
bytecode_manager::bytecode_manager()
|
||||
{
|
||||
::ithread::start();
|
||||
}
|
||||
|
||||
bytecode_manager::~bytecode_manager()
|
||||
{
|
||||
::ithread::stop();
|
||||
::ithread::wait();
|
||||
}
|
||||
|
||||
bool bytecode_manager::create(const std::string& name, const std::string& filepath, bool auto_update)
|
||||
{
|
||||
std::shared_ptr<bytecode> bc;
|
||||
if (m_bytescodes.get(name, bc))
|
||||
{
|
||||
m_lastErrorDesc = "The bytecode already exists, name: " + name;
|
||||
return false;
|
||||
}
|
||||
bc = std::make_shared<bytecode>();
|
||||
if (LuaUtils::make_bytecode(filepath, bc->value) == false)
|
||||
{
|
||||
m_lastErrorDesc = "make bytecode failed.";
|
||||
return false;
|
||||
}
|
||||
bc->filepath = filepath;
|
||||
bc->auto_update = true;
|
||||
bc->auto_update = auto_update;
|
||||
bc->pre_modify_msec = ylib::file::last_write_time(filepath);
|
||||
m_bytescodes.add(name, bc);
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::string& bytecode_manager::get(const std::string& name)
|
||||
{
|
||||
static std::string return_empty;
|
||||
std::shared_ptr<bytecode> bc;
|
||||
if (m_bytescodes.get(name, bc) == false)
|
||||
{
|
||||
return return_empty;
|
||||
}
|
||||
return bc->value;
|
||||
}
|
||||
|
||||
std::map<std::string, std::shared_ptr<bytecode>> bytecode_manager::map()
|
||||
{
|
||||
return *m_bytescodes.parent();
|
||||
}
|
||||
|
||||
bool bytecode_manager::run()
|
||||
{
|
||||
m_bytescodes.lock();
|
||||
auto map = m_bytescodes.parent();
|
||||
for_iter(iter, (*map))
|
||||
{
|
||||
if (iter->second->auto_update == false)
|
||||
continue;
|
||||
|
||||
auto last_write_time = ylib::file::last_write_time(iter->second->filepath);
|
||||
if (last_write_time != iter->second->pre_modify_msec)
|
||||
{
|
||||
LuaUtils::make_bytecode(iter->second->filepath, iter->second->value);
|
||||
iter->second->pre_modify_msec = last_write_time;
|
||||
}
|
||||
}
|
||||
m_bytescodes.unlock();
|
||||
|
||||
system::sleep_msec(sConfig->scripts.auto_update_sec);
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
@@ -1,45 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "core/define.h"
|
||||
#if ENABLE_BYTECODE == 1
|
||||
#include "sol/sol.hpp"
|
||||
|
||||
#include "base/error.h"
|
||||
#include "base/singleton.hpp"
|
||||
#include "util/thread.h"
|
||||
#include "util/queue.hpp"
|
||||
#include "util/map.hpp"
|
||||
|
||||
#include "core/structs.h"
|
||||
|
||||
/// <summary>
|
||||
/// 字节码管理器
|
||||
/// </summary>
|
||||
class bytecode_manager:public ylib::error_base,private ylib::ithread {
|
||||
public:
|
||||
bytecode_manager();
|
||||
~bytecode_manager();
|
||||
/// <summary>
|
||||
/// 创建字节码
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="filepath"></param>
|
||||
/// <param name="auto_update"></param>
|
||||
/// <returns></returns>
|
||||
bool create(const std::string& name,const std::string& filepath,bool auto_update);
|
||||
/// <summary>
|
||||
/// 取字节码
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
const std::string& get(const std::string& name);
|
||||
|
||||
std::map<std::string, std::shared_ptr<bytecode>> map();
|
||||
private:
|
||||
// ServiceLUA文件
|
||||
ylib::map<std::string, std::shared_ptr<bytecode>> m_bytescodes;
|
||||
|
||||
// 通过 ithread 继承
|
||||
bool run() override;
|
||||
};
|
||||
#endif
|
||||
@@ -35,14 +35,33 @@ bool config::open(const std::string& ini_filepath)
|
||||
cache();
|
||||
return true;
|
||||
}
|
||||
bool config::have_https()
|
||||
std::vector<std::string> config::lua_app_files()
|
||||
{
|
||||
for_iter(iter, domain)
|
||||
std::vector<std::string> results;
|
||||
auto luas = ylib::file::traverse(sConfig->scripts.app_dir, "(.*\\.lua)");
|
||||
for_iter(iter, luas)
|
||||
{
|
||||
if (iter->second.https)
|
||||
return true;
|
||||
if (iter->second == IS_DIRECTORY)
|
||||
continue;
|
||||
std::string path = strutils::replace(iter->first, '\\', '/');
|
||||
|
||||
results.push_back(path);
|
||||
}
|
||||
return false;
|
||||
return results;
|
||||
}
|
||||
std::vector<std::string> config::lua_lib_files()
|
||||
{
|
||||
std::vector<std::string> results;
|
||||
auto luas = ylib::file::traverse(sConfig->scripts.lib_dir, "(.*\\.lua)");
|
||||
for_iter(iter, luas)
|
||||
{
|
||||
if (iter->second == IS_DIRECTORY)
|
||||
continue;
|
||||
std::string path = strutils::replace(iter->first, '\\', '/');
|
||||
|
||||
results.push_back(path);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
std::vector<std::string> config::extractVariableNames(const std::string& text)
|
||||
{
|
||||
|
||||
@@ -37,11 +37,8 @@ public:
|
||||
config() = default;
|
||||
bool open(const std::string& ini_filepath);
|
||||
|
||||
/// <summary>
|
||||
/// 是否含有https
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
bool have_https();
|
||||
std::vector<std::string> lua_app_files();
|
||||
std::vector<std::string> lua_lib_files();
|
||||
private:
|
||||
// INI配置文件
|
||||
ylib::ini m_ini;
|
||||
|
||||
@@ -30,4 +30,3 @@
|
||||
#define VarType sol::object
|
||||
|
||||
|
||||
#define ENABLE_BYTECODE 0
|
||||
@@ -8,7 +8,7 @@ extern "C" {
|
||||
#ifdef _WIN32
|
||||
DLL_EXPORT
|
||||
#endif
|
||||
int fastweb(const char* config_filepath)
|
||||
int fastweb_start(const char* config_filepath)
|
||||
{
|
||||
std::cout << "=========== [fastweb engine] ============" << std::endl;
|
||||
if (sConfig->open(config_filepath) == false)
|
||||
@@ -25,4 +25,12 @@ extern "C" {
|
||||
LOG_SUCC("success");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#ifdef _WIN32
|
||||
DLL_EXPORT
|
||||
#endif
|
||||
void fastweb_close()
|
||||
{
|
||||
fastweb::getInstance()->stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#define DLL_EXPORT __attribute__((visibility("default")))
|
||||
#endif
|
||||
extern "C" {
|
||||
DLL_EXPORT int fastweb(const char* config_filepath);
|
||||
DLL_EXPORT int fastweb_start(const char* config_filepath);
|
||||
DLL_EXPORT void fastweb_close();
|
||||
}
|
||||
|
||||
@@ -8,8 +8,10 @@
|
||||
#include "module/http/response.h"
|
||||
#include "module/globalfuns.h"
|
||||
#include "core/config.h"
|
||||
#include "core/global.h"
|
||||
#include "core/statemanager.h"
|
||||
|
||||
#include "core/subscribemanager.h"
|
||||
#include "core/interceptormanager.h"
|
||||
bool fastweb::start()
|
||||
{
|
||||
|
||||
@@ -59,210 +61,34 @@ bool fastweb::start()
|
||||
// 初始化脚本
|
||||
if (initialization_script() == false)
|
||||
return false;
|
||||
#if ENABLE_BYTECODE == 1
|
||||
// 加载服务脚本
|
||||
{
|
||||
auto luas = ylib::file::traverse(sConfig->scripts.app_dir, "(.*\\.lua)");
|
||||
for_iter(iter, luas) {
|
||||
if (iter->second == IS_DIRECTORY)
|
||||
continue;
|
||||
std::string path = strutils::replace(iter->first, '\\', '/');
|
||||
if (service_bytecode.create(path, sConfig->scripts.app_dir + "/" + path, true) == false)
|
||||
{
|
||||
m_lastErrorDesc = service_bytecode.last_error();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 加载拦截器脚本
|
||||
for_iter(iter, sConfig->website.interceptor_scripts) {
|
||||
if (interceptor_bytecode.create(iter->regex_express, iter->filepath, true) == false)
|
||||
{
|
||||
m_lastErrorDesc = interceptor_bytecode.last_error();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 加入LUA服务映射
|
||||
{
|
||||
auto map = service_bytecode.map();
|
||||
for_iter(iter, map)
|
||||
{
|
||||
auto state = sStateMgr->get_state();
|
||||
std::string route_pattern;
|
||||
network::http::method method = network::http::ALL;
|
||||
try
|
||||
{
|
||||
auto result = state->script_file(iter->second->filepath);
|
||||
if (result.valid()) {
|
||||
auto router = (*state)["route"];
|
||||
auto type = router.get_type();
|
||||
if (router.is<sol::table>())
|
||||
{
|
||||
sol::optional<std::string> route_pattern_param = router[1];
|
||||
sol::optional<int> method_param = router[2];
|
||||
if (route_pattern_param && route_pattern_param->empty() == false)
|
||||
route_pattern = *route_pattern_param;
|
||||
if (method_param)
|
||||
method = (network::http::method)*method_param;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
LOG_ERROR(e.what());
|
||||
}
|
||||
if (route_pattern.empty())
|
||||
route_pattern = sConfig->scripts.app_mapping_dir + iter->first;
|
||||
|
||||
// OutPutLog
|
||||
{
|
||||
std::string log;
|
||||
log = "[subscribe] lua: " + iter->first + "\t pattern: " + route_pattern + "\t method: ";
|
||||
switch (method)
|
||||
{
|
||||
case ylib::network::http::GET:
|
||||
log.append("GET");
|
||||
break;
|
||||
case ylib::network::http::POST:
|
||||
log.append("POST");
|
||||
break;
|
||||
case ylib::network::http::PUT:
|
||||
log.append("PUT");
|
||||
break;
|
||||
case ylib::network::http::DEL:
|
||||
log.append("DEL");
|
||||
break;
|
||||
case ylib::network::http::HEAD:
|
||||
log.append("HEAD");
|
||||
break;
|
||||
case ylib::network::http::ALL:
|
||||
log.append("ALL");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
LOG_INFO(log);
|
||||
}
|
||||
router->subscribe(route_pattern, method, &fastweb::subscribe_service,new std::string(iter->first));
|
||||
}
|
||||
|
||||
}
|
||||
#else
|
||||
// 加入LUA服务映射
|
||||
{
|
||||
auto luas = ylib::file::traverse(sConfig->scripts.app_dir, "(.*\\.lua)");
|
||||
for_iter(iter, luas)
|
||||
{
|
||||
if (iter->second == IS_DIRECTORY)
|
||||
continue;
|
||||
std::string path = strutils::replace(iter->first, '\\', '/');
|
||||
auto state = sStateMgr->get_state();
|
||||
std::string route_pattern;
|
||||
network::http::method method = network::http::ALL;
|
||||
try
|
||||
{
|
||||
auto result = state->script_file(sConfig->scripts.app_dir+"/"+ path);
|
||||
if (result.valid()) {
|
||||
auto router = (*state)["route"];
|
||||
auto type = router.get_type();
|
||||
if (router.is<sol::table>())
|
||||
{
|
||||
sol::optional<std::string> route_pattern_param = router[1];
|
||||
sol::optional<int> method_param = router[2];
|
||||
if (route_pattern_param && route_pattern_param->empty() == false)
|
||||
route_pattern = *route_pattern_param;
|
||||
if (method_param)
|
||||
method = (network::http::method)*method_param;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
LOG_ERROR(e.what());
|
||||
}
|
||||
if (route_pattern.empty())
|
||||
route_pattern = sConfig->scripts.app_mapping_dir + path;
|
||||
|
||||
// OutPutLog
|
||||
{
|
||||
std::string log;
|
||||
log = "[subscribe] lua: " +path + "\t pattern: " + route_pattern + "\t method: ";
|
||||
switch (method)
|
||||
{
|
||||
case ylib::network::http::GET:
|
||||
log.append("GET");
|
||||
break;
|
||||
case ylib::network::http::POST:
|
||||
log.append("POST");
|
||||
break;
|
||||
case ylib::network::http::PUT:
|
||||
log.append("PUT");
|
||||
break;
|
||||
case ylib::network::http::DEL:
|
||||
log.append("DEL");
|
||||
break;
|
||||
case ylib::network::http::HEAD:
|
||||
log.append("HEAD");
|
||||
break;
|
||||
case ylib::network::http::ALL:
|
||||
log.append("ALL");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
LOG_INFO(log);
|
||||
}
|
||||
router->subscribe(route_pattern, method, &fastweb::subscribe_service, new std::string(sConfig->scripts.app_dir+"/" +path));
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
// 加入拦截器
|
||||
for (size_t i = 0; i < sConfig->website.interceptor_scripts.size(); i++)
|
||||
{
|
||||
#if ENABLE_BYTECODE == 0
|
||||
interceptor.emplace(sConfig->website.interceptor_scripts[i].regex_express,sConfig->website.interceptor_scripts[i].filepath);
|
||||
#endif
|
||||
router->interceptor()->add(sConfig->website.interceptor_scripts[i].regex_express, &fastweb::subscribe_interceptor);
|
||||
}
|
||||
// 加载订阅
|
||||
m_subscribe.load(router);
|
||||
// 加载拦截器
|
||||
m_interceptor.load(router);
|
||||
|
||||
|
||||
|
||||
|
||||
router->other([&](network::http::request* request, network::http::response* response) {
|
||||
if (request->filepath() == "/")
|
||||
{
|
||||
bool find = false;
|
||||
for (size_t i = 0; i < sConfig->website.default_index.size(); i++)
|
||||
{
|
||||
std::string filepath = sConfig->website.static_dir + request->filepath() + sConfig->website.default_index[i];
|
||||
if (ylib::file::exist(filepath))
|
||||
{
|
||||
find = true;
|
||||
response->send_file(filepath);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (find == false)
|
||||
send_404(response);
|
||||
return;
|
||||
}
|
||||
|
||||
send_file(response,request->filepath());
|
||||
});
|
||||
|
||||
|
||||
return m_center->start();
|
||||
}
|
||||
|
||||
void fastweb::stop()
|
||||
{
|
||||
m_subscribe.clear();
|
||||
m_interceptor.clear();
|
||||
if (m_center != nullptr)
|
||||
{
|
||||
m_center->close();
|
||||
delete m_center;
|
||||
}
|
||||
m_center = nullptr;
|
||||
|
||||
global::getInstance()->clear();
|
||||
if (m_state_init != nullptr)
|
||||
delete m_state_init;
|
||||
m_state_init = nullptr;
|
||||
sStateMgr->close();
|
||||
}
|
||||
|
||||
bool fastweb::initialization_script()
|
||||
@@ -275,11 +101,11 @@ bool fastweb::initialization_script()
|
||||
m_lastErrorDesc = "Initialization script not found, filepath: " + script_filepath;
|
||||
return false;
|
||||
}
|
||||
auto state = sStateMgr->get_state();
|
||||
auto state = sStateMgr->get();
|
||||
try
|
||||
{
|
||||
state->set_function("global_regist", module::global_regist);
|
||||
auto result = state->script_file(script_filepath);
|
||||
state->state->set_function("global_regist", module::global_regist);
|
||||
auto result = state->state->script_file(script_filepath);
|
||||
if (!result.valid()) {
|
||||
sol::error err = result;
|
||||
throw ylib::exception(err.what());
|
||||
@@ -295,134 +121,6 @@ bool fastweb::initialization_script()
|
||||
}
|
||||
// 不可DELETE,否则注册的全局变量会被自动销毁
|
||||
//delete state;
|
||||
m_state_init = state;
|
||||
return m_lastErrorDesc == "";
|
||||
}
|
||||
|
||||
void fastweb::subscribe_service(network::http::request* request, network::http::response* response,void *extra)
|
||||
{
|
||||
std::string lua_name = *(std::string*)extra;
|
||||
|
||||
// 文件原路径(非绝对路径)
|
||||
//std::string lua_name = strutils::right(request->filepath(), request->filepath().length() - sConfig->scripts.app_mapping_dir.length());
|
||||
|
||||
|
||||
auto lua = sStateMgr->get_state();
|
||||
std::string exception_string;
|
||||
try
|
||||
{
|
||||
#if ENABLE_BYTECODE == 1
|
||||
auto bytecode = sFastWeb->service_bytecode.get(lua_name);
|
||||
if (bytecode.empty())
|
||||
throw ylib::exception("Serious error: Bytecode not found, possibly due to pre compilation modification error. Please recheck the script file, "+lua_name);
|
||||
auto lbResult = lua->load_buffer(bytecode.data(), bytecode.length(), "bytecode");
|
||||
#else
|
||||
auto lbResult = lua->load_file(lua_name);
|
||||
#endif
|
||||
if (lbResult.valid() == false)
|
||||
{
|
||||
sol::error err = lbResult;
|
||||
throw ylib::exception("Failed to load bytecode, " + std::string(err.what()));
|
||||
}
|
||||
module::request m_request(request);
|
||||
module::response m_response(response);
|
||||
|
||||
lbResult();
|
||||
|
||||
(*lua)["response"] = &m_response;
|
||||
(*lua)["request"] = &m_request;
|
||||
|
||||
auto result = (*lua)["access"]();
|
||||
if (!result.valid()) {
|
||||
sol::error err = result;
|
||||
throw ylib::exception(err.what());
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
exception_string = e.what();
|
||||
if(sConfig->website.debug)
|
||||
LOG_ERROR("[subscribe_service]["+ request->filepath() + "]: "+e.what());
|
||||
}
|
||||
lua->collect_garbage();
|
||||
sStateMgr->push_state(lua);
|
||||
|
||||
if (exception_string.empty() == false)
|
||||
throw ylib::exception(exception_string);
|
||||
}
|
||||
|
||||
bool fastweb::subscribe_interceptor(network::http::reqpack* reqpack, const std::string& express_string)
|
||||
{
|
||||
|
||||
bool ok_continue = false;
|
||||
auto lua = sStateMgr->get_state();
|
||||
std::string exception_string;
|
||||
try
|
||||
{
|
||||
#if ENABLE_BYTECODE == 1
|
||||
const std::string& bytecode = sFastWeb->interceptor_bytecode.get(express_string);
|
||||
if (bytecode.empty())
|
||||
throw ylib::exception("[interceptor] Serious error: Bytecode not found, possibly due to pre compilation modification error. Please recheck the script file, " + express_string);
|
||||
|
||||
auto lbResult = lua->load_buffer(bytecode.data(), bytecode.length(), "bytecode");
|
||||
#else
|
||||
auto lbResult = lua->load_file(sFastWeb->interceptor[express_string]);
|
||||
#endif
|
||||
if (lbResult.valid() == false)
|
||||
{
|
||||
sol::error err = lbResult;
|
||||
throw ylib::exception("[interceptor] Failed to load bytecode, " + std::string(err.what()));
|
||||
}
|
||||
module::request m_request(reqpack->request());
|
||||
module::response m_response(reqpack->response());
|
||||
|
||||
lbResult();
|
||||
|
||||
(*lua)["response"] = m_response;
|
||||
(*lua)["request"] = m_request;
|
||||
|
||||
auto result = (*lua)["access"]();
|
||||
if (!result.valid()) {
|
||||
sol::error err = result;
|
||||
throw ylib::exception(err.what());
|
||||
}
|
||||
ok_continue = result.get<bool>();
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
exception_string = e.what();
|
||||
if (sConfig->website.debug)
|
||||
LOG_ERROR("[subscribe_interceptor][" + reqpack->request()->filepath() + "]: " + e.what());
|
||||
}
|
||||
sStateMgr->push_state(lua);
|
||||
|
||||
if (exception_string.empty() == false)
|
||||
throw ylib::exception(exception_string);
|
||||
|
||||
return ok_continue;
|
||||
}
|
||||
|
||||
void fastweb::send_file(network::http::response* response, std::string filepath)
|
||||
{
|
||||
filepath = sConfig->website.static_dir + filepath;
|
||||
if (ylib::file::exist(filepath))
|
||||
{
|
||||
response->send_file(filepath);
|
||||
}
|
||||
else
|
||||
{
|
||||
send_404(response);
|
||||
}
|
||||
}
|
||||
|
||||
void fastweb::send_404(network::http::response* response)
|
||||
{
|
||||
std::string default_404 = sConfig->website.static_dir + "\\" + sConfig->website.default_404;
|
||||
if (sConfig->website.default_404 == "" || ylib::file::exist(default_404) == false)
|
||||
{
|
||||
response->send((std::string)"404 Not Found",404,"Not Found");
|
||||
}
|
||||
else
|
||||
{
|
||||
response->send_file(default_404,-1, 404, "Not Found");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,51 +3,26 @@
|
||||
#include "base/error.h"
|
||||
#include "base/singleton.hpp"
|
||||
#include "net/http_center.h"
|
||||
#include "net/http_response.h"
|
||||
#include "net/http_request.h"
|
||||
#include "core/bytecodemanager.h"
|
||||
#include "core/subscribemanager.h"
|
||||
#include "core/interceptormanager.h"
|
||||
class fastweb:public ylib::error_base,public ylib::singleton<fastweb> {
|
||||
public:
|
||||
fastweb() = default;
|
||||
bool start();
|
||||
void stop();
|
||||
|
||||
/// <summary>
|
||||
/// 发送文件
|
||||
/// </summary>
|
||||
/// <param name="response"></param>
|
||||
/// <param name="filepath"></param>
|
||||
void send_file(network::http::response* response, std::string filepath);
|
||||
/// <summary>
|
||||
/// 发送404
|
||||
/// </summary>
|
||||
/// <param name="response"></param>
|
||||
void send_404(network::http::response* response);
|
||||
private:
|
||||
/// <summary>
|
||||
/// 初始化执行脚本
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
bool initialization_script();
|
||||
/// <summary>
|
||||
/// 服务回调
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="response"></param>
|
||||
static void subscribe_service(network::http::request* request, network::http::response* response, void* extra);
|
||||
/// <summary>
|
||||
/// 拦截器回调
|
||||
/// </summary>
|
||||
static bool subscribe_interceptor(network::http::reqpack* reqpack,const std::string& express_string);
|
||||
private:
|
||||
// 初始化脚本虚拟机
|
||||
luastate* m_state_init = nullptr;
|
||||
// 网站服务核心
|
||||
network::http::center *m_center = nullptr;
|
||||
public:
|
||||
#if ENABLE_BYTECODE == 1
|
||||
// 服务字节码
|
||||
bytecode_manager service_bytecode;
|
||||
// 拦截器字节码
|
||||
bytecode_manager interceptor_bytecode;
|
||||
#else
|
||||
std::map<std::string, std::string> interceptor;
|
||||
#endif
|
||||
// 订阅管理器
|
||||
subscribe_manager m_subscribe;
|
||||
// 拦截器管理器
|
||||
interceptor_manager m_interceptor;
|
||||
};
|
||||
@@ -43,3 +43,18 @@ void global::set(const std::string& name, VarType value)
|
||||
{
|
||||
m_values.set(name, value, true);
|
||||
}
|
||||
|
||||
void global::clear()
|
||||
{
|
||||
m_values.clear();
|
||||
m_value_ptr.clear();
|
||||
|
||||
//m_value_ptr.lock();
|
||||
//for_iter(iter, (*m_value_ptr.parent()))
|
||||
//{
|
||||
// auto im = static_cast<module::imodule*>(iter->second);
|
||||
// im->delete_global();
|
||||
//}
|
||||
//m_value_ptr.unlock();
|
||||
//m_value_ptr.clear();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ public:
|
||||
VarType get(const std::string& name, sol::this_state s);
|
||||
void set(const std::string& name,VarType value);
|
||||
|
||||
void clear();
|
||||
private:
|
||||
ylib::map<std::string, void*> m_value_ptr;
|
||||
|
||||
|
||||
75
src/core/interceptormanager.cpp
Normal file
75
src/core/interceptormanager.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#include "core/interceptormanager.h"
|
||||
#include "core/config.h"
|
||||
#include "core/statemanager.h"
|
||||
#include "module/http/request.h"
|
||||
#include "module/http/response.h"
|
||||
#include "net/http_interceptor.h"
|
||||
std::map<std::string, std::string> interceptor_manager::interceptor = std::map<std::string,std::string>();
|
||||
interceptor_manager::interceptor_manager()
|
||||
{
|
||||
}
|
||||
interceptor_manager::~interceptor_manager()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
void interceptor_manager::load(network::http::router* router)
|
||||
{
|
||||
clear();
|
||||
m_router = router;
|
||||
for (size_t i = 0; i < sConfig->website.interceptor_scripts.size(); i++)
|
||||
{
|
||||
interceptor_manager::interceptor.emplace(sConfig->website.interceptor_scripts[i].regex_express, sConfig->website.interceptor_scripts[i].filepath);
|
||||
router->interceptor()->add(sConfig->website.interceptor_scripts[i].regex_express, &interceptor_manager::callback);
|
||||
}
|
||||
}
|
||||
|
||||
void interceptor_manager::clear()
|
||||
{
|
||||
if(m_router != nullptr)
|
||||
m_router->interceptor()->clear();
|
||||
interceptor_manager::interceptor.clear();
|
||||
m_router = nullptr;
|
||||
}
|
||||
|
||||
bool interceptor_manager::callback(network::http::reqpack* reqpack, const std::string& express_string)
|
||||
{
|
||||
bool ok_continue = false;
|
||||
auto lua = sStateMgr->get();
|
||||
std::string exception_string;
|
||||
try
|
||||
{
|
||||
auto lbResult = lua->state->load_file(interceptor_manager::interceptor[express_string]);
|
||||
if (lbResult.valid() == false)
|
||||
{
|
||||
sol::error err = lbResult;
|
||||
throw ylib::exception("[interceptor] Failed to load bytecode, " + std::string(err.what()));
|
||||
}
|
||||
module::request m_request(reqpack->request());
|
||||
module::response m_response(reqpack->response());
|
||||
|
||||
lbResult();
|
||||
|
||||
(*lua->state)["response"] = m_response;
|
||||
(*lua->state)["request"] = m_request;
|
||||
|
||||
auto result = (*lua->state)["access"]();
|
||||
if (!result.valid()) {
|
||||
sol::error err = result;
|
||||
throw ylib::exception(err.what());
|
||||
}
|
||||
ok_continue = result.get<bool>();
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
exception_string = e.what();
|
||||
if (sConfig->website.debug)
|
||||
LOG_ERROR("[subscribe_interceptor][" + reqpack->request()->filepath() + "]: " + e.what());
|
||||
}
|
||||
lua->state->collect_garbage();
|
||||
sStateMgr->push(lua);
|
||||
|
||||
if (exception_string.empty() == false)
|
||||
throw ylib::exception(exception_string);
|
||||
|
||||
return ok_continue;
|
||||
}
|
||||
31
src/core/interceptormanager.h
Normal file
31
src/core/interceptormanager.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "base/singleton.hpp"
|
||||
#include "core/structs.h"
|
||||
#include "net/http_reqpack.h"
|
||||
#include "net/http_request.h"
|
||||
#include "net/http_response.h"
|
||||
#include "net/http_router.h"
|
||||
/// <summary>
|
||||
/// 拦截器管理器
|
||||
/// </summary>
|
||||
class interceptor_manager{
|
||||
public:
|
||||
interceptor_manager();
|
||||
~interceptor_manager();
|
||||
|
||||
void load(network::http::router* router);
|
||||
void clear();
|
||||
private:
|
||||
/// <summary>
|
||||
/// 服务回调
|
||||
/// </summary>
|
||||
/// <param name="reqpack"></param>
|
||||
/// <param name="express_string"></param>
|
||||
static bool callback(network::http::reqpack* reqpack, const std::string& express_string);
|
||||
private:
|
||||
network::http::router* m_router = nullptr;
|
||||
public:
|
||||
static std::map<std::string, std::string> interceptor;
|
||||
};
|
||||
45
src/core/lualibdetecter.cpp
Normal file
45
src/core/lualibdetecter.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#include "lualibdetecter.h"
|
||||
#include "core/config.h"
|
||||
#include "util/file.h"
|
||||
lualib_detecter::lualib_detecter()
|
||||
{
|
||||
}
|
||||
|
||||
lualib_detecter::~lualib_detecter()
|
||||
{
|
||||
}
|
||||
|
||||
bool lualib_detecter::changed()
|
||||
{
|
||||
auto lib_files = sConfig->lua_lib_files();
|
||||
bool changed = false;
|
||||
if (lib_files.size() == m_files.size())
|
||||
{
|
||||
for (size_t i = 0; i < lib_files.size(); i++)
|
||||
{
|
||||
auto iter = m_files.find(lib_files[i]);
|
||||
if (iter == m_files.end())
|
||||
{
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
if (ylib::file::last_write_time(sConfig->scripts.lib_dir+"/"+ lib_files[i]) != iter->second)
|
||||
{
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
changed = true;
|
||||
|
||||
|
||||
if (changed == false)
|
||||
return false;
|
||||
|
||||
m_files.clear();
|
||||
for (size_t i = 0; i < lib_files.size(); i++)
|
||||
m_files.emplace(lib_files[i], ylib::file::last_write_time(sConfig->scripts.lib_dir + "/" + lib_files[i]));
|
||||
|
||||
return true;
|
||||
}
|
||||
28
src/core/lualibdetecter.h
Normal file
28
src/core/lualibdetecter.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "sol/sol.hpp"
|
||||
|
||||
#include "base/error.h"
|
||||
#include "base/singleton.hpp"
|
||||
#include "util/thread.h"
|
||||
#include "util/queue.hpp"
|
||||
#include "util/map.hpp"
|
||||
|
||||
#include "core/structs.h"
|
||||
|
||||
/// <summary>
|
||||
/// LUALIB库变动检测
|
||||
/// </summary>
|
||||
class lualib_detecter {
|
||||
public:
|
||||
lualib_detecter();
|
||||
~lualib_detecter();
|
||||
/// <summary>
|
||||
/// 是否变化
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
bool changed();
|
||||
private:
|
||||
std::map<std::string, timestamp> m_files;
|
||||
};
|
||||
@@ -26,28 +26,24 @@
|
||||
#define LOOP_STATE_USE 1
|
||||
bool state_manager::start()
|
||||
{
|
||||
#if LOOP_STATE_USE == 0
|
||||
close();
|
||||
::ithread::start();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
void state_manager::close()
|
||||
{
|
||||
#if LOOP_STATE_USE == 0
|
||||
::ithread::stop();
|
||||
::ithread::wait();
|
||||
#endif
|
||||
sol::state* state = nullptr;
|
||||
luastate* state = nullptr;
|
||||
while (m_states.pop(state))
|
||||
delete state;
|
||||
|
||||
}
|
||||
sol::state* state_manager::create_state()
|
||||
luastate* state_manager::create()
|
||||
{
|
||||
sol::state* lua = new sol::state();
|
||||
lua->open_libraries(
|
||||
luastate* lua = new luastate();
|
||||
lua->flag = m_flag;
|
||||
lua->state->open_libraries(
|
||||
sol::lib::base,
|
||||
sol::lib::package,
|
||||
sol::lib::math,
|
||||
@@ -64,82 +60,62 @@ sol::state* state_manager::create_state()
|
||||
);
|
||||
{
|
||||
// 获取当前的package.path,添加新的搜索路径
|
||||
std::string current_path = (*lua)["package"]["path"]; // 获取当前的路径
|
||||
std::string current_path = (*lua->state)["package"]["path"]; // 获取当前的路径
|
||||
current_path += ";"+ sConfig->scripts.lib_dir +"/?.lua"; // 添加新的路径
|
||||
(*lua)["package"]["path"] = current_path; // 设置修改后的路径
|
||||
(*lua->state)["package"]["path"] = current_path; // 设置修改后的路径
|
||||
}
|
||||
module::request::regist(*lua);
|
||||
module::response::regist(*lua);
|
||||
module::session::regist(*lua);
|
||||
module::httpclient::regist(*lua);
|
||||
module::mysql_regist(*lua);
|
||||
module::request::regist(*lua->state);
|
||||
module::response::regist(*lua->state);
|
||||
module::session::regist(*lua->state);
|
||||
module::httpclient::regist(*lua->state);
|
||||
module::mysql_regist(*lua->state);
|
||||
#ifdef _WIN32
|
||||
module::mssql::regist(*lua);
|
||||
module::mssql::regist(*lua->state);
|
||||
#endif
|
||||
module::regist_globalfuns(*lua);
|
||||
module::local_storage::regist(lua);
|
||||
module::mutex::regist(lua);
|
||||
module::auto_lock::regist(lua);
|
||||
module::codec::regist(lua);
|
||||
module::time::regist(lua);
|
||||
module::file::regist(lua);
|
||||
module::sys::regist(lua);
|
||||
module::regist_globalfuns(*lua->state);
|
||||
module::local_storage::regist(lua->state);
|
||||
module::mutex::regist(lua->state);
|
||||
module::auto_lock::regist(lua->state);
|
||||
module::codec::regist(lua->state);
|
||||
module::time::regist(lua->state);
|
||||
module::file::regist(lua->state);
|
||||
module::sys::regist(lua->state);
|
||||
|
||||
global::getInstance()->regist_lua(lua);
|
||||
global::getInstance()->regist_lua(lua->state);
|
||||
return lua;
|
||||
}
|
||||
|
||||
sol::state* state_manager::get_state()
|
||||
luastate* state_manager::get()
|
||||
{
|
||||
sol::state* result = nullptr;
|
||||
if (m_states.pop(result))
|
||||
return result;
|
||||
return create_state();
|
||||
luastate* result = nullptr;
|
||||
while (m_states.pop(result))
|
||||
{
|
||||
if (result->flag != m_flag)
|
||||
delete result;
|
||||
else
|
||||
return result;
|
||||
}
|
||||
return create();
|
||||
}
|
||||
|
||||
void state_manager::push_state(sol::state* state)
|
||||
void state_manager::push(luastate* state)
|
||||
{
|
||||
if (state == nullptr)
|
||||
return;
|
||||
#if LOOP_STATE_USE == 1
|
||||
if (state->flag != m_flag)
|
||||
{
|
||||
delete state;
|
||||
return;
|
||||
}
|
||||
m_states.push(state);
|
||||
#else
|
||||
m_delete_states.push(state);
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool state_manager::run()
|
||||
{
|
||||
#if LOOP_STATE_USE == 0
|
||||
auto now_msec = time::now_msec();
|
||||
// 虚拟机缓冲保证
|
||||
if(sConfig->scripts.lua_cache_size > m_states.size())
|
||||
{
|
||||
std::vector<sol::state*> bhvalues;
|
||||
auto bhcount = sConfig->scripts.lua_cache_size - m_states.size();
|
||||
if (bhcount > 0 && bhcount <= sConfig->scripts.lua_cache_size)
|
||||
{
|
||||
for (size_t i = 0; i < bhcount; i++)
|
||||
bhvalues.push_back(create_state());
|
||||
}
|
||||
for(size_t i=0;i< bhvalues.size();i++)
|
||||
m_states.push(bhvalues[i]);
|
||||
}
|
||||
|
||||
// 释放虚拟机
|
||||
{
|
||||
sol::state* state = nullptr;
|
||||
while (m_delete_states.pop(state))
|
||||
delete state;
|
||||
}
|
||||
|
||||
system::sleep_msec(100);
|
||||
if (m_lib_detecter.changed())
|
||||
m_flag++;
|
||||
system::sleep_msec(3000);
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "util/map.hpp"
|
||||
|
||||
#include "core/structs.h"
|
||||
#include "core/lualibdetecter.h"
|
||||
|
||||
/// <summary>
|
||||
/// LUA状态管理器
|
||||
@@ -27,21 +28,29 @@ public:
|
||||
/// 取虚拟机
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
sol::state* get_state();
|
||||
luastate* get();
|
||||
/// <summary>
|
||||
/// 归还虚拟机
|
||||
/// </summary>
|
||||
/// <param name="state"></param>
|
||||
void push_state(sol::state* state);
|
||||
void push(luastate* state);
|
||||
private:
|
||||
// 虚拟机
|
||||
ylib::queue<sol::state*> m_states;
|
||||
ylib::queue<sol::state*> m_delete_states;
|
||||
ylib::queue<luastate*> m_states;
|
||||
// 版本FLAT
|
||||
size_t m_flag = 0;
|
||||
// LIB变化检测
|
||||
lualib_detecter m_lib_detecter;
|
||||
private:
|
||||
// 通过 ithread 继承
|
||||
bool run() override;
|
||||
/// <summary>
|
||||
/// 创建虚拟机
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
luastate* create();
|
||||
|
||||
|
||||
sol::state* create_state();
|
||||
|
||||
|
||||
};
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "base/define.h"
|
||||
#include "sol/sol.hpp"
|
||||
/// <summary>
|
||||
/// LUA字节码
|
||||
/// </summary>
|
||||
@@ -12,4 +13,19 @@ struct bytecode {
|
||||
std::string value;
|
||||
// 自动更新
|
||||
bool auto_update = false;
|
||||
};
|
||||
/// <summary>
|
||||
/// 包装虚拟机
|
||||
/// </summary>
|
||||
struct luastate {
|
||||
luastate()
|
||||
{
|
||||
state = new sol::state();
|
||||
}
|
||||
~luastate()
|
||||
{
|
||||
delete state;
|
||||
}
|
||||
sol::state* state = nullptr;
|
||||
size_t flag = 0;
|
||||
};
|
||||
194
src/core/subscribemanager.cpp
Normal file
194
src/core/subscribemanager.cpp
Normal file
@@ -0,0 +1,194 @@
|
||||
#include "subscribemanager.h"
|
||||
#include "core/config.h"
|
||||
#include "core/statemanager.h"
|
||||
#include "module/http/request.h"
|
||||
#include "module/http/response.h"
|
||||
subscribe_manager::subscribe_manager()
|
||||
{
|
||||
}
|
||||
subscribe_manager::~subscribe_manager()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
void subscribe_manager::load(network::http::router* router)
|
||||
{
|
||||
clear();
|
||||
m_router = router;
|
||||
// 初始化全部订阅
|
||||
auto files = sConfig->lua_app_files();
|
||||
for (size_t i = 0; i < files.size(); i++)
|
||||
{
|
||||
init_subscribe(files[i]);
|
||||
}
|
||||
// 其它绑定
|
||||
router->other(&subscribe_manager::other);
|
||||
}
|
||||
|
||||
void subscribe_manager::clear()
|
||||
{
|
||||
if (m_router != nullptr)
|
||||
{
|
||||
m_router->clear_subscribe();
|
||||
}
|
||||
for (size_t i = 0; i < m_subextra.size(); i++)
|
||||
delete m_subextra[i];
|
||||
m_subextra.clear();
|
||||
m_router = nullptr;
|
||||
}
|
||||
|
||||
void subscribe_manager::init_subscribe(const std::string& filepath)
|
||||
{
|
||||
auto state = sStateMgr->get();
|
||||
std::string route_pattern;
|
||||
network::http::method method = network::http::ALL;
|
||||
try
|
||||
{
|
||||
auto result = state->state->script_file(sConfig->scripts.app_dir + "/" + filepath);
|
||||
if (result.valid()) {
|
||||
auto router = (*state->state)["route"];
|
||||
auto type = router.get_type();
|
||||
if (router.is<sol::table>())
|
||||
{
|
||||
sol::optional<std::string> route_pattern_param = router[1];
|
||||
sol::optional<int> method_param = router[2];
|
||||
if (route_pattern_param && route_pattern_param->empty() == false)
|
||||
route_pattern = *route_pattern_param;
|
||||
if (method_param)
|
||||
method = (network::http::method)*method_param;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
LOG_ERROR(e.what());
|
||||
}
|
||||
|
||||
sStateMgr->push(state);
|
||||
if (route_pattern.empty())
|
||||
route_pattern = sConfig->scripts.app_mapping_dir + filepath;
|
||||
|
||||
// OutPutLog
|
||||
{
|
||||
std::string log;
|
||||
log = "[subscribe] lua: " + filepath + "\t pattern: " + route_pattern + "\t method: ";
|
||||
switch (method)
|
||||
{
|
||||
case ylib::network::http::GET:
|
||||
log.append("GET");
|
||||
break;
|
||||
case ylib::network::http::POST:
|
||||
log.append("POST");
|
||||
break;
|
||||
case ylib::network::http::PUT:
|
||||
log.append("PUT");
|
||||
break;
|
||||
case ylib::network::http::DEL:
|
||||
log.append("DEL");
|
||||
break;
|
||||
case ylib::network::http::HEAD:
|
||||
log.append("HEAD");
|
||||
break;
|
||||
case ylib::network::http::ALL:
|
||||
log.append("ALL");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
LOG_INFO(log);
|
||||
}
|
||||
|
||||
|
||||
std::string* extra = new std::string(sConfig->scripts.app_dir + "/" + filepath);
|
||||
m_subextra.push_back(extra);
|
||||
m_router->subscribe(route_pattern, method, &subscribe_manager::callback, extra);
|
||||
}
|
||||
|
||||
void subscribe_manager::callback(network::http::request* request, network::http::response* response, void* extra)
|
||||
{
|
||||
std::string lua_filepath = *(std::string*)extra;
|
||||
|
||||
auto lua = sStateMgr->get();
|
||||
std::string exception_string;
|
||||
try
|
||||
{
|
||||
auto lbResult = lua->state->load_file(lua_filepath);
|
||||
if (lbResult.valid() == false)
|
||||
{
|
||||
sol::error err = lbResult;
|
||||
throw ylib::exception("Failed to load bytecode, " + std::string(err.what()));
|
||||
}
|
||||
module::request m_request(request);
|
||||
module::response m_response(response);
|
||||
|
||||
lbResult();
|
||||
|
||||
(*lua->state)["response"] = &m_response;
|
||||
(*lua->state)["request"] = &m_request;
|
||||
|
||||
auto result = (*lua->state)["access"]();
|
||||
if (!result.valid()) {
|
||||
sol::error err = result;
|
||||
throw ylib::exception(err.what());
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
exception_string = e.what();
|
||||
if (sConfig->website.debug)
|
||||
LOG_ERROR("[subscribe_service][" + request->filepath() + "]: " + e.what());
|
||||
}
|
||||
// 清理
|
||||
lua->state->collect_garbage();
|
||||
sStateMgr->push(lua);
|
||||
|
||||
if (exception_string.empty() == false)
|
||||
throw ylib::exception(exception_string);
|
||||
}
|
||||
|
||||
void subscribe_manager::other(network::http::request* request, network::http::response* response)
|
||||
{
|
||||
auto send_404 = [](network::http::response* response) {
|
||||
std::string default_404 = sConfig->website.static_dir + "\\" + sConfig->website.default_404;
|
||||
if (sConfig->website.default_404 == "" || ylib::file::exist(default_404) == false)
|
||||
{
|
||||
response->send((std::string)"404 Not Found", 404, "Not Found");
|
||||
}
|
||||
else
|
||||
{
|
||||
response->send_file(default_404, -1, 404, "Not Found");
|
||||
}
|
||||
};
|
||||
auto send_file = [&](network::http::response* response, std::string filepath)
|
||||
{
|
||||
filepath = sConfig->website.static_dir + filepath;
|
||||
if (ylib::file::exist(filepath))
|
||||
{
|
||||
response->send_file(filepath);
|
||||
}
|
||||
else
|
||||
{
|
||||
send_404(response);
|
||||
}
|
||||
};
|
||||
|
||||
if (request->filepath() == "/")
|
||||
{
|
||||
bool find = false;
|
||||
for (size_t i = 0; i < sConfig->website.default_index.size(); i++)
|
||||
{
|
||||
std::string filepath = sConfig->website.static_dir + request->filepath() + sConfig->website.default_index[i];
|
||||
if (ylib::file::exist(filepath))
|
||||
{
|
||||
find = true;
|
||||
response->send_file(filepath);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (find == false)
|
||||
{
|
||||
send_404(response);
|
||||
}
|
||||
return;
|
||||
}
|
||||
send_file(response, request->filepath());
|
||||
}
|
||||
44
src/core/subscribemanager.h
Normal file
44
src/core/subscribemanager.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "sol/sol.hpp"
|
||||
#include "base/singleton.hpp"
|
||||
#include "core/structs.h"
|
||||
#include "net/http_request.h"
|
||||
#include "net/http_response.h"
|
||||
#include "net/http_router.h"
|
||||
/// <summary>
|
||||
/// 订阅管理器
|
||||
/// </summary>
|
||||
class subscribe_manager{
|
||||
public:
|
||||
subscribe_manager();
|
||||
~subscribe_manager();
|
||||
|
||||
void load(network::http::router* router);
|
||||
void clear();
|
||||
private:
|
||||
/// <summary>
|
||||
/// 初始化订阅
|
||||
/// </summary>
|
||||
/// <param name="filepath"></param>
|
||||
/// <returns></returns>
|
||||
void init_subscribe(const std::string& filepath);
|
||||
private:
|
||||
/// <summary>
|
||||
/// 服务回调
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="response"></param>
|
||||
static void callback(network::http::request* request, network::http::response* response, void* extra);
|
||||
/// <summary>
|
||||
/// 其它
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="response"></param>
|
||||
/// <param name="extra"></param>
|
||||
static void other(network::http::request* request, network::http::response* response);
|
||||
private:
|
||||
network::http::router* m_router = nullptr;
|
||||
std::vector<std::string*> m_subextra;
|
||||
};
|
||||
@@ -9,12 +9,14 @@ namespace module
|
||||
/// </summary>
|
||||
class imodule {
|
||||
public:
|
||||
virtual ~imodule() {};
|
||||
/// <summary>
|
||||
/// 注册全局变量
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="lua"></param>
|
||||
virtual void regist_global(const std::string& name,sol::state* lua) = 0;
|
||||
virtual void delete_global() = 0;
|
||||
/// <summary>
|
||||
/// 全局变量阶段获取自身指针
|
||||
/// </summary>
|
||||
|
||||
@@ -4,6 +4,11 @@ module::local_storage::local_storage()
|
||||
{
|
||||
}
|
||||
|
||||
module::local_storage::~local_storage()
|
||||
{
|
||||
::ylib::local_storage::close();
|
||||
}
|
||||
|
||||
sol::optional<std::string> module::local_storage::readex(const std::string& name)
|
||||
{
|
||||
std::string value;
|
||||
@@ -23,7 +28,8 @@ void module::local_storage::regist(sol::state* lua)
|
||||
"open", &module::local_storage::open,
|
||||
"read", &module::local_storage::readex,
|
||||
"write", &module::local_storage::write,
|
||||
"self", &module::local_storage::self
|
||||
"self", &module::local_storage::self,
|
||||
"last_error", &module::local_storage::last_error
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace module
|
||||
class local_storage : public ylib::local_storage,public module::imodule {
|
||||
public:
|
||||
local_storage();
|
||||
~local_storage() override;
|
||||
/// <summary>
|
||||
/// 取数据
|
||||
/// </summary>
|
||||
@@ -20,6 +21,7 @@ namespace module
|
||||
private:
|
||||
// 通过 imodule 继承
|
||||
virtual void regist_global(const std::string& name, sol::state* lua);
|
||||
virtual void delete_global() { delete this; }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace module
|
||||
class mutex:public module::imodule {
|
||||
public:
|
||||
mutex();
|
||||
~mutex();
|
||||
~mutex() override;
|
||||
/// <summary>
|
||||
/// 加锁
|
||||
/// </summary>
|
||||
@@ -28,6 +28,7 @@ namespace module
|
||||
private:
|
||||
// 通过 imodule 继承
|
||||
virtual void regist_global(const std::string& name, sol::state* lua);
|
||||
virtual void delete_global() { delete this; }
|
||||
std::mutex m_mutex;
|
||||
};
|
||||
|
||||
|
||||
@@ -448,12 +448,13 @@ module::mysql::mysql()
|
||||
|
||||
module::mysql::~mysql()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
bool module::mysql::start(const std::string& ipaddress, const std::string& username, const std::string& password, const std::string& database, const std::string& charset, ushort port, int32 size)
|
||||
{
|
||||
close();
|
||||
m_pool = new ylib::mysql::pool();
|
||||
m_pool = std::make_shared<ylib::mysql::pool>();
|
||||
ylib::mysql::mysql_conn_info info;
|
||||
info.ipaddress = ipaddress;
|
||||
info.username = username;
|
||||
@@ -466,9 +467,7 @@ bool module::mysql::start(const std::string& ipaddress, const std::string& usern
|
||||
|
||||
void module::mysql::close()
|
||||
{
|
||||
if (m_pool != nullptr)
|
||||
delete m_pool;
|
||||
m_pool = nullptr;
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<module::select> module::mysql::select()
|
||||
@@ -496,7 +495,6 @@ void module::mysql::regist_global(const std::string& name, sol::state* lua)
|
||||
lua->registry()[name] = this;
|
||||
(*lua)[name] = this;
|
||||
}
|
||||
|
||||
module::mysql_result::mysql_result(ylib::mysql::result* result):m_result(result)
|
||||
{
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@ namespace module
|
||||
class mysql :public imodule {
|
||||
public:
|
||||
mysql();
|
||||
~mysql();
|
||||
~mysql() override;
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
@@ -177,10 +177,11 @@ namespace module
|
||||
std::shared_ptr<module::update> update();
|
||||
std::shared_ptr<module::delete_> delete_();
|
||||
private:
|
||||
ylib::mysql::pool* m_pool = nullptr;
|
||||
std::shared_ptr<ylib::mysql::pool> m_pool;
|
||||
|
||||
// 通过 imodule 继承
|
||||
virtual void regist_global(const std::string& name, sol::state* lua);
|
||||
virtual void delete_global() { delete this; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,38 +1,3 @@
|
||||
#include "luautils.h"
|
||||
#include "core/define.h"
|
||||
#include "core/statemanager.h"
|
||||
bool LuaUtils::make_bytecode(const std::string& filepath, std::string& bytecode)
|
||||
{
|
||||
auto lua = sStateMgr->get_state();
|
||||
try
|
||||
{
|
||||
auto result = lua->load_file(filepath);
|
||||
if (!result.valid()) {
|
||||
sol::error err = result;
|
||||
LOG_ERROR(err.what() + std::string(", filepath: " + filepath));
|
||||
return false;
|
||||
}
|
||||
result();
|
||||
sol::function func = result;
|
||||
if (!func.valid()) {
|
||||
LOG_ERROR("Pre execution script failed before compilation. filepath: " + filepath);
|
||||
return false;
|
||||
}
|
||||
sol::function dump = (*lua)["string"]["dump"];
|
||||
sol::protected_function_result result2 = dump(func);
|
||||
if (!result2.valid()) {
|
||||
sol::error err = result2;
|
||||
LOG_ERROR("failed to dump. " + std::string(err.what()) + ", filepath: " + filepath);
|
||||
return false;
|
||||
}
|
||||
LOG_INFO("update lua script, filepath: " + filepath);
|
||||
bytecode = result2;
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
LOG_INFO(std::string(e.what()) + ", filepath: " + filepath);
|
||||
}
|
||||
sStateMgr->push_state(lua);
|
||||
return false;
|
||||
}
|
||||
#include "core/statemanager.h"
|
||||
@@ -2,11 +2,5 @@
|
||||
#include <string>
|
||||
namespace LuaUtils {
|
||||
|
||||
/// <summary>
|
||||
/// 创建服务字节码
|
||||
/// </summary>
|
||||
/// <param name="filepath"></param>
|
||||
/// <param name="bytecode"></param>
|
||||
/// <returns></returns>
|
||||
bool make_bytecode(const std::string& filepath,std::string& bytecode);
|
||||
|
||||
}
|
||||
@@ -5,10 +5,22 @@
|
||||
int main()
|
||||
{
|
||||
std::string config_filepath = std::filesystem::current_path().string()+"/config.ini";
|
||||
if (fastweb(config_filepath.c_str()) != 0)
|
||||
if (fastweb_start(config_filepath.c_str()) != 0)
|
||||
return -1;
|
||||
|
||||
while (true)
|
||||
std::cin.get();
|
||||
{
|
||||
std::string input;
|
||||
std::cin >> input;
|
||||
|
||||
if (input == "quit" || input == "exit")
|
||||
{
|
||||
fastweb_close();
|
||||
std::cout << "closed";
|
||||
break;
|
||||
}
|
||||
else
|
||||
std::cout << "Enter \"quit\" or \"exit\" to exit the application" << std::endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user