userver: samples/tcp_service/tcp_service.cpp
Loading...
Searching...
No Matches
samples/tcp_service/tcp_service.cpp
namespace samples::tcp {
class Hello final : public components::TcpAcceptorBase {
public:
static constexpr std::string_view kName = "tcp-hello";
// Component is valid after construction and is able to accept requests
Hello(const components::ComponentConfig& config,
: TcpAcceptorBase(config, context),
greeting_(config["greeting"].As<std::string>("hi")) {}
void ProcessSocket(engine::io::Socket&& sock) override;
static yaml_config::Schema GetStaticConfigSchema();
private:
const std::string greeting_;
};
} // namespace samples::tcp
namespace samples::tcp {
void Hello::ProcessSocket(engine::io::Socket&& sock) {
std::string data;
data.resize(2);
const auto read_bytes = sock.ReadAll(data.data(), 2, {});
if (read_bytes != 2 || data != "hi") {
sock.Close();
return;
}
const auto sent_bytes =
sock.SendAll(greeting_.data(), greeting_.size(), {});
if (sent_bytes != greeting_.size()) {
return;
}
}
}
yaml_config::Schema Hello::GetStaticConfigSchema() {
return yaml_config::MergeSchemas<TcpAcceptorBase>(R"(
type: object
description: |
Component for accepting incoming TCP connections and responding with some
greeting as long as the client sends 'hi'.
additionalProperties: false
properties:
greeting:
type: string
description: greeting to send to client
defaultDescription: hi
)");
}
} // namespace samples::tcp
int main(int argc, const char* const argv[]) {
const auto component_list =
components::MinimalComponentList().Append<samples::tcp::Hello>();
return utils::DaemonMain(argc, argv, component_list);
}