1 /* 2 * 3 * Copyright 2015 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_IMPL_CODEGEN_ASYNC_GENERIC_SERVICE_H 20 #define GRPCPP_IMPL_CODEGEN_ASYNC_GENERIC_SERVICE_H 21 22 #include <grpc/impl/codegen/port_platform.h> 23 24 #include <grpcpp/impl/codegen/async_stream_impl.h> 25 #include <grpcpp/impl/codegen/byte_buffer.h> 26 #include <grpcpp/impl/codegen/server_callback_handlers.h> 27 #include <grpcpp/impl/codegen/server_callback_impl.h> 28 29 struct grpc_server; 30 31 namespace grpc { 32 33 typedef ::grpc_impl::ServerAsyncReaderWriter<ByteBuffer, ByteBuffer> 34 GenericServerAsyncReaderWriter; 35 typedef ::grpc_impl::ServerAsyncResponseWriter<ByteBuffer> 36 GenericServerAsyncResponseWriter; 37 typedef ::grpc_impl::ServerAsyncReader<ByteBuffer, ByteBuffer> 38 GenericServerAsyncReader; 39 typedef ::grpc_impl::ServerAsyncWriter<ByteBuffer> GenericServerAsyncWriter; 40 41 class GenericServerContext final : public ::grpc_impl::ServerContext { 42 public: method()43 const std::string& method() const { return method_; } host()44 const std::string& host() const { return host_; } 45 46 private: 47 friend class grpc_impl::Server; 48 friend class grpc::ServerInterface; 49 Clear()50 void Clear() { 51 method_.clear(); 52 host_.clear(); 53 ::grpc_impl::ServerContext::Clear(); 54 } 55 56 std::string method_; 57 std::string host_; 58 }; 59 60 // A generic service at the server side accepts all RPC methods and hosts. It is 61 // typically used in proxies. The generic service can be registered to a server 62 // which also has other services. 63 // Sample usage: 64 // ServerBuilder builder; 65 // auto cq = builder.AddCompletionQueue(); 66 // AsyncGenericService generic_service; 67 // builder.RegisterAsyncGenericService(&generic_service); 68 // auto server = builder.BuildAndStart(); 69 // 70 // // request a new call 71 // GenericServerContext context; 72 // GenericServerAsyncReaderWriter stream; 73 // generic_service.RequestCall(&context, &stream, cq.get(), cq.get(), tag); 74 // 75 // When tag is retrieved from cq->Next(), context.method() can be used to look 76 // at the method and the RPC can be handled accordingly. 77 class AsyncGenericService final { 78 public: AsyncGenericService()79 AsyncGenericService() : server_(nullptr) {} 80 81 void RequestCall(GenericServerContext* ctx, 82 GenericServerAsyncReaderWriter* reader_writer, 83 ::grpc_impl::CompletionQueue* call_cq, 84 ::grpc_impl::ServerCompletionQueue* notification_cq, 85 void* tag); 86 87 private: 88 friend class grpc_impl::Server; 89 grpc_impl::Server* server_; 90 }; 91 92 #ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL 93 namespace experimental { 94 #endif 95 96 /// \a ServerGenericBidiReactor is the reactor class for bidi streaming RPCs 97 /// invoked on a CallbackGenericService. It is just a ServerBidi reactor with 98 /// ByteBuffer arguments. 99 using ServerGenericBidiReactor = 100 ::grpc_impl::ServerBidiReactor<ByteBuffer, ByteBuffer>; 101 102 class GenericCallbackServerContext final 103 : public ::grpc_impl::CallbackServerContext { 104 public: method()105 const std::string& method() const { return method_; } host()106 const std::string& host() const { return host_; } 107 108 private: 109 friend class ::grpc_impl::Server; 110 friend class ::grpc::ServerInterface; 111 Clear()112 void Clear() { 113 method_.clear(); 114 host_.clear(); 115 ::grpc_impl::CallbackServerContext::Clear(); 116 } 117 118 std::string method_; 119 std::string host_; 120 }; 121 122 /// \a CallbackGenericService is the base class for generic services implemented 123 /// using the callback API and registered through the ServerBuilder using 124 /// RegisterCallbackGenericService. 125 class CallbackGenericService { 126 public: CallbackGenericService()127 CallbackGenericService() {} ~CallbackGenericService()128 virtual ~CallbackGenericService() {} 129 130 /// The "method handler" for the generic API. This function should be 131 /// overridden to provide a ServerGenericBidiReactor that implements the 132 /// application-level interface for this RPC. Unimplemented by default. CreateReactor(GenericCallbackServerContext *)133 virtual ServerGenericBidiReactor* CreateReactor( 134 GenericCallbackServerContext* /*ctx*/) { 135 class Reactor : public ServerGenericBidiReactor { 136 public: 137 Reactor() { this->Finish(Status(StatusCode::UNIMPLEMENTED, "")); } 138 void OnDone() override { delete this; } 139 }; 140 return new Reactor; 141 } 142 143 private: 144 friend class ::grpc_impl::Server; 145 146 ::grpc_impl::internal::CallbackBidiHandler<ByteBuffer, ByteBuffer>* Handler()147 Handler() { 148 return new ::grpc_impl::internal::CallbackBidiHandler<ByteBuffer, 149 ByteBuffer>( 150 [this](::grpc_impl::CallbackServerContext* ctx) { 151 return CreateReactor(static_cast<GenericCallbackServerContext*>(ctx)); 152 }); 153 } 154 155 grpc_impl::Server* server_{nullptr}; 156 }; 157 158 #ifndef GRPC_CALLBACK_API_NONEXPERIMENTAL 159 } // namespace experimental 160 #endif 161 } // namespace grpc 162 163 #endif // GRPCPP_IMPL_CODEGEN_ASYNC_GENERIC_SERVICE_H 164