{"id":15660503,"url":"https://github.com/owent/libatapp","last_synced_at":"2025-04-15T17:47:14.700Z","repository":{"id":5748855,"uuid":"53823017","full_name":"owent/libatapp","owner":"owent","description":"server app framework based on libatbus","archived":false,"fork":false,"pushed_at":"2024-10-29T02:40:25.000Z","size":1375,"stargazers_count":21,"open_issues_count":0,"forks_count":12,"subscribers_count":5,"default_branch":"main","last_synced_at":"2024-10-30T03:00:03.321Z","etag":null,"topics":["app","cpp","cxx","distributed-systems","framework","gcc","gitter","linux","macos","osx","performance","server","windows"],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/owent.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-03-14T03:08:37.000Z","updated_at":"2024-10-29T02:24:17.000Z","dependencies_parsed_at":"2023-02-14T16:31:13.347Z","dependency_job_id":"90d37855-d40e-4086-aaf3-2c6d487271c8","html_url":"https://github.com/owent/libatapp","commit_stats":{"total_commits":377,"total_committers":4,"mean_commits":94.25,"dds":0.3687002652519894,"last_synced_commit":"aa1dd64a2383956690bd4740f991d4a48c464cec"},"previous_names":["owent/libatapp"],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/owent%2Flibatapp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/owent%2Flibatapp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/owent%2Flibatapp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/owent%2Flibatapp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/owent","download_url":"https://codeload.github.com/owent/libatapp/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249124563,"owners_count":21216689,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["app","cpp","cxx","distributed-systems","framework","gcc","gitter","linux","macos","osx","performance","server","windows"],"created_at":"2024-10-03T13:22:03.437Z","updated_at":"2025-04-15T17:47:14.687Z","avatar_url":"https://github.com/owent.png","language":"C++","readme":"# libatapp\r\n\r\n用于搭建高性能、全异步(a)的跨平台应用框架库。\r\n\r\n[![ci-badge]][ci-link]\r\n\r\n[ci-badge]: https://github.com/atframework/libatapp/actions/workflows/main.yml/badge.svg \"Github action build status\"\r\n[ci-link]:  https://github.com/atframework/libatapp/actions/workflows/main.yml \"Github action build status\"\r\n\r\n## CI Job Matrix\r\n\r\n| Target System | Toolchain          | Note                  |\r\n| ------------- | ------------------ | --------------------- |\r\n| Linux         | GCC                |\r\n| Linux         | Clang              | With libc++           |\r\n| Linux         | GCC 4.8            |\r\n| MinGW64       | GCC                | Dynamic linking       |\r\n| Windows       | Visual Studio 2022 | Dynamic linking       |\r\n| Windows       | Visual Studio 2022 | Static linking        |\r\n| Windows       | Visual Studio 2019 | Static linking        |\r\n| macOS         | AppleClang         | With libc++           |\r\n\r\n## 依赖\r\n\r\n+ 支持c++0x或c++11的编译器(为了代码尽量简洁,特别是少做无意义的平台兼容，依赖部分 C11和C++11的功能，所以不支持过低版本的编译器)\r\n  \u003e + GCC: 4.8 及以上\r\n  \u003e + Clang: 7 及以上\r\n  \u003e + VC: VS2019 及以上\r\n\r\n+ [cmake](https://cmake.org/download/) 3.24.0 以上\r\n\r\n## GET START\r\n\r\n### 最小化服务器\r\n\r\n```cpp\r\n#include \u003ccstdio\u003e\r\n#include \u003ccstdlib\u003e\r\n#include \u003ccstring\u003e\r\n#include \u003ciostream\u003e\r\n#include \u003cvector\u003e\r\n\r\n#include \u003cuv.h\u003e\r\n\r\n#include \u003catframe/atapp.h\u003e\r\n#include \u003ccommon/file_system.h\u003e\r\n\r\nstatic int app_handle_on_msg(atapp::app \u0026app, const atapp::app::message_sender_t\u0026 source, const atapp::app::message_t \u0026msg) {\r\n    std::string data;\r\n    data.assign(reinterpret_cast\u003cconst char *\u003e(msg.data), msg.data_size);\r\n    FWLOGINFO(\"receive a message(from {:#x}, type={}) {}\", source.id, msg.type, data);\r\n\r\n    return app.get_bus_node()-\u003esend_data(source.id, msg.type, msg.data, msg.data_size);\r\n}\r\n\r\nstatic int app_handle_on_response(atapp::app \u0026 app, const atapp::app::message_sender_t\u0026 source, const atapp::app::message_t \u0026 msg, int32_t error_code) {\r\n    if (error_code \u003c 0) {\r\n        FWLOGERROR(\"send data from {:#x} to {:#x} failed, sequence: {}, code: {}\", app.get_id(), source.id, msg.msg_sequence, error_code);\r\n    } else {\r\n        FWLOGDEBUG(\"send data from {:#x} to {:#x} got response, sequence: {}\", app.get_id(), source.id, msg.msg_sequence);\r\n    }\r\n    return 0;\r\n}\r\n\r\nint main(int argc, char *argv[]) {\r\n    atapp::app app;\r\n\r\n    // 设置工程目录，不设置的话日志打印出来都是绝对路劲，比较长\r\n    {\r\n        std::string proj_dir;\r\n        atfw::util::file_system::dirname(__FILE__, 0, proj_dir, 2); // 设置当前源文件的2级父目录为工程目录\r\n        atfw::util::log::log_formatter::set_project_directory(proj_dir.c_str(), proj_dir.size());\r\n    }\r\n\r\n    // setup handle\r\n    app.set_evt_on_forward_request(app_handle_on_msg);         // 注册接收到数据后的回调\r\n    app.set_evt_on_forward_response(app_handle_on_response);   // 注册发送消息失败的回调\r\n\r\n    // run with default loop in libuv\r\n    return app.run(uv_default_loop(), argc, (const char **)argv, nullptr);\r\n}\r\n```\r\n\r\n### 设置自定义命令行参数\r\n\r\n```cpp\r\n// ...\r\n\r\n#include \u003csstream\u003e\r\n\r\nstatic int app_option_handler_echo(atfw::util::cli::callback_param params) {\r\n    // 获取参数并输出到stdout\r\n    std::stringstream ss;\r\n    for (size_t i = 0; i \u003c params.get_params_number(); ++i) {\r\n        ss \u003c\u003c \" \" \u003c\u003c params[i]-\u003eto_cpp_string();\r\n    }\r\n\r\n    std::cout \u003c\u003c \"echo option: \" \u003c\u003c ss.str() \u003c\u003c std::endl;\r\n    return 0;\r\n}\r\n\r\nint main(int argc, char *argv[]) {\r\n    atapp::app app;\r\n    // ...\r\n    // setup options, 自定义命令行参数是区分大小写的\r\n    atfw::util::cli::cmd_option::ptr_type opt_mgr = app.get_option_manager();\r\n    // show help and exit\r\n    opt_mgr-\u003ebind_cmd(\"-echo\", app_option_handler_echo)   // 当启动参数里带-echo时跳转进 app_option_handler_echo 函数\r\n        -\u003eset_help_msg(\"-echo [text]                           echo a message.\"); // 帮助文本，--help时显示，不执行这个就没有帮助信息\r\n\r\n    // ...\r\n    // run\r\n    return app.run(uv_default_loop(), argc, (const char **)argv, nullptr);\r\n}\r\n```\r\n\r\n### 设置自定义远程命令\r\n\r\n```cpp\r\n// ...\r\n#include \u003csstream\u003e\r\n\r\nstatic int app_command_handler_echo(atfw::util::cli::callback_param params) {\r\n    std::stringstream ss;\r\n    for (size_t i = 0; i \u003c params.get_params_number(); ++i) {\r\n        ss \u003c\u003c \" \" \u003c\u003c params[i]-\u003eto_cpp_string();\r\n    }\r\n\r\n    WLOGINFO(\"echo commander:%s\", ss.str().c_str());\r\n    return 0;\r\n}\r\n\r\nint main(int argc, char *argv[]) {\r\n    atapp::app app;\r\n    // ... \r\n    // setup cmd, 自定义远程命令是不区分大小写的\r\n    atfw::util::cli::cmd_option_ci::ptr_type cmgr = app.get_command_manager();\r\n    cmgr-\u003ebind_cmd(\"echo\", app_command_handler_echo)\r\n        -\u003eset_help_msg(\"echo       [messages...]                                    echo messages to log\");\r\n\r\n    // 然后就可以通过 [EXECUTABLE] -id ID --conf CONFIGURE_FILE run echo MESSAGES ... 来发送命令到正在运行的服务器进程了\r\n    // ...\r\n\r\n    // run\r\n    return app.run(uv_default_loop(), argc, (const char **)argv, nullptr);\r\n}\r\n```\r\n\r\n### 自定义模块\r\n\r\n```cpp\r\n// ...\r\n\r\n// 自定义模块必需继承自atapp::module_impl\r\nclass echo_module : public atapp::module_impl {\r\npublic:\r\n    virtual int init() {\r\n        // 初始化时调用，整个app的生命周期只会调用一次\r\n        // 初始化时这个调用再reload只会，这样保证再init的时候配置时可用的\r\n        WLOGINFO(\"echo module init\");\r\n        return 0;\r\n    };\r\n\r\n    virtual int reload() {\r\n        // 重新加载配置时调用\r\n        WLOGINFO(\"echo module reload\");\r\n        return 0;\r\n    }\r\n\r\n    virtual int stop() {\r\n        // app即将停止时调用，返回非0值表示需要异步回收数据，这时候等回收完成后需要手动再次调用atapp的stop函数\r\n        WLOGINFO(\"echo module stop\");\r\n        return 0;\r\n    }\r\n\r\n    virtual int timeout() {\r\n        // stop超时后调用，这个返回以后这个模块会被强制关闭\r\n        WLOGINFO(\"echo module timeout\");\r\n        return 0;\r\n    }\r\n\r\n    virtual const char *name() const { \r\n        // 返回模块名，如果不重载会尝试使用C++ RTTI特性判定，但是RTTI生成的符号名称可能不是很易读\r\n        return \"echo_module\"; \r\n    }\r\n\r\n    virtual int tick() {\r\n        // 每次tick的时候调用，tick间隔由配置文件指定，返回成功执行的任务数\r\n        time_t cur_print = atfw::util::time::time_utility::get_sys_now() / 20;\r\n        static time_t print_per_sec = cur_print;\r\n        if (print_per_sec != cur_print) {\r\n            WLOGINFO(\"echo module tick\");\r\n            print_per_sec = cur_print;\r\n        }\r\n\r\n        // 返回值大于0时，atapp会认为模块正忙，会很快再次调用tick\r\n        // 这样可以阻止atapp进入sleep\r\n        return 0;\r\n    }\r\n};\r\n\r\nint main(int argc, char *argv[]) {\r\n    atapp::app app;\r\n    // ... \r\n    // setup module, 自定义模块必需是shared_ptr\r\n    app.add_module(std::make_shared\u003cecho_module\u003e());\r\n    // ...\r\n\r\n    // run\r\n    return app.run(uv_default_loop(), argc, (const char **)argv, nullptr);\r\n}\r\n```\r\n\r\n**更多的细节请参照 [sample](sample)**\r\n","funding_links":[],"categories":["C++"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fowent%2Flibatapp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fowent%2Flibatapp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fowent%2Flibatapp/lists"}