Forráskód Böngészése

Merge branch 'master' of https://github.com/Liuccysdgg/fastweb

xx 2 éve
szülő
commit
7e80e528b3
50 módosított fájl, 1074 hozzáadás és 711 törlés
  1. 14 3
      CMakeLists.txt
  2. 3 0
      config.ini
  3. 95 0
      module/hello/CMakeLists.txt
  4. 33 0
      module/hello/hello.cpp
  5. 9 0
      module/hello/hello.h
  6. 18 0
      module/module.h
  7. 3 1
      scripts/init.lua
  8. 0 80
      src/core/bytecodemanager.cpp
  9. 0 45
      src/core/bytecodemanager.h
  10. 34 5
      src/core/config.cpp
  11. 3 5
      src/core/config.h
  12. 0 1
      src/core/define.h
  13. 10 2
      src/core/entry.cpp
  14. 2 1
      src/core/entry.h
  15. 31 324
      src/core/fastweb.cpp
  16. 9 34
      src/core/fastweb.h
  17. 15 0
      src/core/global.cpp
  18. 1 0
      src/core/global.h
  19. 75 0
      src/core/interceptormanager.cpp
  20. 31 0
      src/core/interceptormanager.h
  21. 45 0
      src/core/lualibdetecter.cpp
  22. 28 0
      src/core/lualibdetecter.h
  23. 161 0
      src/core/modulemanager.cpp
  24. 48 0
      src/core/modulemanager.h
  25. 28 101
      src/core/statemanager.cpp
  26. 17 6
      src/core/statemanager.h
  27. 16 0
      src/core/structs.h
  28. 194 0
      src/core/subscribemanager.cpp
  29. 44 0
      src/core/subscribemanager.h
  30. 5 5
      src/module/globalfuns.cpp
  31. 1 1
      src/module/globalfuns.h
  32. 2 2
      src/module/http/httpclient.cpp
  33. 1 1
      src/module/http/httpclient.h
  34. 7 7
      src/module/http/request.cpp
  35. 1 1
      src/module/http/request.h
  36. 2 2
      src/module/http/response.cpp
  37. 1 1
      src/module/http/response.h
  38. 2 2
      src/module/http/session.cpp
  39. 1 1
      src/module/http/session.h
  40. 2 0
      src/module/imodule.h
  41. 7 1
      src/module/localstorage.cpp
  42. 2 0
      src/module/localstorage.h
  43. 2 2
      src/module/mssql.cpp
  44. 1 1
      src/module/mssql.h
  45. 2 1
      src/module/mutex.h
  46. 18 20
      src/module/mysql.cpp
  47. 9 8
      src/module/mysql.h
  48. 1 36
      src/utils/luautils.cpp
  49. 1 7
      src/utils/luautils.h
  50. 39 4
      tests/main.cpp

+ 14 - 3
CMakeLists.txt

@@ -1,7 +1,8 @@
 cmake_minimum_required(VERSION 3.5)
 project("fastweb")
 
-
+# 设置全局属性
+set_property(GLOBAL PROPERTY USE_FOLDERS ON)
 
 
 # 设置自定义配置类型
@@ -14,7 +15,8 @@ set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
 set(FASTWEBCORE ${PROJECT_NAME}core)
 # 安装复制
 set(CMAKE_INSTALL_ALWAYS_COPY TRUE)
