Spaces:
Paused
Paused
/* | |
* | |
* @build make examples | |
* @server bin/one-acceptor-multi-workers 1234 | |
* @client bin/nc 127.0.0.1 1234 | |
* nc 127.0.0.1 1234 | |
* telnet 127.0.0.1 1234 | |
*/ | |
static const char *host = "0.0.0.0"; | |
static int port = 8080; | |
static int thread_num = 4; | |
static hloop_t *tcpaccept_loop = NULL, *udpbind_loop = NULL; | |
static void new_conn_event(hevent_t *ev) | |
{ | |
hloop_t *loop = ev->loop; | |
hio_t *io = (hio_t *)hevent_userdata(ev); | |
hio_attach(loop, io); | |
tcp_on_accept(io, ev); | |
} | |
static void on_accept(hio_t *io) | |
{ | |
hio_detach(io); | |
hloop_t *worker_loop = get_next_loop(); | |
hevent_t ev; | |
memset(&ev, 0, sizeof(ev)); | |
ev.loop = worker_loop; | |
ev.cb = new_conn_event; | |
ev.userdata = io; | |
hloop_post_event(worker_loop, &ev); | |
} | |
static HTHREAD_RETTYPE worker_thread(void *userdata) | |
{ | |
hloop_t *loop = (hloop_t *)userdata; | |
hloop_run(loop); | |
return 0; | |
} | |
static HTHREAD_RETTYPE tcpaccept_thread(void *userdata) | |
{ | |
hloop_t *loop = (hloop_t *)userdata; | |
hio_t *listenio = hloop_create_tcp_server(loop, host, port, on_accept); | |
if (listenio == NULL) | |
{ | |
exit(1); | |
} | |
int listeniofd = hio_fd(listenio); | |
hloop_run(loop); | |
close(listeniofd); | |
return 0; | |
} | |
static HTHREAD_RETTYPE udpbind_thread(void *userdata) | |
{ | |
hloop_t *loop = (hloop_t *)userdata; | |
hio_t *bindio = hloop_create_udp_server(loop, host, port); | |
if (bindio == NULL) | |
{ | |
exit(1); | |
} | |
int bindfd = hio_fd(bindio); | |
spdlog::info("ProxyServer start: udp->{}", port); | |
hevent_set_userdata(bindio, loop); //必须 | |
hio_setcb_read(bindio, udp_on_recvfrom); | |
hio_setcb_write(bindio, udp_on_writed); | |
hio_setcb_close(bindio, udp_on_close); | |
hio_read(bindio); | |
hloop_run(loop); | |
close(bindfd); | |
return 0; | |
} | |
int main(int argc, char **argv) | |
{ | |
int type = 0; | |
if (argc == 3) | |
{ | |
type = atoi(argv[1]); | |
port = atoi(argv[2]); | |
} | |
int cores = std::thread::hardware_concurrency(); | |
if (cores > 0) | |
{ | |
thread_num = cores; | |
} | |
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>(); | |
auto logger = std::make_shared<spdlog::logger>("my_logger", console_sink); | |
// 设置异步模式,设置线程数(0 表示使用 CPU 核心数) | |
spdlog::init_thread_pool(8192, thread_num); | |
// 设置异步日志器 | |
spdlog::set_default_logger(std::make_shared<spdlog::async_logger>( | |
"ProxyServer", console_sink, spdlog::thread_pool(), spdlog::async_overflow_policy::block)); | |
spdlog::info("ProxyServer start: threadNum:{:d}", thread_num); | |
if (type == 1) | |
{ | |
// Udp | |
udpbind_loop = hloop_new(HLOOP_FLAG_AUTO_FREE); | |
udpbind_thread(udpbind_loop); | |
} | |
else | |
{ | |
// Tcp | |
init_loop(thread_num, worker_thread); | |
spdlog::info("ProxyServer start: tcp->{}", port); | |
tcpaccept_loop = hloop_new(HLOOP_FLAG_AUTO_FREE); | |
tcpaccept_thread(tcpaccept_loop); | |
} | |
return 0; | |
} | |