1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| #include "common.hpp" #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <vector> #include <unordered_map>
class AsyncServer { public: AsyncServer(int port) : port_(port), listen_fd_(-1) {}
void SetConnectCallback(ConnectCallback cb) { conn_cb_ = cb; } void SetMessageCallback(MessageCallback cb) { msg_cb_ = cb; }
void Start() { listen_fd_ = socket(AF_INET, SOCK_STREAM, 0); sockaddr_in addr{AF_INET, htons(port_), INADDR_ANY};
bind(listen_fd_, (sockaddr *)&addr, sizeof(addr)); listen(listen_fd_, 128);
while (true) { sockaddr_in client_addr; socklen_t len = sizeof(client_addr); int client_fd = accept(listen_fd_, (sockaddr *)&client_addr, &len); std::cout << "accept client = " << client_fd << std::endl; if (client_fd > 0) { if (conn_cb_) conn_cb_(client_fd);
contexts_[client_fd] = {client_fd, nullptr, [this](int fd, const std::string &msg) { if (msg_cb_) msg_cb_(fd, msg); }};
std::thread([this, client_fd]() { char buf[1024]; while(true) { ssize_t len = recv(client_fd, buf, sizeof(buf), 0); if(len > 0) { contexts_[client_fd].on_message(client_fd, std::string(buf, len)); send(client_fd, buf, len, 0); } else break; } close(client_fd); }) .detach(); } } }
private: int port_, listen_fd_; std::unordered_map<int, EventContext> contexts_; ConnectCallback conn_cb_; MessageCallback msg_cb_; };
|