{"id":22441482,"url":"https://github.com/mastprogs/none_boost_asio","last_synced_at":"2025-03-27T10:15:25.465Z","repository":{"id":42159821,"uuid":"266949853","full_name":"MastProgs/None_boost_Asio","owner":"MastProgs","description":"boost 라이브러리를 사용하지 않은 asio. 먼 미래에 module 정상적으로 지원할 때 싹 개편할래","archived":false,"fork":false,"pushed_at":"2023-07-05T01:55:28.000Z","size":24239,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-01T14:45:42.035Z","etag":null,"topics":["asio","coroutine","cpp20"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MastProgs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2020-05-26T05:10:22.000Z","updated_at":"2025-01-21T17:45:24.000Z","dependencies_parsed_at":"2025-02-01T14:43:30.690Z","dependency_job_id":"a4392992-0c8f-4080-84a5-f119f5a4b815","html_url":"https://github.com/MastProgs/None_boost_Asio","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MastProgs%2FNone_boost_Asio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MastProgs%2FNone_boost_Asio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MastProgs%2FNone_boost_Asio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MastProgs%2FNone_boost_Asio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MastProgs","download_url":"https://codeload.github.com/MastProgs/None_boost_Asio/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245823316,"owners_count":20678173,"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":["asio","coroutine","cpp20"],"created_at":"2024-12-06T02:14:40.728Z","updated_at":"2025-03-27T10:15:25.437Z","avatar_url":"https://github.com/MastProgs.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# C++20 Asio Server\n\n## 서론\nboost 라이브러리를 사용하지 않은 단일 asio 서버 통신 라이브러리에, C++20 베이스의 코어 서버이며, 실무에서 직접 구현한 코드들을 테스트하고 검증한 구조와 알고리즘 위주로 작성.\n필요한 경우 오픈소스를 활용하여 작성된 경우가 있고, 각 오픈소스는 소스코드의 github 주소들이 존재.\n\n## 환경설정\n* Visual Studio 2022\n* C++20\n\n## 오픈소스\n* cpp_redis ( https://github.com/cpp-redis/cpp_redis )\n  * thread safe ( using mutex )\n  * can be async ( using future )\n* nlohmann json ( https://github.com/nlohmann/json )\n* httplib ( https://github.com/yhirose/cpp-httplib )\n  * blocking\n* better enums ( https://github.com/aantron/better-enums )\n\n## 코드 설명\n\n### Core\n대부분의 핵심 기능들은 여기에 구현하여 가져다 쓰는중\n\n#### [Asio](https://github.com/MastProgs/None_boost_Asio/tree/master/C%2B%2B20%20Asio/CoroutineAsioCpp20/Core/Asio)\n* asio 을 기반으로 네트워크 통신의 가장 핵심적인 역할을 담당\n* boost 문법을 제거하고, std 표준 문법으로 재작성\n* asyncronous\n* thread safe\n\n##### AsioServer\n* Singleton\n* io_context 객체를 직접 다루는 핸들러\n* 기본적인 IOCP 함수들 같은 IO 서비스를 담당\n* Post 함수를 통한 비통기 처리 가능\n* Acceptor Handling ( listen control )\n* Thread list control\n\n##### AsioAcceptor\n* need shared pointer\n* need io_context reference\n* 접속한 클라이언트를 핸들링\n  * async_accept 수행을 동한 AsioClient handling\n* Acceptor 상속을 통한, 다양한 연결 지원\n* 하나의 io_context 에서 여러 Acceptor 를 활용하려면, 상위 AsioServer 가 핸들링 해주는것을 상정하여 구조를 설계\n* 다른 io_context 별 컨트롤이 필요하다면, AsioServer 를 따로 만들어서 handling 해주는 것을 추천\n\n##### AsioClient\n* Winsock 의 SOCKET 객체와 같은 기본적인 Send Recv 를 지원하는 클라이언트 객체\n* Send Recv 는 asyncronous\n* 데이터의 input param 값은 string_view 객체이나, 데이터를 강제 캐스팅 하여 string 버퍼에 담아주는 형태에 불과\n* Packet delimiter 를 통한 데이터 끝을 구분하는 구조라 클라이언트 측에서도 Packet delimiter 가 같아야 함\n  * 다른 커스텀이 필요하다면, Send Recv 부분을 다른 형태로 커스텀하여 사용 가능\n  * asio 의 write, read 함수는 다양한 형식을 지원\n* Acceptor 에서 어떠한 Client 형태로 랩핑할지를 결정\n\n#### [Coroutine](https://github.com/MastProgs/None_boost_Asio/tree/master/C%2B%2B20%20Asio/CoroutineAsioCpp20/Core/Coroutine)\n코루틴을 통해 더 효율적인 비동기 처리를 할 수 있으며, C++20 이 지원이 되어야 정상적으로 처리 가능\n\n* Task 객체를 통해 함수에서 스위칭 되는 시점의 상태 값을 Task 객체로 받음\n  * RTask\n    * Return task 의 의미\n    * 함수로 부터 결과값을 co_yield, co_return 받아야 하는 경우 쓰는 객체\n    * 템플릿을 통해 value 값이 임시 저장됨\n    * 복사 생성을 추천\n    * reference 및 pointer 같은 값은 추천하지 않음 ( 원본 객체가 살아있을 보장이 없음 )\n  * VTask\n    * Void task 의 의미\n    * 특별히 결과값을 받을 필요 없을때 사용\n* coroutine handle 을 기본적으로 가지고 있으며, suspend 가 수행 될 때마다, AsioContext Post 함수로 수행을 넘겨줌\n* AwaitPost 를 통해 handle\n```c++\n// coroutine 은 아래와 같은 형태로 사용 가능\nVTask Logger::StoreDB(std::string_view log)\n{\n    /* ... */\n    DB.Send(log);\n    co_await AwaitPost{};\n    auto result = DB.Recv();\n    /* ... */\n}\n```\n\n#### [Logger](https://github.com/MastProgs/None_boost_Asio/tree/master/C%2B%2B20%20Asio/CoroutineAsioCpp20/Core/Logger)\n로그 관련 처리를 하기 위한 클래스. 기본적으로 std::format 을 사용하므로, C++17 이상 필요. Better Enums 오픈소스를 활용중\n\n##### LogManager\n에러 로그 정보들을 사전에 map 구조의 error number, detail info 로 가지고 있고, 에러가 발생하는 시점에 관련 에러코드를 이 LogManager 에서 찾아서 활용\n\n* Singleton\n* not thread safe\n  * 서버 초기화 시점에 error log 정보를 추가하는 것을 추천\n  * 서버가 올라간 상황에서는 std::mutex m_lock 을 통해 접근 관리를 해주어야 함\n* Logger 클래스에서만 접근하여 관련 정보를 참조로 불러옴\n\n##### Logger\n실질적으로 log 내용을 작성하는 객체, file out 이나 DB store 작업이 필요하다면, print 함수에서 커스텀 시켜주면 된다. 기본은 std::cout 으로 cmd 창 출력\n\n* Singleton\n* not thread safe\n\n#### [Redis](https://github.com/MastProgs/None_boost_Asio/tree/master/C%2B%2B20%20Asio/CoroutineAsioCpp20/Core/Redis)\ncpp_redis 오픈소스를 랩핑하여 활용한 Redis 객체, 다양한 범위 연산을 하기위해 ranges 를 활용하기에 C++20 필요.\n\n##### RedisManager\ncpp_redis 클라이언트 객체를 관리하고 처리하는 클래스. cpp_redis 자체가 비동기 지원을 하며, thread safe.\n\n* Singleton\n* Sentinal 형태로 사용하는 경우, vector 를 통해 미리 각 redis index 를 select 해두고 활용하는 구조\n  * GetIndex 로 컨텐츠에 해당하는 redis index 를 select 한 cpp_redis::client 객체를 가져오고 GetRedis 를 통해 객체를 reference 로 전달\n* not thread safe\n  * 최초 서버 시점에 초기화를 진행해주고, 그 이후에 만든 객체를 통해서만 활용하는 것으로 설계\n\n##### RedisCommand\n이 객체는 redis 명령어에만 관여하며, 실질적으로 명령어 생성 \u0026 구조 변경을 하여 cpp_redis::client 객체에 전달하는 역할\n\n* need cpp_redis::client\n* key hash 구분자를 ':' 를 사용\n  * SetKey 함수를 통해 다양한 hash key 를 자동으로 처리\n* param value 들을 추가로 넣어주어서 사용\n\n```c++\nRedis::Zadd zadd { RedisContentsType::MAX };\nzadd.SetKey(\"User\", 326, \"th\"); // key = \"User:326:th\"\nzadd.SetParams(10);\nzadd.Run();  // final command = ZADD User:326:th 10\n```\n\n##### RedisResult\nRedisCommand 객체를 통해서 실행한 결과가 cpp_redis::reply 객체로 반환되는데, 이 reply 객체를 랩핑하여 데이터를 훨씬 쉽고 간편하게 다루기 위한 클래스\n\n* 단일 데이터를 받는다면 GetString(), GetNumber() 를 통해 결과를 받을 수 있음\n* IsError(), IsNull() 을 통해 결과의 에러 여부 확인 가능\n* Value Score 형태의 리스트로 반환을 받아와야 하는 경우 GetResult\u003c\u003e() 활용 가능\n  * 템플릿에서 변환하고자 하는 형태의 데이터를 입력하면, 캐스팅 시켜줌\n  * 지원 가능한 형변환\n    * std::string\n    * long long\n    * int\n    * std::vector\u003cstd::string\u003e\n    * std::vector\u003clong long\u003e\n    * std::vector\u003cint\u003e\n    * std::vector\u003cstd::pair\u003cstd::string, std::string\u003e\u003e\n    * std::vector\u003cstd::pair\u003cstd::string, long long\u003e\u003e\n    * std::vector\u003cstd::pair\u003clong long, std::string\u003e\u003e\n    * std::vector\u003cstd::pair\u003clong long, long long\u003e\u003e\n    * std::vector\u003cstd::pair\u003cstd::string, int\u003e\u003e\n    * std::vector\u003cstd::pair\u003cint, std::string\u003e\u003e\n    * std::vector\u003cstd::pair\u003cint, int\u003e\u003e \n\n```c++\nRedis::ZRevRank zrevrank{ RedisContentsType::MAX }; \n/* ... */\n\nzrevrank.SetWithScores();\nzrevrank.Run();\n \nauto userRankList = zrevrank.GetResult\u003cstd::vector\u003cstd::pair\u003cstd::string, long long\u003e\u003e\u003e();\nfor ( const auto\u0026 iter : userRankList )\n{\n   const auto\u0026 name = iter.first;\n   const auto\u0026 rank = iter.second; \n}\n```\n \n### [Common](https://github.com/MastProgs/None_boost_Asio/tree/master/C%2B%2B20%20Asio/CoroutineAsioCpp20/Common)\n공통적으로 자주 활용하게 되는 코드의 경우 여기에 구현\n\n* Datetime\n  * 시간 관련 다루는 객체\n* Enum\n  * 공통으로 쓰이는 enum 정의\n* Random\n  * std random engine 을 활용한 랜덤 함수\n* String\n  * std::vformat 함수를 한 번 더 랩핑\n  * ToStr 을 통해 다양한 문자열 형태 변환\n    * Unicode \u003c-\u003e Multibytes\n    * std::string \u003c-\u003e std::wstring \n \n### [OpenSource](https://github.com/MastProgs/None_boost_Asio/tree/master/C%2B%2B20%20Asio/CoroutineAsioCpp20/OpenSource)\n대부분 오픈 소스들을 가져와 활용하게 되는 곳\n \n* Dump\n  * StackWalker\n    * 이 소스를 통해서 크래시 났을 경우, call stack 들을 출력 가능\n    * 상속받아서, 파일 입출력 형태로도 활용 가능\n  * ExceptionHandler\n    * Minidump 파일 (.dmp) 를 남기는 코드\n* httplib\n* json\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmastprogs%2Fnone_boost_asio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmastprogs%2Fnone_boost_asio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmastprogs%2Fnone_boost_asio/lists"}