Temos usado o excelente cpp-httlib para fazer solicitações REST. Agora gostaríamos de usá-lo para um servidor. Bem no topo da documentação está:
Importante
Esta biblioteca usa E/S de soquete 'bloqueantes'. Se você está procurando uma biblioteca com E/S de soquete 'não bloqueadoras', esta não é a que você quer.
Não tenho certeza do que isso significa em um sentido prático, pois, embora eu entenda os princípios básicos de IP/UDP/TCP etc., não estou familiarizado com programação de socket. Testei o servidor disparando várias solicitações para ele, por exemplo, se a primeira solicitação for implementada dormindo por 30s, uma segunda solicitação "hello world" ainda retorna imediatamente.
Depurando o código, vejo que o thread principal é executado:
while (svr_sock_ != INVALID_SOCKET) {
// socket operations
if (!task_queue->enqueue(
[this, sock]() { process_and_close_socket(sock); })) {
detail::shutdown_socket(sock);
detail::close_socket(sock);
}
}
Os threads de trabalho são executados
for (;;) {
std::function<void()> fn;
{
// Lock / wait for new request
fn = pool_.jobs_.front();
pool_.jobs_.pop_front();
}
fn();
}
ou seja, o thread principal é como um loop de eventos em um aplicativo GUI, recebendo cada solicitação recebida, mas em vez de executar a solicitação em si, ele a coloca em uma fila para que os threads de trabalho a peguem.
Anteriormente eu estava encerrando chamadas para C++ em um servidor web Python FastAPI, o que é bom, mas executar Python e C++ claramente adiciona sobrecarga/complexidade, e não é totalmente simples entender como as solicitações são executadas em relação ao bloqueio global do interpretador. A abordagem direta do C++ usando cpp-httlib parece muito melhor, mas o comentário sobre 'bloquear' E/S de socket me preocupa. O que estou perdendo ao não usar E/S de socket não bloqueantes?
(O servidor será construído para Windows e Linux; no entanto, a produção será Linux.)