17 short events = POLLIN | (conn.hasPendingWrite() ? POLLOUT : 0);
18 _pollFds.push_back({conn.fd(), events, 0});
29 if (ret < 0 && errno == EINTR)
return {};
30 if (ret < 0)
throw std::runtime_error(std::string(
"poll() failed: ") + strerror(errno));
43 _connections.emplace(std::piecewise_construct, std::forward_as_tuple(
id),
44 std::forward_as_tuple(fd));
46 for (
auto* obs :
_observers) obs->onClientConnected(
id);
51 if (!pfd.revents)
return;
56 if (pfd.revents & POLLIN) {
58 ssize_t
n = ::recv(pfd.fd, buf,
sizeof(buf), 0);
63 conn.appendRead({buf,
static_cast<size_t>(
n)});
64 while (
auto line = conn.nextLine()) {
65 for (
auto* obs :
_observers) obs->onLineReceived(
id, *line);
66 result.
lines.emplace_back(
id, std::move(*line));
69 if (pfd.revents & (POLLHUP | POLLERR)) {
73 if (pfd.revents & POLLOUT) conn.flushWrite();
79 if (it !=
_connections.end()) it->second.queueWrite(msg);
80 for (
auto* obs :
_observers) obs->onLineSent(connectionId, msg);
87 it->second.flushWrite();
89 for (
auto* obs :
_observers) obs->onClientDisconnected(connectionId);
96 throw std::out_of_range(
"ClientManager::getConnection: unknown id");
static std::string id(int n)
static std::string n(int v)
void send(int connectionId, const std::string &msg)
Queue msg to be sent to a client (flushed during poll()).
std::unordered_map< int, Connection > _connections
void _acceptNew(PollResult &result)
Connection & getConnection(int connectionId)
Access the underlying Connection (e.g. to set its type/playerId).
void disconnect(int connectionId)
Close a client and drop its connection.
std::vector< INetworkObserver * > _observers
void _handleEvents(const pollfd &pfd, PollResult &result)
std::vector< pollfd > _pollFds
PollResult poll(int timeoutMs)
Run one poll cycle (blocks up to timeoutMs); returns this cycle's events.
std::unordered_map< int, int > _fdToId
ClientManager(Listener &listener)
void addNetworkObserver(INetworkObserver *observer)
Subscribe an observer to connect/disconnect/line events.
One client socket plus its read/write buffers.
Observer hooks for raw socket events (Observer pattern).
The server's listening socket.
int fd() const
The listening socket fd (to register in poll()).
int accept() const
Accept one pending client; returns its new socket fd.
std::vector< int > disconnectedIds
std::vector< int > newConnections
std::vector< std::pair< int, std::string > > lines