-
+# 设置根目录
+set(ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
 # Recursively get all source files
 file(GLOB_RECURSE SOURCE_FILES
     "${PROJECT_SOURCE_DIR}/src/*.cpp"
@@ -126,10 +128,19 @@ else()
 
 endif()
 
-
+# 编译测试调用示例
 add_executable(${PROJECT_NAME} tests/main.cpp)
 target_link_libraries(${PROJECT_NAME} ${FASTWEBCORE})
 set_target_properties(${PROJECT_NAME} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}")
+
+# 查找并添加所有模块
+file(GLOB MODULES RELATIVE ${CMAKE_SOURCE_DIR}/module ${CMAKE_SOURCE_DIR}/module/*)
+foreach(MODULE ${MODULES})
+    if(IS_DIRECTORY ${CMAKE_SOURCE_DIR}/module/${MODULE})
+        add_subdirectory(${CMAKE_SOURCE_DIR}/module/${MODULE})
+    endif()
+endforeach()
+
 ########################  安装  ########################
 install(TARGETS ${FASTWEBCORE} DESTINATION $<IF:$<CONFIG:Debug>,bin/debug,bin/release>)
 install(TARGETS ${PROJECT_NAME} DESTINATION $<IF:$<CONFIG:Debug>,bin/debug,bin/release>)

+ 3 - 0
config.ini

@@ -7,6 +7,8 @@ base=${current_dir}
 app_dir=${base}/scripts/app
 ; LUA库目录
 lib_dir=${base}/scripts/lib
+; 模块目录
+module_dir=${base}/module
 ; LUA虚拟机缓存数量(并发越高越大)-建议:10
 lua_cache_size=3000
 ; 脚本映射网站目录
@@ -16,6 +18,7 @@ app_mapping_dir=/scripts/
 ; 自动检测文件修改时间(秒)
 auto_update_sec=3
 
+
 [website]
 ; 网站静态文件目录
 static_dir=${base}/www

+ 95 - 0
module/hello/CMakeLists.txt

@@ -0,0 +1,95 @@
+# 获取当前目录的名称
+get_filename_component(MODULE_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
+
+# 设置项目名为当前目录名
+project(${MODULE_NAME})
+
+# 搜索源文件和头文件
+file(GLOB_RECURSE SOURCE_FILES "${PROJECT_SOURCE_DIR}/*.cpp")
+file(GLOB_RECURSE HEADER_FILES 
+    "${PROJECT_SOURCE_DIR}/*.h"
+    "../*.h"
+)
+
+# 将源文件分配到 Source Files 文件夹
+foreach(source IN LISTS SOURCE_FILES)
+    get_filename_component(source_path "${source}" PATH)
+    file(RELATIVE_PATH source_path_rel "${PROJECT_SOURCE_DIR}" "${source_path}")
+    string(REPLACE "/" "\\" source_path_rel_win "${source_path_rel}")
+    source_group("Source Files\\${source_path_rel_win}" FILES "${source}")
+endforeach()
+
+# 将头文件分配到 Header Files 文件夹
+foreach(header IN LISTS HEADER_FILES)
+    get_filename_component(header_path "${header}" PATH)
+    file(RELATIVE_PATH header_path_rel "${PROJECT_SOURCE_DIR}" "${header_path}")
+    string(REPLACE "/" "\\" header_path_rel_win "${header_path_rel}")
+    source_group("Header Files\\${header_path_rel_win}" FILES "${header}")
+endforeach()
+
+include_directories(${ROOT_DIR}/module)
+include_directories(${ROOT_DIR}/3rdpary)
+# 添加共享库
+add_library(${MODULE_NAME} SHARED ${HEADER_FILES} ${SOURCE_FILES})
+
+if(MSVC)
+	target_link_libraries(${MODULE_NAME} PRIVATE
+			odbc32.lib
+			User32.lib
+			Advapi32.lib
+			IPHLPAPI.lib
+			WS2_32.lib
+			Shell32.lib
+			${YLIB}/lib/libcrypto_static_win64.lib
+			$<$<CONFIG:Debug>:${ROOT_DIR}/3rdparty/HP-Socket/Lib/HPSocket_D.lib>
+			$<$<CONFIG:Debug>:${ROOT_DIR}/3rdparty/mysql/lib/Debug/mysqlcppconn.lib>
+			$<$<CONFIG:Debug>:${YLIB}/lib/leveldb_d.lib>
+			$<$<CONFIG:Debug>:${YLIB}/lib/libzip_d.lib>
+			$<$<CONFIG:Debug>:${YLIB}/lib/lua_d.lib>
+			$<$<CONFIG:Debug>:${YLIB}/lib/sqlite3_d.lib>
+			$<$<CONFIG:Debug>:${YLIB}/lib/ylib_d.lib>
+			$<$<CONFIG:Debug>:${YLIB}/lib/zlib_d.lib>
+			$<$<CONFIG:Debug>:${ROOT_DIR}/3rdparty/soci/lib/Debug/libsoci_core_4_1.lib>
+			$<$<CONFIG:Debug>:${ROOT_DIR}/3rdparty/soci/lib/Debug/libsoci_empty_4_1.lib>
+			$<$<CONFIG:Debug>:${ROOT_DIR}/3rdparty/soci/lib/Debug/libsoci_odbc_4_1.lib>
+			$<$<CONFIG:Debug>:${ROOT_DIR}/3rdparty/soci/lib/Debug/soci_core_4_1.lib>
+			$<$<CONFIG:Debug>:${ROOT_DIR}/3rdparty/soci/lib/Debug/soci_empty_4_1.lib>
+			$<$<CONFIG:Debug>:${ROOT_DIR}/3rdparty/soci/lib/Debug/soci_odbc_4_1.lib>
+			$<$<CONFIG:Release>:${ROOT_DIR}/3rdparty/HP-Socket/Lib/HPSocket.lib>
+			$<$<CONFIG:Release>:${ROOT_DIR}/3rdparty/mysql/lib/Release/mysqlcppconn.lib>
+			$<$<CONFIG:Release>:${YLIB}/lib/leveldb.lib>
+			$<$<CONFIG:Release>:${YLIB}/lib/libzip.lib>
+			$<$<CONFIG:Release>:${YLIB}/lib/lua.lib>
+			$<$<CONFIG:Release>:${YLIB}/lib/sqlite3.lib>
+			$<$<CONFIG:Release>:${YLIB}/lib/ylib.lib>
+			$<$<CONFIG:Release>:${YLIB}/lib/zlib.lib>
+			$<$<CONFIG:Release>:${ROOT_DIR}/3rdparty/soci/lib/Release/libsoci_core_4_1.lib>
+			$<$<CONFIG:Release>:${ROOT_DIR}/3rdparty/soci/lib/Release/libsoci_empty_4_1.lib>
+			$<$<CONFIG:Release>:${ROOT_DIR}/3rdparty/soci/lib/Release/libsoci_odbc_4_1.lib>
+			$<$<CONFIG:Release>:${ROOT_DIR}/3rdparty/soci/lib/Release/soci_core_4_1.lib>
+			$<$<CONFIG:Release>:${ROOT_DIR}/3rdparty/soci/lib/Release/soci_empty_4_1.lib>
+			$<$<CONFIG:Release>:${ROOT_DIR}/3rdparty/soci/lib/Release/soci_odbc_4_1.lib>
+	)
+else()
+	target_link_libraries(${MODULE_NAME} 
+			hpsocket
+			ylib
+			leveldb
+			soci_core
+			soci_firebird
+			soci_mysql
+			soci_odbc
+			soci_postgresql
+			soci_sqlite3
+			crypto
+			lua5.3
+			mysqlcppconn
+			pthread
+	)
+
+endif()
+# 设置生成的项目文件夹为 module
+set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "module")
+
+
+install(TARGETS ${MODULE_NAME} DESTINATION $<IF:$<CONFIG:Debug>,bin/debug/module,bin/release/module>)

+ 33 - 0
module/hello/hello.cpp

@@ -0,0 +1,33 @@
+#include "hello.h"
+#include "module.h"
+#include "sol/sol.hpp"
+hello::hello()
+{
+}
+
+hello::~hello()
+{
+}
+
+std::string hello::name()
+{
+	return "My name is `Fast Web`";
+}
+
+
+extern "C" {
+#ifdef _WIN32
+	DLL_EXPORT
+#endif
+	int fastweb_module_regist(void* sol2, void* lua)
+	{
+		sol::state* state = static_cast<sol::state*>(sol2);
+		state->new_usertype<hello>("hello",
+			"name", &hello::name
+		);
+		// 返回成功
+		return 0;
+	}
+}
+
+

+ 9 - 0
module/hello/hello.h

@@ -0,0 +1,9 @@
+#pragma once
+#include <string>
+class hello
+{
+public:
+	hello();
+	~hello();
+	static std::string name();
+};

+ 18 - 0
module/module.h

@@ -0,0 +1,18 @@
+#if defined(_WIN32) || defined(_WIN64)
+#define DLL_EXPORT __declspec(dllexport)
+#else
+#define DLL_EXPORT __attribute__((visibility("default")))
+#endif
+extern "C" {
+	/// <summary>
+	/// 注册模块入口
+	/// </summary>
+	/// <param name="sol2"></param>
+	/// <param name="lua"></param>
+	/// <returns>
+	/// 0=成功
+	/// 1=失败
+	/// </returns>
+	DLL_EXPORT int fastweb_module_regist(void* sol2,void* lua);
+}
+ 

+ 3 - 1
scripts/init.lua

@@ -1,6 +1,8 @@
 
 
 print("init fast web success!")
-
+-- 自定义模块演示
+local hello = hello.new()
+print("Custom Module: "..hello:name())
 
 return true

+ 0 - 80
src/core/bytecodemanager.cpp

@@ -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

+ 0 - 45
src/core/bytecodemanager.h

@@ -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

+ 34 - 5
src/core/config.cpp

@@ -14,7 +14,16 @@ bool config::open(const std::string& ini_filepath)
 		return false;
 	}
 	std::string src_content = ylib::file::read(temp_filepath);
+	// EXE运行目录
 	src_content = strutils::replace(src_content, "${current_dir}", strutils::replace(system::current_dir(),'\\','/'));
+	// 配置文件目录
+	{
+		std::string ini_dir = ylib::file::parent_dir(ini_filepath);
+		src_content = strutils::replace(src_content, "${config_dir}", ini_dir);
+	}
+	
+
+
 	ylib::file::write(temp_filepath,src_content);
 	if (m_ini.open(temp_filepath))
 	{
@@ -35,14 +44,33 @@ bool config::open(const std::string& ini_filepath)
 	cache();
 	return true;
 }
-bool config::have_https()
+std::vector<std::string> config::lua_app_files()
+{
+	std::vector<std::string> results;
+	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, '\\', '/');
+
+		results.push_back(path);
+	}
+	return results;
+}
+std::vector<std::string> config::lua_lib_files()
 {
-	for_iter(iter, domain)
+	std::vector<std::string> results;
+	auto luas = ylib::file::traverse(sConfig->scripts.lib_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::extractVariableNames(const std::string& text)
 {
@@ -63,6 +91,7 @@ void config::cache()
 
 	scripts.app_dir = m_ini.read("scripts","app_dir");
 	scripts.lib_dir = m_ini.read("scripts", "lib_dir");
+	scripts.module_dir = m_ini.read("scripts", "module_dir");
 	scripts.lua_cache_size = ylib::stoi(m_ini.read("scripts", "lua_cache_size"));
 	scripts.app_mapping_dir = m_ini.read("scripts", "app_mapping_dir");
 	scripts.auto_update_sec = ylib::stoi(m_ini.read("scripts", "auto_update_sec"));

+ 3 - 5
src/core/config.h

@@ -14,6 +14,7 @@ public:
 	struct scripts {
 		std::string app_dir;
 		std::string lib_dir;
+		std::string module_dir;
 		uint32 lua_cache_size = 0;
 		std::string app_mapping_dir;
 		uint32 auto_update_sec = 0;
@@ -37,11 +38,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;

+ 0 - 1
src/core/define.h

@@ -30,4 +30,3 @@
 #define VarType sol::object
 
 
-#define ENABLE_BYTECODE 0

+ 10 - 2
src/core/entry.cpp

@@ -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();
+	}
+}
+

+ 2 - 1
src/core/entry.h

@@ -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();
 }
  

+ 31 - 324
src/core/fastweb.cpp

@@ -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()
 {
 
@@ -32,6 +34,15 @@ bool fastweb::start()
 		host_config.port = iter->second.port;
 		host_config.ssl = iter->second.https;
 		ws_config.host.push_back(host_config);
+
+		std::string url;
+		if (host_config.ssl)
+			url = "https://";
+		else
+			url = "http://";
+		url += host_config.domain;
+		url += ":" + std::to_string(host_config.port);
+		LOG_WARN("URL: "+url);
 	}
 
 	ws_config.name = "master";
@@ -59,210 +70,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 +110,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 +130,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");
-	}
-}
+}

+ 9 - 34
src/core/fastweb.h

@@ -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;
 };

+ 15 - 0
src/core/global.cpp

@@ -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();
+}

+ 1 - 0
src/core/global.h

@@ -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 - 0
src/core/interceptormanager.cpp

@@ -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 - 0
src/core/interceptormanager.h

@@ -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 - 0
src/core/lualibdetecter.cpp

@@ -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 - 0
src/core/lualibdetecter.h

@@ -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;
+};

+ 161 - 0
src/core/modulemanager.cpp

@@ -0,0 +1,161 @@
+#include "modulemanager.h"
+
+#include "util/file.h"
+
+#include "core/config.h"
+#include "core/global.h"
+#ifdef _WIN32
+#include <Windows.h>
+#else
+
+#endif
+
+#include "module/http/request.h"
+#include "module/http/response.h"
+#include "module/http/session.h"
+#include "module/http/httpclient.h"
+#include "module/mysql.h"
+#ifdef _WIN32
+#include "module/mssql.h"
+#endif
+#include "module/localstorage.h"
+#include "module/globalfuns.h"
+#include "module/mutex.h"
+#include "module/codec.h"
+#include "module/time.h"
+#include "module/file.h"
+#include "module/sys.h"
+module_manager::module_manager()
+{
+	
+}
+
+module_manager::~module_manager()
+{
+}
+
+void module_manager::start()
+{
+	close();
+	auto ms = modules();
+	for (size_t i = 0; i < ms.size(); i++)
+	{
+		module_info mi;
+		std::string mod_filepath = sConfig->scripts.module_dir + "/" + ms[i];
+#ifdef _WIN32
+		mi.dll = LoadLibrary(mod_filepath.c_str());
+		if (mi.dll == nullptr)
+		{
+			LOG_ERROR("module loading failed, filename: " + mod_filepath);
+			continue;
+		}
+		mi.func = (fastweb_module_regist)GetProcAddress((HMODULE)mi.dll, "fastweb_module_regist");
+		if (mi.func == nullptr) {
+			LOG_ERROR("function not found: `fastweb_module_regist`, filename: " + mod_filepath);
+			FreeLibrary((HMODULE)mi.dll);
+			continue;
+		}
+		m_modules.emplace(mod_filepath, mi);
+		/*if (api_func(lua, lua->lua_state()) == 0)
+		{
+			LOG_INFO("successfully regist module, filename: " + mod_filepath);
+			continue;
+		}
+		LOG_ERROR("regist module failed, filename: " + mod_filepath);*/
+#else
+
+#endif
+	}
+}
+
+void module_manager::close()
+{
+	for_iter(iter, m_modules)
+	{
+#ifdef _WIN32
+		FreeLibrary((HMODULE)iter->second.dll);
+#else
+#endif
+	}
+	m_modules.clear();
+}
+
+void module_manager::load(sol::state* lua)
+{
+	load_core(lua);
+	load_lualib(lua);
+	load_3rdparty(lua);
+}
+
+void module_manager::load_core(sol::state* lua)
+{
+	lua->open_libraries(
+		sol::lib::base,
+		sol::lib::package,
+		sol::lib::math,
+		sol::lib::string,
+		sol::lib::table,
+		sol::lib::utf8,
+		sol::lib::bit32,
+		sol::lib::coroutine,
+		sol::lib::count,
+		sol::lib::ffi,
+		sol::lib::io,
+		sol::lib::jit,
+		sol::lib::os
+	);
+
+
+	module::request::regist(lua);
+	module::response::regist(lua);
+	module::session::regist(lua);
+	module::httpclient::regist(lua);
+	module::mysql_regist(lua);
+#ifdef _WIN32
+	module::mssql::regist(lua);
+#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);
+
+	global::getInstance()->regist_lua(lua);
+
+}
+
+void module_manager::load_3rdparty(sol::state* lua)
+{
+	for_iter(iter, m_modules)
+	{ 
+		if (iter->second.func(lua, lua->lua_state()) != 0)
+		{
+			LOG_ERROR("egist module failed, filename: "+iter->first);
+		}
+	}
+}
+
+void module_manager::load_lualib(sol::state* lua)
+{
+	// 获取当前的package.path,添加新的搜索路径
+	std::string current_path = (*lua)["package"]["path"];  // 获取当前的路径
+	current_path += ";" + sConfig->scripts.lib_dir + "/?.lua";  // 添加新的路径
+	(*lua)["package"]["path"] = current_path;  // 设置修改后的路径
+}
+
+std::vector<std::string> module_manager::modules()
+{
+	std::vector<std::string> results;
+	auto luas = ylib::file::traverse(sConfig->scripts.module_dir, "(.*\\.dll)");
+	for_iter(iter, luas)
+	{
+		if (iter->second == IS_DIRECTORY)
+			continue;
+		std::string path = strutils::replace(iter->first, '\\', '/');
+		results.push_back(path);
+	}
+	return results;
+}

+ 48 - 0
src/core/modulemanager.h

@@ -0,0 +1,48 @@
+#pragma once
+#include <map>
+#include "sol/sol.hpp"
+#include "core/structs.h"
+typedef int (*fastweb_module_regist)(void*, void*);
+struct module_info {
+	void* dll = nullptr;
+	fastweb_module_regist func = nullptr;
+};
+
+/// <summary>
+/// 模块管理器
+/// </summary>
+class module_manager{
+public:
+	module_manager();
+	~module_manager();
+
+	void start();
+	void close();
+	/// <summary>
+	/// 创建虚拟机
+	/// </summary>
+	/// <returns></returns>
+	void load(sol::state* lua);
+private:
+	/// <summary>
+	/// 加载核心库
+	/// </summary>
+	/// <param name="lua"></param>
+	void load_core(sol::state* lua);
+	/// <summary>
+	/// 加载三方库
+	/// </summary>
+	void load_3rdparty(sol::state* lua);
+	/// <summary>
+	/// 加载LUA库
+	/// </summary>
+	/// <param name="lua"></param>
+	void load_lualib(sol::state* lua);
+	/// <summary>
+	/// 取模块文件列表
+	/// </summary>
+	/// <returns></returns>
+	std::vector<std::string> modules();
+private:
+	std::map<std::string, module_info> m_modules;
+};

+ 28 - 101
src/core/statemanager.cpp

@@ -8,138 +8,65 @@
 #include "core/config.h"
 #include "core/global.h"
 
-#include "module/http/request.h"
-#include "module/http/response.h"
-#include "module/http/session.h"
-#include "module/http/httpclient.h"
-#include "module/mysql.h"
-#ifdef _WIN32
-#include "module/mssql.h"
-#endif
-#include "module/localstorage.h"
-#include "module/globalfuns.h"
-#include "module/mutex.h"
-#include "module/codec.h"
-#include "module/time.h"
-#include "module/file.h"
-#include "module/sys.h"
+
 #define LOOP_STATE_USE 1
 bool state_manager::start()
 {
-#if LOOP_STATE_USE ==  0
 	close();
 	::ithread::start();
-#endif
+	m_module_manager.start();
 	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;
-
+	m_module_manager.close();
 }
-sol::state* state_manager::create_state()
+luastate* state_manager::create()
 {
-	sol::state* lua = new sol::state();
-	lua->open_libraries(
-		sol::lib::base, 
-		sol::lib::package, 
-		sol::lib::math, 
-		sol::lib::string,
-		sol::lib::table,
-		sol::lib::utf8,
-		sol::lib::bit32,
-		sol::lib::coroutine,
-		sol::lib::count,
-		sol::lib::ffi,
-		sol::lib::io,
-		sol::lib::jit,
-		sol::lib::os
-	);
-	{
-		// 获取当前的package.path,添加新的搜索路径
-		std::string current_path = (*lua)["package"]["path"];  // 获取当前的路径
-		current_path += ";"+ sConfig->scripts.lib_dir +"/?.lua";  // 添加新的路径
-		(*lua)["package"]["path"] = current_path;  // 设置修改后的路径
-	}
-	module::request::regist(*lua);
-	module::response::regist(*lua);
-	module::session::regist(*lua);
-	module::httpclient::regist(*lua);
-	module::mysql_regist(*lua);
-	#ifdef _WIN32
-	module::mssql::regist(*lua);
-	#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);
-
-	global::getInstance()->regist_lua(lua);
+	luastate* lua = new luastate();
+	lua->flag = m_flag;
+	// 加载库或模块
+	m_module_manager.load(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(sConfig->scripts.auto_update_sec);
 	return true;
-#else
-	return false;
-#endif
 }
 

+ 17 - 6
src/core/statemanager.h

@@ -10,7 +10,8 @@
 #include "util/map.hpp"
 
 #include "core/structs.h"
-
+#include "core/lualibdetecter.h"
+#include "core/modulemanager.h"
 /// <summary>
 /// LUA状态管理器
 /// </summary>
@@ -27,21 +28,31 @@ 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;
+	// 模块管理器
+	module_manager m_module_manager;
 private:
 	// 通过 ithread 继承
 	bool run() override;
+	/// <summary>
+	/// 创建虚拟机
+	/// </summary>
+	/// <returns></returns>
+	luastate* create();
+
 
-	sol::state* create_state();
 
 
 };

+ 16 - 0
src/core/structs.h

@@ -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 - 0
src/core/subscribemanager.cpp

@@ -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 - 0
src/core/subscribemanager.h

@@ -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;
+};

