blob: c13e4de4465a77bba4979a69de72f8fe8bb62a34 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <fidl/fuchsia.examples/cpp/wire.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/sys/component/llcpp/handlers.h>
#include <lib/sys/component/llcpp/outgoing_directory.h>
#include <iostream>
// An implementation of the Echo protocol. Protocols are implemented in LLCPP by
// creating a subclass of the ::Interface class for the protocol.
class EchoImpl final : public fidl::WireServer<fuchsia_examples::Echo> {
public:
// Bind this implementation to a channel.
EchoImpl(bool reverse, async_dispatcher_t* dispatcher,
fidl::ServerEnd<fuchsia_examples::Echo> request)
: reverse_(reverse),
binding_(fidl::BindServer(dispatcher, std::move(request), this,
// This is a fidl::OnUnboundFn<EchoImpl>.
[this](EchoImpl* impl, fidl::UnbindInfo info,
fidl::ServerEnd<fuchsia_examples::Echo> server_end) {
if (info.is_peer_closed()) {
std::cout << "Client disconnected" << std::endl;
} else if (!info.is_user_initiated()) {
std::cerr << "server error: " << info << std::endl;
}
delete this;
})) {}
// Handle a SendString request by sending on OnString event with the request value. For
// fire and forget methods, the completer can be used to close the channel with an epitaph.
void SendString(SendStringRequestView request, SendStringCompleter::Sync& completer) override {}
// Handle an EchoString request by responding with the request value. For two-way
// methods, the completer is also used to send a response.
void EchoString(EchoStringRequestView request, EchoStringCompleter::Sync& completer) override {
std::string value(request->value.get());
std::cout << "Got echo request: " << value << std::endl;
if (reverse_) {
std::reverse(value.begin(), value.end());
}
std::cout << "Sending response: " << value << std::endl;
auto reply = fidl::StringView::FromExternal(value);
completer.Reply(reply);
}
private:
const bool reverse_;
fidl::ServerBindingRef<fuchsia_examples::Echo> binding_;
};
int main(int argc, const char** argv) {
async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
auto outgoing = component::OutgoingDirectory::Create(loop.dispatcher());
component::ServiceHandler handler;
fuchsia_examples::EchoService::Handler my_service(&handler);
// Example of serving members of a service instance.
auto add_regular_result = my_service.add_regular_echo(
[&loop](fidl::ServerEnd<fuchsia_examples::Echo> request_channel) -> void {
new EchoImpl(false, loop.dispatcher(), std::move(request_channel));
});
ZX_ASSERT(add_regular_result.is_ok());
auto add_reversed_result = my_service.add_reversed_echo(
[&loop](fidl::ServerEnd<fuchsia_examples::Echo> request_channel) -> void {
new EchoImpl(true, loop.dispatcher(), std::move(request_channel));
});
ZX_ASSERT(add_reversed_result.is_ok());
// Example of serving an instance of "EchoService".
auto result = outgoing.AddService<fuchsia_examples::EchoService>(std::move(handler));
if (result.is_error()) {
return result.status_value();
}
result = outgoing.ServeFromStartupInfo();
if (result.is_error()) {
return result.status_value();
}
std::cout << "Running echo server" << std::endl;
loop.Run();
return 0;
}