Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic server example without manual buffer serializaiton? #80

Closed
criatura2 opened this issue Jul 24, 2023 · 4 comments
Closed

Generic server example without manual buffer serializaiton? #80

criatura2 opened this issue Jul 24, 2023 · 4 comments

Comments

@criatura2
Copy link

Hi again,

I am wondering which of your examples should I use to implement an async server in a way that it supports multiple kinds of messages but does not require me to serialize buffers manually like in the generic server example.

The multi-threaded-server seems like a good start but uses only one type of message namely HelloReply.

@Tradias
Copy link
Owner

Tradias commented Jul 24, 2023

In your proto file you would typically define a Service with multiple endpoints, like in the example. Then for each GrpcContext you register your request handler for each endpoint:

void register_handlers(agrpc::GrpcContext& grpc_context, example::v1::Example::AsyncService& service)
{
    auto register_handler = [&](auto request_function, auto handler)
    {
        agrpc::repeatedly_request(request_function, service, asio::bind_executor(grpc_context, handler));
    };

    register_handler(&example::v1::Example::AsyncService::RequestUnary,
                     [&](grpc::ServerContext&, example::v1::Request&,
                         grpc::ServerAsyncResponseWriter<example::v1::Response>&) -> asio::awaitable<void>
                     {
                         co_return;
                     });
    register_handler(&example::v1::Example::AsyncService::RequestServerStreaming,
                     [&](grpc::ServerContext&, example::v1::Request&,
                         grpc::ServerAsyncWriter<example::v1::Response>&) -> asio::awaitable<void>
                     {
                         co_return;
                     });
    register_handler(&example::v1::Example::AsyncService::RequestClientStreaming,
                     [&](grpc::ServerContext&,
                         grpc::ServerAsyncReader<example::v1::Response, example::v1::Request>&) -> asio::awaitable<void>
                     {
                         co_return;
                     });
    register_handler(&example::v1::Example::AsyncService::RequestBidirectionalStreaming,
                     [&](grpc::ServerContext&,
                         grpc::ServerAsyncReaderWriter<example::v1::Response, example::v1::Request>&) -> asio::awaitable<void>
                     {
                         co_return;
                     });
}

I hope that is what you were asking.

Regarding the generic server, I personally haven't had a use case for it but I know that someone experimented with haskell bindings for grpc and made use of it.

@criatura2
Copy link
Author

Ok, thanks. I suppose this example also work for when each service has a different message type?

Also, are you implying I need one grpc-context and threfore one thread for each service? In the generic example I am using only one grpc-context and threfore only one thread.

@Tradias
Copy link
Owner

Tradias commented Jul 24, 2023

Correct, it also works for different message types. Interesting question, the documentation actually doesn't mention that and the examples use the same type for simplicity. I guess I could add an example for the official route guide.

You can have as many or few services and GprcContexts as you like. Have one context handle all services or multiple contexts handle multiple services, everything's possible.

@criatura2
Copy link
Author

Thanks, this is solved now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants