1 // 2 // 3 // Copyright 2018 gRPC authors. 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 // 17 // 18 19 #ifndef GRPCPP_GENERIC_ASYNC_GENERIC_SERVICE_H 20 #define GRPCPP_GENERIC_ASYNC_GENERIC_SERVICE_H 21 22 #include <grpc/support/port_platform.h> 23 #include <grpcpp/impl/server_callback_handlers.h> 24 #include <grpcpp/support/async_stream.h> 25 #include <grpcpp/support/byte_buffer.h> 26 #include <grpcpp/support/server_callback.h> 27 28 struct grpc_server; 29 30 namespace grpc { 31 32 typedef ServerAsyncReaderWriter<ByteBuffer, ByteBuffer> 33 GenericServerAsyncReaderWriter; 34 typedef ServerAsyncResponseWriter<ByteBuffer> GenericServerAsyncResponseWriter; 35 typedef ServerAsyncReader<ByteBuffer, ByteBuffer> GenericServerAsyncReader; 36 typedef ServerAsyncWriter<ByteBuffer> GenericServerAsyncWriter; 37 38 class GenericServerContext final : public ServerContext { 39 public: method()40 const std::string& method() const { return method_; } host()41 const std::string& host() const { return host_; } 42 43 private: 44 friend class ServerInterface; 45 46 std::string method_; 47 std::string host_; 48 }; 49 50 // A generic service at the server side accepts all RPC methods and hosts. It is 51 // typically used in proxies. The generic service can be registered to a server 52 // which also has other services. 53 // Sample usage: 54 // ServerBuilder builder; 55 // auto cq = builder.AddCompletionQueue(); 56 // AsyncGenericService generic_service; 57 // builder.RegisterAsyncGenericService(&generic_service); 58 // auto server = builder.BuildAndStart(); 59 // 60 // // request a new call 61 // GenericServerContext context; 62 // GenericServerAsyncReaderWriter stream; 63 // generic_service.RequestCall(&context, &stream, cq.get(), cq.get(), tag); 64 // 65 // When tag is retrieved from cq->Next(), context.method() can be used to look 66 // at the method and the RPC can be handled accordingly. 67 class AsyncGenericService final { 68 public: AsyncGenericService()69 AsyncGenericService() : server_(nullptr) {} 70 71 void RequestCall(GenericServerContext* ctx, 72 GenericServerAsyncReaderWriter* reader_writer, 73 grpc::CompletionQueue* call_cq, 74 grpc::ServerCompletionQueue* notification_cq, void* tag); 75 76 private: 77 friend class grpc::Server; 78 grpc::Server* server_; 79 }; 80 81 /// \a ServerGenericBidiReactor is the reactor class for bidi streaming RPCs 82 /// invoked on a CallbackGenericService. It is just a ServerBidi reactor with 83 /// ByteBuffer arguments. 84 using ServerGenericBidiReactor = ServerBidiReactor<ByteBuffer, ByteBuffer>; 85 86 class GenericCallbackServerContext final : public grpc::CallbackServerContext { 87 public: method()88 const std::string& method() const { return method_; } host()89 const std::string& host() const { return host_; } 90 91 private: 92 friend class grpc::Server; 93 94 std::string method_; 95 std::string host_; 96 }; 97 98 /// \a CallbackGenericService is the base class for generic services implemented 99 /// using the callback API and registered through the ServerBuilder using 100 /// RegisterCallbackGenericService. 101 class CallbackGenericService { 102 public: CallbackGenericService()103 CallbackGenericService() {} ~CallbackGenericService()104 virtual ~CallbackGenericService() {} 105 106 /// The "method handler" for the generic API. This function should be 107 /// overridden to provide a ServerGenericBidiReactor that implements the 108 /// application-level interface for this RPC. Unimplemented by default. CreateReactor(GenericCallbackServerContext *)109 virtual ServerGenericBidiReactor* CreateReactor( 110 GenericCallbackServerContext* /*ctx*/) { 111 class Reactor : public ServerGenericBidiReactor { 112 public: 113 Reactor() { this->Finish(Status(StatusCode::UNIMPLEMENTED, "")); } 114 void OnDone() override { delete this; } 115 }; 116 return new Reactor; 117 } 118 119 private: 120 friend class grpc::Server; 121 Handler()122 internal::CallbackBidiHandler<ByteBuffer, ByteBuffer>* Handler() { 123 return new internal::CallbackBidiHandler<ByteBuffer, ByteBuffer>( 124 [this](grpc::CallbackServerContext* ctx) { 125 return CreateReactor(static_cast<GenericCallbackServerContext*>(ctx)); 126 }); 127 } 128 129 grpc::Server* server_{nullptr}; 130 }; 131 132 } // namespace grpc 133 134 #endif // GRPCPP_GENERIC_ASYNC_GENERIC_SERVICE_H 135