+ 5 - 5
src/module/globalfuns.cpp

@@ -4,12 +4,12 @@
 #include "util/time.h"
 #include "core/global.h"
 static ylib::counter<uint64> s_counter_guid;
-void module::regist_globalfuns(sol::state& lua)
+void module::regist_globalfuns(sol::state* lua)
 {
-	lua.set_function("global_get", module::global_get);
-	lua.set_function("global_set", module::global_set);
-	lua.set_function("make_software_guid", module::make_software_guid);
-	lua.set_function("throw_string", module::throw_string);
+	lua->set_function("global_get", module::global_get);
+	lua->set_function("global_set", module::global_set);
+	lua->set_function("make_software_guid", module::make_software_guid);
+	lua->set_function("throw_string", module::throw_string);
 }
 std::string module::make_software_guid()
 {

+ 1 - 1
src/module/globalfuns.h

@@ -5,7 +5,7 @@
 /// </summary>
 namespace module
 {
-	void regist_globalfuns(sol::state& lua);
+	void regist_globalfuns(sol::state* lua);
 	/// <summary>
 	/// 生成软件唯一GUID
 	/// </summary>

+ 2 - 2
src/module/http/httpclient.cpp

@@ -43,9 +43,9 @@ ushort module::httpclient::status()
 	return m_client.status();
 }
 
-void module::httpclient::regist(sol::state& state)
+void module::httpclient::regist(sol::state* lua)
 {
-	state.new_usertype<module::httpclient>("httpclient",
+	lua->new_usertype<module::httpclient>("httpclient",
 		"new", sol::constructors<module::httpclient()>(),
 		"get", &module::httpclient::get,
 		"post", &module::httpclient::post,

+ 1 - 1
src/module/http/httpclient.h

@@ -17,7 +17,7 @@ namespace module
         std::string response();
         ushort status();
 
-        static void regist(sol::state& state);
+        static void regist(sol::state* lua);
     private:
         network::http::client_plus m_client;
     };

+ 7 - 7
src/module/http/request.cpp

@@ -45,10 +45,10 @@ void* module::request::website()
 {
     return m_request->website();
 }
-void module::request::regist(sol::state& state)
+void module::request::regist(sol::state* lua)
 {
     // 绑定 Request 类到 Lua
-    state.new_usertype<module::request>("module_request",
+    lua->new_usertype<module::request>("module_request",
         "header", &module::request::header,
         "method", &module::request::method,
         "filepath", &module::request::filepath,
@@ -62,11 +62,11 @@ void module::request::regist(sol::state& state)
         "url_param", &module::request::url_param,
         "body", &module::request::body
     );
-    state["GET"] = (int)network::http::GET;
-    state["POST"] = (int)network::http::POST;
-    state["DEL"] = (int)network::http::DEL;
-    state["HEAD"] = (int)network::http::HEAD;
-    state["PUT"] = (int)network::http::PUT;
+    (*lua)["GET"] = (int)network::http::GET;
+    (*lua)["POST"] = (int)network::http::POST;
+    (*lua)["DEL"] = (int)network::http::DEL;
+    (*lua)["HEAD"] = (int)network::http::HEAD;
+    (*lua)["PUT"] = (int)network::http::PUT;
 }
 
 

+ 1 - 1
src/module/http/request.h

@@ -30,7 +30,7 @@ namespace module
         std::string body();
         void* website();
 
-        static void regist(sol::state& state);
+        static void regist(sol::state* lua);
     private:
         bool request_param(const std::string& name, std::string& value);
     private:

+ 2 - 2
src/module/http/response.cpp

@@ -10,10 +10,10 @@ module::response::~response()
 {
 }
 
-void module::response::regist(sol::state& state)
+void module::response::regist(sol::state* lua)
 {
     // 绑定 Request 类到 Lua
-    state.new_usertype<module::response>("module_response",
+    lua->new_usertype<module::response>("module_response",
         "send_data", &module::response::send_data,
         "send", &module::response::send,
         "send_file", &module::response::send_file,

+ 1 - 1
src/module/http/response.h

@@ -18,7 +18,7 @@ namespace module
         bool redirect(const std::string& filepath, bool MovedPermanently = false);
         bool forward(const std::string& filepath);
         void header(const std::string& name, const std::string& value);
-        static void regist(sol::state& state);
+        static void regist(sol::state* lua);
     private:
         network::http::response* m_response = nullptr;
     };

+ 2 - 2
src/module/http/session.cpp

@@ -38,9 +38,9 @@ bool module::session::check()
 	return m_session->check();
 }
 
-void module::session::regist(sol::state& state)
+void module::session::regist(sol::state* lua)
 {
-	state.new_usertype<module::session>("module_session",
+	lua->new_usertype<module::session>("module_session",
 		"check", &module::session::check,
 		"get", &module::session::get,
 		"id", &module::session::id,

+ 1 - 1
src/module/http/session.h

@@ -16,7 +16,7 @@ namespace module
         void set(const std::string& name, const std::string& value);
         std::string get(const std::string& name);
         bool check();
-        static void regist(sol::state& state);
+        static void regist(sol::state* lua);
     private:
         network::http::session* m_session = nullptr;
     };

+ 2 - 0
src/module/imodule.h

@@ -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>

+ 7 - 1
src/module/localstorage.cpp

@@ -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
     );
 }
 

+ 2 - 0
src/module/localstorage.h

@@ -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; }
 	};
 }
 

+ 2 - 2
src/module/mssql.cpp

@@ -91,9 +91,9 @@ bool module::mssql::next()
 }
 
 
-void module::mssql::regist(sol::state& lua)
+void module::mssql::regist(sol::state* lua)
 {
-    lua.new_usertype<module::mssql>("mssql",
+    lua->new_usertype<module::mssql>("mssql",
         "new", sol::constructors<module::mssql(const std::string&)>(),
         "get_dob", &module::mssql::get_dob,
         "get_i32", &module::mssql::get_i32,

+ 1 - 1
src/module/mssql.h

@@ -34,7 +34,7 @@ namespace module
 		/// 注册
 		/// </summary>
 		/// <param name="lua"></param>
-		static void regist(sol::state& lua);
+		static void regist(sol::state* lua);
 	private:
 		std::shared_ptr<soci::session> m_session;
 		//std::shared_ptr<soci::statement> m_st;

+ 2 - 1
src/module/mutex.h

@@ -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;
 	};
 

+ 18 - 20
src/module/mysql.cpp

@@ -98,9 +98,9 @@ uint64 module::select::count()
     return m_select->count();
 }
 
-void module::select::regist(sol::state& lua)
+void module::select::regist(sol::state* lua)
 {
-    lua.new_usertype<module::select>("mysql_builder_select",
+    lua->new_usertype<module::select>("mysql_builder_select",
         "new", sol::constructors<module::select(ylib::mysql::conn*)>(),
         "count", &module::select::count,
         "field", &module::select::field,
@@ -223,9 +223,9 @@ void module::update::clear()
     m_update->clear();
 }
 
-void module::update::regist(sol::state& lua)
+void module::update::regist(sol::state* lua)
 {
-    lua.new_usertype<module::update>("mysql_builder_update",
+    lua->new_usertype<module::update>("mysql_builder_update",
         "new", sol::constructors<module::update(ylib::mysql::conn*)>(),
         "exec", &module::update::exec,
         "limit", &module::update::limit,
@@ -301,9 +301,9 @@ void module::insert::clear()
     m_insert->clear();
 }
 
-void module::insert::regist(sol::state& lua)
+void module::insert::regist(sol::state* lua)
 {
-    lua.new_usertype<module::insert>("mysql_builder_insert",
+    lua->new_usertype<module::insert>("mysql_builder_insert",
         "new", sol::constructors<module::insert(ylib::mysql::conn*)>(),
         "exec", &module::insert::exec,
         "table", &module::insert::table,
@@ -390,9 +390,9 @@ void module::delete_::clear()
     m_delete->clear();
 }
 
-void module::delete_::regist(sol::state& lua)
+void module::delete_::regist(sol::state* lua)
 {
-    lua.new_usertype<module::delete_>("mysql_builder_delete",
+    lua->new_usertype<module::delete_>("mysql_builder_delete",
         "new", sol::constructors<module::delete_(ylib::mysql::conn*)>(),
         "exec", &module::delete_::exec,
         "limit", &module::delete_::limit,
@@ -408,12 +408,12 @@ void module::delete_::regist(sol::state& lua)
     );
 }
 
-void module::mysql_regist(sol::state& lua)
+void module::mysql_regist(sol::state* lua)
 {
-    lua["DESC"] = ylib::sort::DESC;
-    lua["ASC"] = ylib::sort::ASC;
+    (*lua)["DESC"] = ylib::sort::DESC;
+    (*lua)["ASC"] = ylib::sort::ASC;
     
-    lua.new_usertype<ylib::mysql::conn>("mysql_conn",
+    lua->new_usertype<ylib::mysql::conn>("mysql_conn",
         "clear", &ylib::mysql::conn::clear,
         "close", &ylib::mysql::conn::close,
         "commit", &ylib::mysql::conn::commit,
@@ -423,7 +423,7 @@ void module::mysql_regist(sol::state& lua)
         "rollback", &ylib::mysql::conn::rollback,
         "setsql", &ylib::mysql::conn::setsql
     );
-    lua.new_usertype<module::mysql>("mysql_pool",
+    lua->new_usertype<module::mysql>("mysql_pool",
         "new", sol::constructors<module::mysql()>(),
         "start", &module::mysql::start,
         "close", &module::mysql::close,
@@ -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)
 {
 
@@ -591,9 +589,9 @@ sol::table module::mysql_result::table(sol::this_state s)
     return result_table;
 }
 
-void module::mysql_result::regist(sol::state& lua)
+void module::mysql_result::regist(sol::state* lua)
 {
-    lua.new_usertype<module::mysql_result>("mysql_result",
+    lua->new_usertype<module::mysql_result>("mysql_result",
         "field_name", &module::mysql_result::field_name,
         "get", &module::mysql_result::get,
         "next", &module::mysql_result::next,

+ 9 - 8
src/module/mysql.h

@@ -9,7 +9,7 @@ namespace module
 	/// 注册
 	/// </summary>
 	/// <param name="lua"></param>
-	void mysql_regist(sol::state& lua);
+	void mysql_regist(sol::state* lua);
 	/// <summary>
 	/// 结果集
 	/// </summary>
@@ -61,7 +61,7 @@ namespace module
 		/// 注册
 		/// </summary>
 		/// <param name="lua"></param>
-		static void regist(sol::state& lua);
+		static void regist(sol::state* lua);
 	private:
 		ylib::mysql::result* m_result = nullptr;
 	};
@@ -85,7 +85,7 @@ namespace module
 		void clear();
 		std::shared_ptr<module::mysql_result> query();
 		uint64 count();
-		static void regist(sol::state& lua);
+		static void regist(sol::state* lua);
 	private:
 		std::shared_ptr<ylib::select> m_select;
 	};
@@ -109,7 +109,7 @@ namespace module
 		module::update& orderby(const std::string& field, int sort);
 		uint64 exec();
 		void clear();
-		static void regist(sol::state& lua);
+		static void regist(sol::state* lua);
 	private:
 		std::shared_ptr<ylib::update> m_update;
 	};
@@ -125,7 +125,7 @@ namespace module
 		module::insert& set_not_ppst(const std::string& name, const std::string& value);
 		uint64 exec();
 		void clear();
-		static void regist(sol::state& lua);
+		static void regist(sol::state* lua);
 	private:
 		std::shared_ptr<ylib::insert> m_insert;
 	};
@@ -144,7 +144,7 @@ namespace module
 		module::delete_& orderby(const std::string& field, int sort);
 		uint64 exec();
 		void clear();
-		static void regist(sol::state& lua);
+		static void regist(sol::state* lua);
 	private:
 		std::shared_ptr <ylib::delete_> m_delete;
 	};
@@ -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 - 36
src/utils/luautils.cpp

@@ -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"

+ 1 - 7
src/utils/luautils.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);
+
 }

+ 39 - 4
tests/main.cpp

@@ -2,13 +2,48 @@
 #include <iostream>
 #include "core/entry.h"
 #include <filesystem>
+std::string config_filepath;
+bool start()
+{
+	return fastweb_start(config_filepath.c_str()) == 0;
+}
+void close()
+{
+	fastweb_close();
+}
 int main()
 {
-	std::string config_filepath = std::filesystem::current_path().string()+"/config.ini";
-	if (fastweb(config_filepath.c_str()) != 0)
-		return -1;
+	config_filepath = std::filesystem::current_path().string() + "/config.ini";
 
+	std::string input = "restart";
 	while (true)
-		std::cin.get();
+	{
+		if (input == "restart")
+		{
+			std::cout << "closing..." << std::endl;
+			close();
+			std::cout << "starting..." << std::endl;
+			if (start() == false)
+			{
+				std::cin.get();
+				return -1;
+			}
+			std::cout << "started" << std::endl;
+		}
+		else if (input == "quit" || input == "exit")
+		{
+			close();
+			std::cout << "closed";
+			break;
+		}
+		else
+		{
+			std::cout << "Enter \"quit\" or \"exit\" to exit the application" << std::endl;
+			std::cout << "Enter \"restart\"  to restart the application" << std::endl;
+		}
+
+
+		std::cin >> input;
+	}
 	return 0;
 }