mirror of
https://github.com/unclechu/gRPC-haskell.git
synced 2024-11-26 21:19:43 +01:00
Various example/benchmarking code (#16)
* initial echo client/server examples * registered and unregistered versions of the example client * ignore pyc files * cpp echo code, flag to build examples * threaded server example
This commit is contained in:
parent
9ffdec4c56
commit
ce56953b24
21 changed files with 1135 additions and 6 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,2 +1,5 @@
|
|||
dist
|
||||
.stack-work/
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.o
|
||||
|
|
37
examples/echo/echo-client/Main.hs
Normal file
37
examples/echo/echo-client/Main.hs
Normal file
|
@ -0,0 +1,37 @@
|
|||
{-# LANGUAGE OverloadedStrings #-}
|
||||
|
||||
import Control.Concurrent (threadDelay)
|
||||
import Control.Monad (forever)
|
||||
import Data.ByteString ()
|
||||
import qualified Data.Map as M
|
||||
import Network.GRPC.LowLevel
|
||||
|
||||
echoMethod :: MethodName
|
||||
echoMethod = MethodName "/echo.Echo/DoEcho"
|
||||
|
||||
ntimes :: Int -> IO () -> IO ()
|
||||
ntimes 1 f = f
|
||||
ntimes n f = f >> (ntimes (n-1) f)
|
||||
|
||||
unregClient :: IO ()
|
||||
unregClient = do
|
||||
withGRPC $ \grpc ->
|
||||
withClient grpc (ClientConfig "localhost" 50051) $ \client ->
|
||||
ntimes 100000 $ do
|
||||
reqResult <- clientRequest client echoMethod "localhost:50051" 1 "hi" M.empty
|
||||
case reqResult of
|
||||
Left x -> error $ "Got client error: " ++ show x
|
||||
Right resp -> return ()
|
||||
|
||||
regClient :: IO ()
|
||||
regClient = do
|
||||
withGRPC $ \grpc ->
|
||||
withClient grpc (ClientConfig "localhost" 50051) $ \client -> ntimes 100000 $ do
|
||||
regMethod <- clientRegisterMethod client echoMethod "localhost:50051" Normal
|
||||
reqResult <- clientRegisteredRequest client regMethod 1 "hi" M.empty
|
||||
case reqResult of
|
||||
Left x -> error $ "Got client error: " ++ show x
|
||||
Right resp -> return ()
|
||||
|
||||
main :: IO ()
|
||||
main = regClient
|
10
examples/echo/echo-cpp/Makefile
Normal file
10
examples/echo/echo-cpp/Makefile
Normal file
|
@ -0,0 +1,10 @@
|
|||
CXX = clang++
|
||||
CXXFLAGS += -std=c++11
|
||||
CPPFLAGS += -I/usr/local/include -pthread
|
||||
LDFLAGS += -L/usr/local/lib -lgrpc++_unsecure -lgrpc -lprotobuf -lpthread -ldl
|
||||
|
||||
echo-server: echo.pb.o echo.grpc.pb.o echo-server.o
|
||||
clang++ $^ $(LDFLAGS) -o $@
|
||||
|
||||
echo-client: echo.pb.o echo.grpc.pb.o echo-client.o
|
||||
clang++ $^ $(LDFLAGS) -o $@
|
BIN
examples/echo/echo-cpp/echo-client
Executable file
BIN
examples/echo/echo-cpp/echo-client
Executable file
Binary file not shown.
48
examples/echo/echo-cpp/echo-client.cc
Normal file
48
examples/echo/echo-cpp/echo-client.cc
Normal file
|
@ -0,0 +1,48 @@
|
|||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include <grpc++/grpc++.h>
|
||||
|
||||
#include "echo.grpc.pb.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
using grpc::Channel;
|
||||
using grpc::ClientContext;
|
||||
using grpc::Status;
|
||||
using echo::EchoRequest;
|
||||
using echo::Echo;
|
||||
|
||||
class EchoClient {
|
||||
public:
|
||||
EchoClient(shared_ptr<Channel> chan) : stub_(Echo::NewStub(chan)) {}
|
||||
|
||||
Status DoEcho(const string& msg){
|
||||
EchoRequest req;
|
||||
req.set_message(msg);
|
||||
|
||||
EchoRequest resp;
|
||||
|
||||
ClientContext ctx;
|
||||
|
||||
return stub_->DoEcho(&ctx, req, &resp);
|
||||
}
|
||||
|
||||
private:
|
||||
unique_ptr<Echo::Stub> stub_;
|
||||
};
|
||||
|
||||
int main(){
|
||||
EchoClient client(grpc::CreateChannel("localhost:50051",
|
||||
grpc::InsecureChannelCredentials()));
|
||||
string msg("hi");
|
||||
for(int i = 0; i < 100000; i++){
|
||||
Status status = client.DoEcho(msg);
|
||||
if(!status.ok()){
|
||||
cout<<"Error: "<<status.error_code()<<endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
BIN
examples/echo/echo-cpp/echo-server
Executable file
BIN
examples/echo/echo-cpp/echo-server
Executable file
Binary file not shown.
34
examples/echo/echo-cpp/echo-server.cc
Normal file
34
examples/echo/echo-cpp/echo-server.cc
Normal file
|
@ -0,0 +1,34 @@
|
|||
#include <string>
|
||||
|
||||
#include <grpc++/grpc++.h>
|
||||
#include "echo.grpc.pb.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
using grpc::Server;
|
||||
using grpc::ServerBuilder;
|
||||
using grpc::ServerContext;
|
||||
using grpc::Status;
|
||||
|
||||
using echo::EchoRequest;
|
||||
using echo::Echo;
|
||||
|
||||
class EchoServiceImpl final : public Echo::Service {
|
||||
Status DoEcho(ServerContext* ctx, const EchoRequest* req,
|
||||
EchoRequest* resp) override {
|
||||
resp->set_message(req->message());
|
||||
return Status::OK;
|
||||
}
|
||||
};
|
||||
|
||||
int main(){
|
||||
string server_address("localhost:50051");
|
||||
EchoServiceImpl service;
|
||||
|
||||
ServerBuilder builder;
|
||||
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
|
||||
builder.RegisterService(&service);
|
||||
unique_ptr<Server> server(builder.BuildAndStart());
|
||||
server->Wait();
|
||||
return 0;
|
||||
}
|
59
examples/echo/echo-cpp/echo.grpc.pb.cc
Normal file
59
examples/echo/echo-cpp/echo.grpc.pb.cc
Normal file
|
@ -0,0 +1,59 @@
|
|||
// Generated by the gRPC protobuf plugin.
|
||||
// If you make any local change, they will be lost.
|
||||
// source: echo.proto
|
||||
|
||||
#include "echo.pb.h"
|
||||
#include "echo.grpc.pb.h"
|
||||
|
||||
#include <grpc++/impl/codegen/async_stream.h>
|
||||
#include <grpc++/impl/codegen/async_unary_call.h>
|
||||
#include <grpc++/impl/codegen/channel_interface.h>
|
||||
#include <grpc++/impl/codegen/client_unary_call.h>
|
||||
#include <grpc++/impl/codegen/method_handler_impl.h>
|
||||
#include <grpc++/impl/codegen/rpc_service_method.h>
|
||||
#include <grpc++/impl/codegen/service_type.h>
|
||||
#include <grpc++/impl/codegen/sync_stream.h>
|
||||
namespace echo {
|
||||
|
||||
static const char* Echo_method_names[] = {
|
||||
"/echo.Echo/DoEcho",
|
||||
};
|
||||
|
||||
std::unique_ptr< Echo::Stub> Echo::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) {
|
||||
std::unique_ptr< Echo::Stub> stub(new Echo::Stub(channel));
|
||||
return stub;
|
||||
}
|
||||
|
||||
Echo::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel)
|
||||
: channel_(channel), rpcmethod_DoEcho_(Echo_method_names[0], ::grpc::RpcMethod::NORMAL_RPC, channel)
|
||||
{}
|
||||
|
||||
::grpc::Status Echo::Stub::DoEcho(::grpc::ClientContext* context, const ::echo::EchoRequest& request, ::echo::EchoRequest* response) {
|
||||
return ::grpc::BlockingUnaryCall(channel_.get(), rpcmethod_DoEcho_, context, request, response);
|
||||
}
|
||||
|
||||
::grpc::ClientAsyncResponseReader< ::echo::EchoRequest>* Echo::Stub::AsyncDoEchoRaw(::grpc::ClientContext* context, const ::echo::EchoRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
return new ::grpc::ClientAsyncResponseReader< ::echo::EchoRequest>(channel_.get(), cq, rpcmethod_DoEcho_, context, request);
|
||||
}
|
||||
|
||||
Echo::Service::Service() {
|
||||
AddMethod(new ::grpc::RpcServiceMethod(
|
||||
Echo_method_names[0],
|
||||
::grpc::RpcMethod::NORMAL_RPC,
|
||||
new ::grpc::RpcMethodHandler< Echo::Service, ::echo::EchoRequest, ::echo::EchoRequest>(
|
||||
std::mem_fn(&Echo::Service::DoEcho), this)));
|
||||
}
|
||||
|
||||
Echo::Service::~Service() {
|
||||
}
|
||||
|
||||
::grpc::Status Echo::Service::DoEcho(::grpc::ServerContext* context, const ::echo::EchoRequest* request, ::echo::EchoRequest* response) {
|
||||
(void) context;
|
||||
(void) request;
|
||||
(void) response;
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
|
||||
|
||||
} // namespace echo
|
||||
|
103
examples/echo/echo-cpp/echo.grpc.pb.h
Normal file
103
examples/echo/echo-cpp/echo.grpc.pb.h
Normal file
|
@ -0,0 +1,103 @@
|
|||
// Generated by the gRPC protobuf plugin.
|
||||
// If you make any local change, they will be lost.
|
||||
// source: echo.proto
|
||||
#ifndef GRPC_echo_2eproto__INCLUDED
|
||||
#define GRPC_echo_2eproto__INCLUDED
|
||||
|
||||
#include "echo.pb.h"
|
||||
|
||||
#include <grpc++/impl/codegen/async_stream.h>
|
||||
#include <grpc++/impl/codegen/async_unary_call.h>
|
||||
#include <grpc++/impl/codegen/proto_utils.h>
|
||||
#include <grpc++/impl/codegen/rpc_method.h>
|
||||
#include <grpc++/impl/codegen/service_type.h>
|
||||
#include <grpc++/impl/codegen/status.h>
|
||||
#include <grpc++/impl/codegen/stub_options.h>
|
||||
#include <grpc++/impl/codegen/sync_stream.h>
|
||||
|
||||
namespace grpc {
|
||||
class CompletionQueue;
|
||||
class RpcService;
|
||||
class ServerCompletionQueue;
|
||||
class ServerContext;
|
||||
} // namespace grpc
|
||||
|
||||
namespace echo {
|
||||
|
||||
class Echo GRPC_FINAL {
|
||||
public:
|
||||
class StubInterface {
|
||||
public:
|
||||
virtual ~StubInterface() {}
|
||||
virtual ::grpc::Status DoEcho(::grpc::ClientContext* context, const ::echo::EchoRequest& request, ::echo::EchoRequest* response) = 0;
|
||||
std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::echo::EchoRequest>> AsyncDoEcho(::grpc::ClientContext* context, const ::echo::EchoRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::echo::EchoRequest>>(AsyncDoEchoRaw(context, request, cq));
|
||||
}
|
||||
private:
|
||||
virtual ::grpc::ClientAsyncResponseReaderInterface< ::echo::EchoRequest>* AsyncDoEchoRaw(::grpc::ClientContext* context, const ::echo::EchoRequest& request, ::grpc::CompletionQueue* cq) = 0;
|
||||
};
|
||||
class Stub GRPC_FINAL : public StubInterface {
|
||||
public:
|
||||
Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel);
|
||||
::grpc::Status DoEcho(::grpc::ClientContext* context, const ::echo::EchoRequest& request, ::echo::EchoRequest* response) GRPC_OVERRIDE;
|
||||
std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::echo::EchoRequest>> AsyncDoEcho(::grpc::ClientContext* context, const ::echo::EchoRequest& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::echo::EchoRequest>>(AsyncDoEchoRaw(context, request, cq));
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr< ::grpc::ChannelInterface> channel_;
|
||||
::grpc::ClientAsyncResponseReader< ::echo::EchoRequest>* AsyncDoEchoRaw(::grpc::ClientContext* context, const ::echo::EchoRequest& request, ::grpc::CompletionQueue* cq) GRPC_OVERRIDE;
|
||||
const ::grpc::RpcMethod rpcmethod_DoEcho_;
|
||||
};
|
||||
static std::unique_ptr<Stub> NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions());
|
||||
|
||||
class Service : public ::grpc::Service {
|
||||
public:
|
||||
Service();
|
||||
virtual ~Service();
|
||||
virtual ::grpc::Status DoEcho(::grpc::ServerContext* context, const ::echo::EchoRequest* request, ::echo::EchoRequest* response);
|
||||
};
|
||||
template <class BaseClass>
|
||||
class WithAsyncMethod_DoEcho : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(Service *service) {}
|
||||
public:
|
||||
WithAsyncMethod_DoEcho() {
|
||||
::grpc::Service::MarkMethodAsync(0);
|
||||
}
|
||||
~WithAsyncMethod_DoEcho() GRPC_OVERRIDE {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status DoEcho(::grpc::ServerContext* context, const ::echo::EchoRequest* request, ::echo::EchoRequest* response) GRPC_FINAL GRPC_OVERRIDE {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
void RequestDoEcho(::grpc::ServerContext* context, ::echo::EchoRequest* request, ::grpc::ServerAsyncResponseWriter< ::echo::EchoRequest>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
|
||||
::grpc::Service::RequestAsyncUnary(0, context, request, response, new_call_cq, notification_cq, tag);
|
||||
}
|
||||
};
|
||||
typedef WithAsyncMethod_DoEcho<Service > AsyncService;
|
||||
template <class BaseClass>
|
||||
class WithGenericMethod_DoEcho : public BaseClass {
|
||||
private:
|
||||
void BaseClassMustBeDerivedFromService(Service *service) {}
|
||||
public:
|
||||
WithGenericMethod_DoEcho() {
|
||||
::grpc::Service::MarkMethodGeneric(0);
|
||||
}
|
||||
~WithGenericMethod_DoEcho() GRPC_OVERRIDE {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status DoEcho(::grpc::ServerContext* context, const ::echo::EchoRequest* request, ::echo::EchoRequest* response) GRPC_FINAL GRPC_OVERRIDE {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace echo
|
||||
|
||||
|
||||
#endif // GRPC_echo_2eproto__INCLUDED
|
384
examples/echo/echo-cpp/echo.pb.cc
Normal file
384
examples/echo/echo-cpp/echo.pb.cc
Normal file
|
@ -0,0 +1,384 @@
|
|||
// Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
// source: echo.proto
|
||||
|
||||
#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
|
||||
#include "echo.pb.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
#include <google/protobuf/stubs/port.h>
|
||||
#include <google/protobuf/stubs/once.h>
|
||||
#include <google/protobuf/io/coded_stream.h>
|
||||
#include <google/protobuf/wire_format_lite_inl.h>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include <google/protobuf/generated_message_reflection.h>
|
||||
#include <google/protobuf/reflection_ops.h>
|
||||
#include <google/protobuf/wire_format.h>
|
||||
// @@protoc_insertion_point(includes)
|
||||
|
||||
namespace echo {
|
||||
|
||||
namespace {
|
||||
|
||||
const ::google::protobuf::Descriptor* EchoRequest_descriptor_ = NULL;
|
||||
const ::google::protobuf::internal::GeneratedMessageReflection*
|
||||
EchoRequest_reflection_ = NULL;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
void protobuf_AssignDesc_echo_2eproto() {
|
||||
protobuf_AddDesc_echo_2eproto();
|
||||
const ::google::protobuf::FileDescriptor* file =
|
||||
::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(
|
||||
"echo.proto");
|
||||
GOOGLE_CHECK(file != NULL);
|
||||
EchoRequest_descriptor_ = file->message_type(0);
|
||||
static const int EchoRequest_offsets_[1] = {
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EchoRequest, message_),
|
||||
};
|
||||
EchoRequest_reflection_ =
|
||||
::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
|
||||
EchoRequest_descriptor_,
|
||||
EchoRequest::default_instance_,
|
||||
EchoRequest_offsets_,
|
||||
-1,
|
||||
-1,
|
||||
-1,
|
||||
sizeof(EchoRequest),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EchoRequest, _internal_metadata_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EchoRequest, _is_default_instance_));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);
|
||||
inline void protobuf_AssignDescriptorsOnce() {
|
||||
::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,
|
||||
&protobuf_AssignDesc_echo_2eproto);
|
||||
}
|
||||
|
||||
void protobuf_RegisterTypes(const ::std::string&) {
|
||||
protobuf_AssignDescriptorsOnce();
|
||||
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
|
||||
EchoRequest_descriptor_, &EchoRequest::default_instance());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void protobuf_ShutdownFile_echo_2eproto() {
|
||||
delete EchoRequest::default_instance_;
|
||||
delete EchoRequest_reflection_;
|
||||
}
|
||||
|
||||
void protobuf_AddDesc_echo_2eproto() {
|
||||
static bool already_here = false;
|
||||
if (already_here) return;
|
||||
already_here = true;
|
||||
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
||||
|
||||
::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
|
||||
"\n\necho.proto\022\004echo\"\036\n\013EchoRequest\022\017\n\007mes"
|
||||
"sage\030\001 \001(\t28\n\004Echo\0220\n\006DoEcho\022\021.echo.Echo"
|
||||
"Request\032\021.echo.EchoRequest\"\000b\006proto3", 116);
|
||||
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
|
||||
"echo.proto", &protobuf_RegisterTypes);
|
||||
EchoRequest::default_instance_ = new EchoRequest();
|
||||
EchoRequest::default_instance_->InitAsDefaultInstance();
|
||||
::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_echo_2eproto);
|
||||
}
|
||||
|
||||
// Force AddDescriptors() to be called at static initialization time.
|
||||
struct StaticDescriptorInitializer_echo_2eproto {
|
||||
StaticDescriptorInitializer_echo_2eproto() {
|
||||
protobuf_AddDesc_echo_2eproto();
|
||||
}
|
||||
} static_descriptor_initializer_echo_2eproto_;
|
||||
|
||||
namespace {
|
||||
|
||||
static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
|
||||
static void MergeFromFail(int line) {
|
||||
GOOGLE_CHECK(false) << __FILE__ << ":" << line;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
// ===================================================================
|
||||
|
||||
#if !defined(_MSC_VER) || _MSC_VER >= 1900
|
||||
const int EchoRequest::kMessageFieldNumber;
|
||||
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
|
||||
|
||||
EchoRequest::EchoRequest()
|
||||
: ::google::protobuf::Message(), _internal_metadata_(NULL) {
|
||||
SharedCtor();
|
||||
// @@protoc_insertion_point(constructor:echo.EchoRequest)
|
||||
}
|
||||
|
||||
void EchoRequest::InitAsDefaultInstance() {
|
||||
_is_default_instance_ = true;
|
||||
}
|
||||
|
||||
EchoRequest::EchoRequest(const EchoRequest& from)
|
||||
: ::google::protobuf::Message(),
|
||||
_internal_metadata_(NULL) {
|
||||
SharedCtor();
|
||||
MergeFrom(from);
|
||||
// @@protoc_insertion_point(copy_constructor:echo.EchoRequest)
|
||||
}
|
||||
|
||||
void EchoRequest::SharedCtor() {
|
||||
_is_default_instance_ = false;
|
||||
::google::protobuf::internal::GetEmptyString();
|
||||
_cached_size_ = 0;
|
||||
message_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
|
||||
EchoRequest::~EchoRequest() {
|
||||
// @@protoc_insertion_point(destructor:echo.EchoRequest)
|
||||
SharedDtor();
|
||||
}
|
||||
|
||||
void EchoRequest::SharedDtor() {
|
||||
message_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
if (this != default_instance_) {
|
||||
}
|
||||
}
|
||||
|
||||
void EchoRequest::SetCachedSize(int size) const {
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
|
||||
_cached_size_ = size;
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_END();
|
||||
}
|
||||
const ::google::protobuf::Descriptor* EchoRequest::descriptor() {
|
||||
protobuf_AssignDescriptorsOnce();
|
||||
return EchoRequest_descriptor_;
|
||||
}
|
||||
|
||||
const EchoRequest& EchoRequest::default_instance() {
|
||||
if (default_instance_ == NULL) protobuf_AddDesc_echo_2eproto();
|
||||
return *default_instance_;
|
||||
}
|
||||
|
||||
EchoRequest* EchoRequest::default_instance_ = NULL;
|
||||
|
||||
EchoRequest* EchoRequest::New(::google::protobuf::Arena* arena) const {
|
||||
EchoRequest* n = new EchoRequest;
|
||||
if (arena != NULL) {
|
||||
arena->Own(n);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
void EchoRequest::Clear() {
|
||||
message_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
|
||||
bool EchoRequest::MergePartialFromCodedStream(
|
||||
::google::protobuf::io::CodedInputStream* input) {
|
||||
#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
|
||||
::google::protobuf::uint32 tag;
|
||||
// @@protoc_insertion_point(parse_start:echo.EchoRequest)
|
||||
for (;;) {
|
||||
::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
|
||||
tag = p.first;
|
||||
if (!p.second) goto handle_unusual;
|
||||
switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
|
||||
// optional string message = 1;
|
||||
case 1: {
|
||||
if (tag == 10) {
|
||||
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
|
||||
input, this->mutable_message()));
|
||||
DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
|
||||
this->message().data(), this->message().length(),
|
||||
::google::protobuf::internal::WireFormatLite::PARSE,
|
||||
"echo.EchoRequest.message"));
|
||||
} else {
|
||||
goto handle_unusual;
|
||||
}
|
||||
if (input->ExpectAtEnd()) goto success;
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
handle_unusual:
|
||||
if (tag == 0 ||
|
||||
::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
|
||||
::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
|
||||
goto success;
|
||||
}
|
||||
DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
success:
|
||||
// @@protoc_insertion_point(parse_success:echo.EchoRequest)
|
||||
return true;
|
||||
failure:
|
||||
// @@protoc_insertion_point(parse_failure:echo.EchoRequest)
|
||||
return false;
|
||||
#undef DO_
|
||||
}
|
||||
|
||||
void EchoRequest::SerializeWithCachedSizes(
|
||||
::google::protobuf::io::CodedOutputStream* output) const {
|
||||
// @@protoc_insertion_point(serialize_start:echo.EchoRequest)
|
||||
// optional string message = 1;
|
||||
if (this->message().size() > 0) {
|
||||
::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
|
||||
this->message().data(), this->message().length(),
|
||||
::google::protobuf::internal::WireFormatLite::SERIALIZE,
|
||||
"echo.EchoRequest.message");
|
||||
::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
|
||||
1, this->message(), output);
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(serialize_end:echo.EchoRequest)
|
||||
}
|
||||
|
||||
::google::protobuf::uint8* EchoRequest::SerializeWithCachedSizesToArray(
|
||||
::google::protobuf::uint8* target) const {
|
||||
// @@protoc_insertion_point(serialize_to_array_start:echo.EchoRequest)
|
||||
// optional string message = 1;
|
||||
if (this->message().size() > 0) {
|
||||
::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
|
||||
this->message().data(), this->message().length(),
|
||||
::google::protobuf::internal::WireFormatLite::SERIALIZE,
|
||||
"echo.EchoRequest.message");
|
||||
target =
|
||||
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
|
||||
1, this->message(), target);
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(serialize_to_array_end:echo.EchoRequest)
|
||||
return target;
|
||||
}
|
||||
|
||||
int EchoRequest::ByteSize() const {
|
||||
int total_size = 0;
|
||||
|
||||
// optional string message = 1;
|
||||
if (this->message().size() > 0) {
|
||||
total_size += 1 +
|
||||
::google::protobuf::internal::WireFormatLite::StringSize(
|
||||
this->message());
|
||||
}
|
||||
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
|
||||
_cached_size_ = total_size;
|
||||
GOOGLE_SAFE_CONCURRENT_WRITES_END();
|
||||
return total_size;
|
||||
}
|
||||
|
||||
void EchoRequest::MergeFrom(const ::google::protobuf::Message& from) {
|
||||
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
|
||||
const EchoRequest* source =
|
||||
::google::protobuf::internal::DynamicCastToGenerated<const EchoRequest>(
|
||||
&from);
|
||||
if (source == NULL) {
|
||||
::google::protobuf::internal::ReflectionOps::Merge(from, this);
|
||||
} else {
|
||||
MergeFrom(*source);
|
||||
}
|
||||
}
|
||||
|
||||
void EchoRequest::MergeFrom(const EchoRequest& from) {
|
||||
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
|
||||
if (from.message().size() > 0) {
|
||||
|
||||
message_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.message_);
|
||||
}
|
||||
}
|
||||
|
||||
void EchoRequest::CopyFrom(const ::google::protobuf::Message& from) {
|
||||
if (&from == this) return;
|
||||
Clear();
|
||||
MergeFrom(from);
|
||||
}
|
||||
|
||||
void EchoRequest::CopyFrom(const EchoRequest& from) {
|
||||
if (&from == this) return;
|
||||
Clear();
|
||||
MergeFrom(from);
|
||||
}
|
||||
|
||||
bool EchoRequest::IsInitialized() const {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void EchoRequest::Swap(EchoRequest* other) {
|
||||
if (other == this) return;
|
||||
InternalSwap(other);
|
||||
}
|
||||
void EchoRequest::InternalSwap(EchoRequest* other) {
|
||||
message_.Swap(&other->message_);
|
||||
_internal_metadata_.Swap(&other->_internal_metadata_);
|
||||
std::swap(_cached_size_, other->_cached_size_);
|
||||
}
|
||||
|
||||
::google::protobuf::Metadata EchoRequest::GetMetadata() const {
|
||||
protobuf_AssignDescriptorsOnce();
|
||||
::google::protobuf::Metadata metadata;
|
||||
metadata.descriptor = EchoRequest_descriptor_;
|
||||
metadata.reflection = EchoRequest_reflection_;
|
||||
return metadata;
|
||||
}
|
||||
|
||||
#if PROTOBUF_INLINE_NOT_IN_HEADERS
|
||||
// EchoRequest
|
||||
|
||||
// optional string message = 1;
|
||||
void EchoRequest::clear_message() {
|
||||
message_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
const ::std::string& EchoRequest::message() const {
|
||||
// @@protoc_insertion_point(field_get:echo.EchoRequest.message)
|
||||
return message_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
void EchoRequest::set_message(const ::std::string& value) {
|
||||
|
||||
message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
|
||||
// @@protoc_insertion_point(field_set:echo.EchoRequest.message)
|
||||
}
|
||||
void EchoRequest::set_message(const char* value) {
|
||||
|
||||
message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
|
||||
// @@protoc_insertion_point(field_set_char:echo.EchoRequest.message)
|
||||
}
|
||||
void EchoRequest::set_message(const char* value, size_t size) {
|
||||
|
||||
message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
|
||||
::std::string(reinterpret_cast<const char*>(value), size));
|
||||
// @@protoc_insertion_point(field_set_pointer:echo.EchoRequest.message)
|
||||
}
|
||||
::std::string* EchoRequest::mutable_message() {
|
||||
|
||||
// @@protoc_insertion_point(field_mutable:echo.EchoRequest.message)
|
||||
return message_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
::std::string* EchoRequest::release_message() {
|
||||
|
||||
return message_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
void EchoRequest::set_allocated_message(::std::string* message) {
|
||||
if (message != NULL) {
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
message_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), message);
|
||||
// @@protoc_insertion_point(field_set_allocated:echo.EchoRequest.message)
|
||||
}
|
||||
|
||||
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
|
||||
|
||||
// @@protoc_insertion_point(namespace_scope)
|
||||
|
||||
} // namespace echo
|
||||
|
||||
// @@protoc_insertion_point(global_scope)
|
183
examples/echo/echo-cpp/echo.pb.h
Normal file
183
examples/echo/echo-cpp/echo.pb.h
Normal file
|
@ -0,0 +1,183 @@
|
|||
// Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
// source: echo.proto
|
||||
|
||||
#ifndef PROTOBUF_echo_2eproto__INCLUDED
|
||||
#define PROTOBUF_echo_2eproto__INCLUDED
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
|
||||
#if GOOGLE_PROTOBUF_VERSION < 3000000
|
||||
#error This file was generated by a newer version of protoc which is
|
||||
#error incompatible with your Protocol Buffer headers. Please update
|
||||
#error your headers.
|
||||
#endif
|
||||
#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
|
||||
#error This file was generated by an older version of protoc which is
|
||||
#error incompatible with your Protocol Buffer headers. Please
|
||||
#error regenerate this file with a newer version of protoc.
|
||||
#endif
|
||||
|
||||
#include <google/protobuf/arena.h>
|
||||
#include <google/protobuf/arenastring.h>
|
||||
#include <google/protobuf/generated_message_util.h>
|
||||
#include <google/protobuf/metadata.h>
|
||||
#include <google/protobuf/message.h>
|
||||
#include <google/protobuf/repeated_field.h>
|
||||
#include <google/protobuf/extension_set.h>
|
||||
#include <google/protobuf/unknown_field_set.h>
|
||||
// @@protoc_insertion_point(includes)
|
||||
|
||||
namespace echo {
|
||||
|
||||
// Internal implementation detail -- do not call these.
|
||||
void protobuf_AddDesc_echo_2eproto();
|
||||
void protobuf_AssignDesc_echo_2eproto();
|
||||
void protobuf_ShutdownFile_echo_2eproto();
|
||||
|
||||
class EchoRequest;
|
||||
|
||||
// ===================================================================
|
||||
|
||||
class EchoRequest : public ::google::protobuf::Message {
|
||||
public:
|
||||
EchoRequest();
|
||||
virtual ~EchoRequest();
|
||||
|
||||
EchoRequest(const EchoRequest& from);
|
||||
|
||||
inline EchoRequest& operator=(const EchoRequest& from) {
|
||||
CopyFrom(from);
|
||||
return *this;
|
||||
}
|
||||
|
||||
static const ::google::protobuf::Descriptor* descriptor();
|
||||
static const EchoRequest& default_instance();
|
||||
|
||||
void Swap(EchoRequest* other);
|
||||
|
||||
// implements Message ----------------------------------------------
|
||||
|
||||
inline EchoRequest* New() const { return New(NULL); }
|
||||
|
||||
EchoRequest* New(::google::protobuf::Arena* arena) const;
|
||||
void CopyFrom(const ::google::protobuf::Message& from);
|
||||
void MergeFrom(const ::google::protobuf::Message& from);
|
||||
void CopyFrom(const EchoRequest& from);
|
||||
void MergeFrom(const EchoRequest& from);
|
||||
void Clear();
|
||||
bool IsInitialized() const;
|
||||
|
||||
int ByteSize() const;
|
||||
bool MergePartialFromCodedStream(
|
||||
::google::protobuf::io::CodedInputStream* input);
|
||||
void SerializeWithCachedSizes(
|
||||
::google::protobuf::io::CodedOutputStream* output) const;
|
||||
::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
|
||||
int GetCachedSize() const { return _cached_size_; }
|
||||
private:
|
||||
void SharedCtor();
|
||||
void SharedDtor();
|
||||
void SetCachedSize(int size) const;
|
||||
void InternalSwap(EchoRequest* other);
|
||||
private:
|
||||
inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
|
||||
return _internal_metadata_.arena();
|
||||
}
|
||||
inline void* MaybeArenaPtr() const {
|
||||
return _internal_metadata_.raw_arena_ptr();
|
||||
}
|
||||
public:
|
||||
|
||||
::google::protobuf::Metadata GetMetadata() const;
|
||||
|
||||
// nested types ----------------------------------------------------
|
||||
|
||||
// accessors -------------------------------------------------------
|
||||
|
||||
// optional string message = 1;
|
||||
void clear_message();
|
||||
static const int kMessageFieldNumber = 1;
|
||||
const ::std::string& message() const;
|
||||
void set_message(const ::std::string& value);
|
||||
void set_message(const char* value);
|
||||
void set_message(const char* value, size_t size);
|
||||
::std::string* mutable_message();
|
||||
::std::string* release_message();
|
||||
void set_allocated_message(::std::string* message);
|
||||
|
||||
// @@protoc_insertion_point(class_scope:echo.EchoRequest)
|
||||
private:
|
||||
|
||||
::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
|
||||
bool _is_default_instance_;
|
||||
::google::protobuf::internal::ArenaStringPtr message_;
|
||||
mutable int _cached_size_;
|
||||
friend void protobuf_AddDesc_echo_2eproto();
|
||||
friend void protobuf_AssignDesc_echo_2eproto();
|
||||
friend void protobuf_ShutdownFile_echo_2eproto();
|
||||
|
||||
void InitAsDefaultInstance();
|
||||
static EchoRequest* default_instance_;
|
||||
};
|
||||
// ===================================================================
|
||||
|
||||
|
||||
// ===================================================================
|
||||
|
||||
#if !PROTOBUF_INLINE_NOT_IN_HEADERS
|
||||
// EchoRequest
|
||||
|
||||
// optional string message = 1;
|
||||
inline void EchoRequest::clear_message() {
|
||||
message_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline const ::std::string& EchoRequest::message() const {
|
||||
// @@protoc_insertion_point(field_get:echo.EchoRequest.message)
|
||||
return message_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline void EchoRequest::set_message(const ::std::string& value) {
|
||||
|
||||
message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
|
||||
// @@protoc_insertion_point(field_set:echo.EchoRequest.message)
|
||||
}
|
||||
inline void EchoRequest::set_message(const char* value) {
|
||||
|
||||
message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
|
||||
// @@protoc_insertion_point(field_set_char:echo.EchoRequest.message)
|
||||
}
|
||||
inline void EchoRequest::set_message(const char* value, size_t size) {
|
||||
|
||||
message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
|
||||
::std::string(reinterpret_cast<const char*>(value), size));
|
||||
// @@protoc_insertion_point(field_set_pointer:echo.EchoRequest.message)
|
||||
}
|
||||
inline ::std::string* EchoRequest::mutable_message() {
|
||||
|
||||
// @@protoc_insertion_point(field_mutable:echo.EchoRequest.message)
|
||||
return message_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline ::std::string* EchoRequest::release_message() {
|
||||
|
||||
return message_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline void EchoRequest::set_allocated_message(::std::string* message) {
|
||||
if (message != NULL) {
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
message_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), message);
|
||||
// @@protoc_insertion_point(field_set_allocated:echo.EchoRequest.message)
|
||||
}
|
||||
|
||||
#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS
|
||||
|
||||
// @@protoc_insertion_point(namespace_scope)
|
||||
|
||||
} // namespace echo
|
||||
|
||||
// @@protoc_insertion_point(global_scope)
|
||||
|
||||
#endif // PROTOBUF_echo_2eproto__INCLUDED
|
13
examples/echo/echo-python/echo_client.py
Normal file
13
examples/echo/echo-python/echo_client.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
from grpc.beta import implementations
|
||||
|
||||
import echo_pb2
|
||||
|
||||
def main():
|
||||
for _ in xrange(1000):
|
||||
channel = implementations.insecure_channel('localhost', 50051)
|
||||
stub = echo_pb2.beta_create_Echo_stub(channel)
|
||||
message = echo_pb2.EchoRequest(message='foo')
|
||||
response = stub.DoEcho(message, 15)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
118
examples/echo/echo-python/echo_pb2.py
Normal file
118
examples/echo/echo-python/echo_pb2.py
Normal file
|
@ -0,0 +1,118 @@
|
|||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: echo.proto
|
||||
|
||||
import sys
|
||||
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from google.protobuf import reflection as _reflection
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
from google.protobuf import descriptor_pb2
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
||||
name='echo.proto',
|
||||
package='echo',
|
||||
syntax='proto3',
|
||||
serialized_pb=_b('\n\necho.proto\x12\x04\x65\x63ho\"\x1e\n\x0b\x45\x63hoRequest\x12\x0f\n\x07message\x18\x01 \x01(\t28\n\x04\x45\x63ho\x12\x30\n\x06\x44oEcho\x12\x11.echo.EchoRequest\x1a\x11.echo.EchoRequest\"\x00\x62\x06proto3')
|
||||
)
|
||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
||||
|
||||
|
||||
|
||||
|
||||
_ECHOREQUEST = _descriptor.Descriptor(
|
||||
name='EchoRequest',
|
||||
full_name='echo.EchoRequest',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='message', full_name='echo.EchoRequest.message', index=0,
|
||||
number=1, type=9, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
options=None),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=20,
|
||||
serialized_end=50,
|
||||
)
|
||||
|
||||
DESCRIPTOR.message_types_by_name['EchoRequest'] = _ECHOREQUEST
|
||||
|
||||
EchoRequest = _reflection.GeneratedProtocolMessageType('EchoRequest', (_message.Message,), dict(
|
||||
DESCRIPTOR = _ECHOREQUEST,
|
||||
__module__ = 'echo_pb2'
|
||||
# @@protoc_insertion_point(class_scope:echo.EchoRequest)
|
||||
))
|
||||
_sym_db.RegisterMessage(EchoRequest)
|
||||
|
||||
|
||||
import abc
|
||||
from grpc.beta import implementations as beta_implementations
|
||||
from grpc.framework.common import cardinality
|
||||
from grpc.framework.interfaces.face import utilities as face_utilities
|
||||
|
||||
class BetaEchoServicer(object):
|
||||
"""<fill me in later!>"""
|
||||
__metaclass__ = abc.ABCMeta
|
||||
@abc.abstractmethod
|
||||
def DoEcho(self, request, context):
|
||||
raise NotImplementedError()
|
||||
|
||||
class BetaEchoStub(object):
|
||||
"""The interface to which stubs will conform."""
|
||||
__metaclass__ = abc.ABCMeta
|
||||
@abc.abstractmethod
|
||||
def DoEcho(self, request, timeout):
|
||||
raise NotImplementedError()
|
||||
DoEcho.future = None
|
||||
|
||||
def beta_create_Echo_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None):
|
||||
import echo_pb2
|
||||
import echo_pb2
|
||||
request_deserializers = {
|
||||
('echo.Echo', 'DoEcho'): echo_pb2.EchoRequest.FromString,
|
||||
}
|
||||
response_serializers = {
|
||||
('echo.Echo', 'DoEcho'): echo_pb2.EchoRequest.SerializeToString,
|
||||
}
|
||||
method_implementations = {
|
||||
('echo.Echo', 'DoEcho'): face_utilities.unary_unary_inline(servicer.DoEcho),
|
||||
}
|
||||
server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout)
|
||||
return beta_implementations.server(method_implementations, options=server_options)
|
||||
|
||||
def beta_create_Echo_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None):
|
||||
import echo_pb2
|
||||
import echo_pb2
|
||||
request_serializers = {
|
||||
('echo.Echo', 'DoEcho'): echo_pb2.EchoRequest.SerializeToString,
|
||||
}
|
||||
response_deserializers = {
|
||||
('echo.Echo', 'DoEcho'): echo_pb2.EchoRequest.FromString,
|
||||
}
|
||||
cardinalities = {
|
||||
'DoEcho': cardinality.Cardinality.UNARY_UNARY,
|
||||
}
|
||||
stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size)
|
||||
return beta_implementations.dynamic_stub(channel, 'echo.Echo', cardinalities, options=stub_options)
|
||||
# @@protoc_insertion_point(module_scope)
|
20
examples/echo/echo-python/echo_server.py
Normal file
20
examples/echo/echo-python/echo_server.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
from grpc.beta import implementations
|
||||
|
||||
import echo_pb2
|
||||
import time
|
||||
|
||||
class Echo(echo_pb2.BetaEchoServicer):
|
||||
def DoEcho(self, request, context):
|
||||
return echo_pb2.EchoRequest(message=request.message)
|
||||
|
||||
def main():
|
||||
server = echo_pb2.beta_create_Echo_server(Echo())
|
||||
server.add_insecure_port('[::]:50051')
|
||||
server.start()
|
||||
try:
|
||||
time.sleep(600)
|
||||
except KeyboardInterrupt:
|
||||
server.stop(0)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
64
examples/echo/echo-server/Main.hs
Normal file
64
examples/echo/echo-server/Main.hs
Normal file
|
@ -0,0 +1,64 @@
|
|||
{-# LANGUAGE OverloadedStrings #-}
|
||||
|
||||
import Control.Concurrent.Async (async, wait)
|
||||
import Control.Monad (forever)
|
||||
import Data.ByteString (ByteString)
|
||||
import qualified Data.Map as M
|
||||
import Network.GRPC.LowLevel
|
||||
|
||||
|
||||
serverMeta :: MetadataMap
|
||||
serverMeta = M.fromList [("test_meta", "test_meta_value")]
|
||||
|
||||
handler :: ByteString -> MetadataMap -> MethodName
|
||||
-> IO (ByteString, MetadataMap, StatusDetails)
|
||||
handler reqBody reqMeta method = do
|
||||
--putStrLn $ "Got request for method: " ++ show method
|
||||
--putStrLn $ "Got metadata: " ++ show reqMeta
|
||||
return (reqBody, serverMeta, StatusDetails "")
|
||||
|
||||
unregMain :: IO ()
|
||||
unregMain = withGRPC $ \grpc -> do
|
||||
withServer grpc (ServerConfig "localhost" 50051 []) $ \server -> forever $ do
|
||||
result <- serverHandleNormalCall server 15 serverMeta handler
|
||||
case result of
|
||||
Left x -> putStrLn $ "handle call result error: " ++ show x
|
||||
Right _ -> return ()
|
||||
|
||||
regMain :: IO ()
|
||||
regMain = withGRPC $ \grpc -> do
|
||||
let methods = [(MethodName "/echo.Echo/DoEcho", Normal)]
|
||||
withServer grpc (ServerConfig "localhost" 50051 methods) $ \server ->
|
||||
forever $ do
|
||||
let method = head (registeredMethods server)
|
||||
result <- serverHandleNormalRegisteredCall server method 15 serverMeta $
|
||||
\reqBody _reqMeta -> return (reqBody, serverMeta, serverMeta,
|
||||
StatusDetails "")
|
||||
case result of
|
||||
Left x -> putStrLn $ "registered call result error: " ++ show x
|
||||
Right _ -> return ()
|
||||
|
||||
-- | loop to fork n times
|
||||
regLoop :: Server -> RegisteredMethod -> IO ()
|
||||
regLoop server method = forever $ do
|
||||
result <- serverHandleNormalRegisteredCall server method 15 serverMeta $
|
||||
\reqBody _reqMeta -> return (reqBody, serverMeta, serverMeta,
|
||||
StatusDetails "")
|
||||
case result of
|
||||
Left x -> putStrLn $ "registered call result error: " ++ show x
|
||||
Right _ -> return ()
|
||||
|
||||
regMainThreaded :: IO ()
|
||||
regMainThreaded = do
|
||||
withGRPC $ \grpc -> do
|
||||
let methods = [(MethodName "/echo.Echo/DoEcho", Normal)]
|
||||
withServer grpc (ServerConfig "localhost" 50051 methods) $ \server -> do
|
||||
let method = head (registeredMethods server)
|
||||
tid1 <- async $ regLoop server method
|
||||
tid2 <- async $ regLoop server method
|
||||
wait tid1
|
||||
wait tid2
|
||||
return ()
|
||||
|
||||
main :: IO ()
|
||||
main = regMainThreaded
|
11
examples/echo/echo.proto
Normal file
11
examples/echo/echo.proto
Normal file
|
@ -0,0 +1,11 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package echo;
|
||||
|
||||
service Echo {
|
||||
rpc DoEcho (EchoRequest) returns (EchoRequest) {}
|
||||
}
|
||||
|
||||
message EchoRequest {
|
||||
string message = 1;
|
||||
}
|
|
@ -18,6 +18,11 @@ Flag Debug
|
|||
Manual: True
|
||||
Default: False
|
||||
|
||||
flag with-examples
|
||||
description: Also build example executables.
|
||||
manual: True
|
||||
default: False
|
||||
|
||||
library
|
||||
build-depends:
|
||||
base ==4.8.*
|
||||
|
@ -65,6 +70,35 @@ library
|
|||
CPP-Options: -DDEBUG
|
||||
CC-Options: -DGRPC_HASKELL_DEBUG
|
||||
|
||||
executable echo-server
|
||||
if flag(with-examples)
|
||||
build-depends:
|
||||
base ==4.8.*
|
||||
, bytestring == 0.10.*
|
||||
, grpc-haskell
|
||||
, containers ==0.5.*
|
||||
, async
|
||||
else
|
||||
buildable: False
|
||||
default-language: Haskell2010
|
||||
ghc-options: -Wall -g -threaded
|
||||
hs-source-dirs: examples/echo/echo-server
|
||||
main-is: Main.hs
|
||||
|
||||
executable echo-client
|
||||
if flag(with-examples)
|
||||
build-depends:
|
||||
base ==4.8.*
|
||||
, bytestring == 0.10.*
|
||||
, grpc-haskell
|
||||
, containers ==0.5.*
|
||||
else
|
||||
buildable: False
|
||||
default-language: Haskell2010
|
||||
ghc-options: -Wall -g -threaded
|
||||
hs-source-dirs: examples/echo/echo-client
|
||||
main-is: Main.hs
|
||||
|
||||
test-suite test
|
||||
build-depends:
|
||||
base ==4.8.*
|
||||
|
|
|
@ -22,6 +22,9 @@ GRPC
|
|||
, GRPCMethodType(..)
|
||||
, RegisteredMethod
|
||||
, NormalRequestResult(..)
|
||||
, MetadataMap
|
||||
, MethodName(..)
|
||||
, StatusDetails(..)
|
||||
|
||||
-- * Server
|
||||
, ServerConfig(..)
|
||||
|
@ -53,7 +56,6 @@ GRPC
|
|||
, runServerUnregOps
|
||||
, Op(..)
|
||||
, OpRecvResult(..)
|
||||
, StatusDetails(..)
|
||||
|
||||
) where
|
||||
|
||||
|
|
|
@ -90,6 +90,10 @@ serverUnregCallGetMethodName :: ServerUnregCall -> IO MethodName
|
|||
serverUnregCallGetMethodName ServerUnregCall{..} =
|
||||
MethodName <$> C.callDetailsGetMethod callDetails
|
||||
|
||||
serverUnregCallGetHost :: ServerUnregCall -> IO Host
|
||||
serverUnregCallGetHost ServerUnregCall{..} =
|
||||
Host <$> C.callDetailsGetHost callDetails
|
||||
|
||||
debugClientCall :: ClientCall -> IO ()
|
||||
{-# INLINE debugClientCall #-}
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -35,7 +35,7 @@ data ServerConfig =
|
|||
-- how this is used. Setting to "localhost" works fine in tests.
|
||||
port :: Int,
|
||||
-- ^ Port to listen for requests on.
|
||||
methodsToRegister :: [(MethodName, Host, GRPCMethodType)]
|
||||
methodsToRegister :: [(MethodName, GRPCMethodType)]
|
||||
-- ^ List of (method name, method host, method type) tuples
|
||||
-- specifying all methods to register. You can also handle
|
||||
-- other unregistered methods with `serverHandleNormalCall`.
|
||||
|
@ -51,8 +51,8 @@ startServer grpc ServerConfig{..} = do
|
|||
cq <- createCompletionQueue grpc
|
||||
serverRegisterCompletionQueue server cq
|
||||
methods <- forM methodsToRegister $
|
||||
\(name, host, mtype) ->
|
||||
serverRegisterMethod server name host mtype
|
||||
\(name, mtype) ->
|
||||
serverRegisterMethod server name (Host hostPort) mtype
|
||||
C.grpcServerStart server
|
||||
return $ Server server cq methods
|
||||
|
||||
|
@ -249,6 +249,8 @@ serverHandleNormalCall s@Server{..} timeLimit srvMetadata f = do
|
|||
requestMeta <- serverUnregCallGetMetadata call
|
||||
grpcDebug $ "got client metadata: " ++ show requestMeta
|
||||
methodName <- serverUnregCallGetMethodName call
|
||||
hostName <- serverUnregCallGetHost call
|
||||
grpcDebug $ "call_details host is: " ++ show hostName
|
||||
(respBody, respMetadata, details) <- f body requestMeta methodName
|
||||
let status = C.GrpcStatusOk
|
||||
let respOps = serverOpsSendNormalResponse
|
||||
|
|
|
@ -44,7 +44,7 @@ testClientCreateDestroy =
|
|||
|
||||
payloadLowLevelServer :: TestServer
|
||||
payloadLowLevelServer = TestServer $ \grpc -> do
|
||||
let conf = (ServerConfig "localhost" 50051 [("/foo", "localhost", Normal)])
|
||||
let conf = (ServerConfig "localhost" 50051 [("/foo", Normal)])
|
||||
withServer grpc conf $ \server -> do
|
||||
let method = head (registeredMethods server)
|
||||
result <- serverHandleNormalRegisteredCall server method 11 M.empty $
|
||||
|
@ -109,7 +109,7 @@ testClientRequestNoServer =
|
|||
testServerAwaitNoClient :: TestTree
|
||||
testServerAwaitNoClient = testCase "server wait times out when no client " $ do
|
||||
withGRPC $ \grpc -> do
|
||||
let conf = (ServerConfig "localhost" 50051 [("/foo", "localhost", Normal)])
|
||||
let conf = (ServerConfig "localhost" 50051 [("/foo", Normal)])
|
||||
withServer grpc conf $ \server -> do
|
||||
let method = head (registeredMethods server)
|
||||
result <- serverHandleNormalRegisteredCall server method 1 M.empty $
|
||||
|
|
Loading…
Reference in a new issue