#include "base/log.h" #include "boost/asio.hpp" #include "boost/asio/executor_work_guard.hpp" #include "boost/asio/io_context.hpp" #include "boost/chrono/duration.hpp" #include "boost/contract.hpp" #include "boost/foreach.hpp" #include "boost/range.hpp" #include "boost/thread.hpp" using namespace boost; bool initLog() { spdlog::set_pattern("%Y-%m-%d %H:%M:%S.%f%z [%^%L%$] [thread %t] %v"); return true; } class RedisServer { public: RedisServer(asio::ip::tcp::endpoint ep = asio::ip::tcp::endpoint(asio::ip::tcp::v4(), 6379), int io_thread_num = 2) : _io_context(), _io_context_guard(asio::make_work_guard(_io_context)), _io_threads(), _acceptor(_io_context, ep) { for (int i = 1; i <= io_thread_num; ++i) { _io_threads.create_thread(boost::bind(&asio::io_context::run, &_io_context)); } } bool running() const { return true; } bool startServer() { LOGI("Listen {}:{}", _acceptor.local_endpoint().address().to_string(), _acceptor.local_endpoint().port()); startAccept(); return true; } private: void startAccept() { _acceptor.async_accept([this](const system::error_code &ec, asio::ip::tcp::socket new_socket) { if (!ec) { auto remote_ep = new_socket.remote_endpoint(); LOGI("Connected to Server, From {}:{}", remote_ep.address().to_string(), remote_ep.port()); } else { LOGE("Accept failed. reason={}", ec.message()); } startAccept(); }); } private: asio::io_context _io_context; asio::executor_work_guard _io_context_guard; thread_group _io_threads; // for accept asio::ip::tcp::acceptor _acceptor; }; int main(int argc, char *argv[]) { BOOST_CONTRACT_ASSERT(initLog()); RedisServer redisServer; redisServer.startServer(); while (redisServer.running()) { boost::this_thread::sleep_for(boost::chrono::milliseconds(100)); } return 0; }