Return non protobuf format from a ::grpc::Server

109 views
Skip to first unread message

cur...@gmail.com

unread,
Jun 1, 2017, 1:43:03 AM6/1/17
to grpc.io
im trying to find an example of calling ServerBuilder::RegisterService with a custom Service that can read / write raw data. 

My use case is that i need an extra endpoint that does some metric reporting that responds with a custom format when pulled. 

Ideally i would like to reuse the server part of GRPC (in addition to some grpc native Services) for serving this custom endpoint.

Thanks!

Curtis

Curtis Mahieu

unread,
Jun 1, 2017, 3:28:37 AM6/1/17
to grpc.io
I can get close to having it work by looking at how Flatbuffer support was added by doing something like this:


//Header file:

struct Thing1{
};

struct Thing2 : public Thing1 {
};

namespace helloworld {

// The greeting service definition.
class Greeter GRPC_FINAL {
public:
  class Service : public ::grpc::Service {
   public:
    Service();
    virtual ~Service() = default;
    virtual ::grpc::Status SayHello(::grpc::ServerContext*, const Thing1*, Thing2*){
        return ::grpc::Status::OK;
    }
  };
};

}  // namespace helloworld




namespace grpc {

    template<class T>
    class SerializationTraits<T, typename std::enable_if<std::is_base_of<Thing1, T>::value>::type> {
    public:
        // The type we're passing here is a BufferRef, which is already serialized
        // FlatBuffer data, which then gets passed to GRPC.
        static grpc::Status Serialize(const T &,
                                      grpc_byte_buffer **buffer,
                                      bool *own_buffer) {

            auto slice = gpr_slice_from_static_string("Hello!World!");
           // *buffer = grpc_raw_byte_buffer_create(&slice, 1);  <- This line make its not work at all!!!!!!
            grpc_slice_unref(slice);
            *own_buffer = true;
            return grpc::Status();
        }

        // There is no de-serialization step in FlatBuffers, so we just receive
        // the data from GRPC.
        static grpc::Status Deserialize(grpc_byte_buffer *buffer, T *) {
            grpc_byte_buffer_destroy(buffer);

            return grpc::Status();
        }
    };

}  // namespace grpc;


namespace helloworld {

    Greeter::Service::Service() {
        AddMethod(new ::grpc::RpcServiceMethod(
                "/bob",
                ::grpc::RpcMethod::NORMAL_RPC,
                new ::grpc::RpcMethodHandler<Greeter::Service, Thing1, Thing2>(std::mem_fn(&Greeter::Service::SayHello), this)));
    }


}  // namespace helloworld

if i use the grpc_cli tool i can get an empty message back when the *buffer line is disabled: 
grpc_cli call localhost:8080 /bob --binary_input=true --infile=frame.bin --outfile=out.bin
Method name not found
connecting to localhost:8080
Rpc succeeded with OK status

but then its enabled i get this:
grpc_cli call localhost:8080 /bob --binary_input=true --infile=./frame.bin --outfile=./out.bin 
Method name not found
connecting to localhost:8080
Method name not found

I can see in the debugger that its going to the entire flow like i expect for both cases, but how do i get it to echo back the raw data????
Reply all
Reply to author
Forward
0 new messages