├── .gitignore ├── EchoClient.cc ├── EchoEndpoint.hh ├── EchoServer.cc ├── LICENSE ├── Makefile ├── README.md ├── RpcChannel.cc ├── RpcChannel.hh ├── RpcMethod.hpp ├── RpcServer.cc ├── RpcServer.hh ├── echo.pb.cc ├── echo.pb.h ├── echo.proto └── nn.hpp /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | 6 | # Compiled Dynamic libraries 7 | *.so 8 | *.dylib 9 | 10 | # Compiled Static libraries 11 | *.lai 12 | *.la 13 | *.a 14 | 15 | # Added 16 | echo_client 17 | echo_server 18 | .libs 19 | RCS 20 | -------------------------------------------------------------------------------- /EchoClient.cc: -------------------------------------------------------------------------------- 1 | /** 2 | * @project nanorpc 3 | * @file EchoClient.cc 4 | * @author S Roychowdhury 5 | * @version 1.0 6 | * 7 | * @section LICENSE 8 | * 9 | * Copyright (c) 2013 S Roychowdhury 10 | * 11 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 12 | * this software and associated documentation files (the "Software"), to deal in 13 | * the Software without restriction, including without limitation the rights to 14 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 15 | * the Software, and to permit persons to whom the Software is furnished to do so, 16 | * subject to the following conditions: 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 20 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 22 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | * @section DESCRIPTION 26 | * 27 | * example: echo client 28 | * 29 | */ 30 | 31 | #include 32 | #include "RpcChannel.hh" 33 | #include "echo.pb.h" 34 | 35 | #include "EchoEndpoint.hh" 36 | 37 | int main(int argc, char *argv[]) 38 | { 39 | try { 40 | echo::EchoRequest request; 41 | nrpc::RpcChannel rpc_channel(ECHO_ENDPOINT_PORT); 42 | echo::EchoService::Stub stub(&rpc_channel); 43 | echo::EchoResponse response; 44 | request.set_message("123456789012345678901234567890123456"); 45 | stub.Echo1(NULL, &request, &response, NULL); 46 | std::cerr << response.response().c_str() << std::endl; 47 | request.set_message("654321098765432109876543210987654321"); 48 | stub.Echo2(NULL, &request, &response, NULL); 49 | std::cerr << response.response().c_str() << std::endl; 50 | 51 | } catch (nn::exception& e) { 52 | std::cerr << "NN EXCEPTION : " << e.what() << std::endl; 53 | } catch (std::exception& e) { 54 | std::cerr << "STD EXCEPTION : " << e.what() << std::endl; 55 | } catch (...) { 56 | std::cerr << " UNTRAPPED EXCEPTION " << std::endl; 57 | } 58 | return 0; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /EchoEndpoint.hh: -------------------------------------------------------------------------------- 1 | /** 2 | * @project nanorpc 3 | * @file EchoCommon.hh 4 | * @author S Roychowdhury 5 | * @version 1.0 6 | * 7 | * @section LICENSE 8 | * 9 | * Copyright (c) 2013 S Roychowdhury 10 | * 11 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 12 | * this software and associated documentation files (the "Software"), to deal in 13 | * the Software without restriction, including without limitation the rights to 14 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 15 | * the Software, and to permit persons to whom the Software is furnished to do so, 16 | * subject to the following conditions: 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 20 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 22 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | * @section DESCRIPTION 26 | * 27 | * example: echo endpoint only 28 | * 29 | */ 30 | #ifndef _NRPC_ECHO_ENDPOINT_HH_ 31 | #define _NRPC_ECHO_ENDPOINT_HH_ 32 | 33 | #define ECHO_ENDPOINT_PORT "tcp://127.0.0.1:9999" 34 | #define ECHO_ENDPOINT_FILE "ipc:///tmp/echo.sock" 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /EchoServer.cc: -------------------------------------------------------------------------------- 1 | /** 2 | * @project nanorpc 3 | * @file EchoServer.cc 4 | * @author S Roychowdhury 5 | * @version 1.0 6 | * 7 | * @section LICENSE 8 | * 9 | * Copyright (c) 2013 S Roychowdhury 10 | * 11 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 12 | * this software and associated documentation files (the "Software"), to deal in 13 | * the Software without restriction, including without limitation the rights to 14 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 15 | * the Software, and to permit persons to whom the Software is furnished to do so, 16 | * subject to the following conditions: 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 20 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 22 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | * @section DESCRIPTION 26 | * 27 | * example: echo server 28 | * 29 | */ 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include "RpcServer.hh" 35 | #include "echo.pb.h" 36 | #include "EchoEndpoint.hh" 37 | 38 | class EchoServiceImpl : public echo::EchoService { 39 | public: 40 | EchoServiceImpl() {}; 41 | 42 | virtual void Echo1(::google::protobuf::RpcController* controller, 43 | const ::echo::EchoRequest* request, 44 | ::echo::EchoResponse* response, 45 | ::google::protobuf::Closure* done) { 46 | std::cerr << "Received1: " << request->message().c_str() << std::endl; 47 | response->set_response(std::string("You sent1: ") + request->message()); 48 | if (done) { 49 | done->Run(); 50 | } 51 | } 52 | virtual void Echo2(::google::protobuf::RpcController* controller, 53 | const ::echo::EchoRequest* request, 54 | ::echo::EchoResponse* response, 55 | ::google::protobuf::Closure* done) { 56 | std::cerr << "Received2: " << request->message().c_str() << std::endl; 57 | response->set_response(std::string("You sent2: ") + request->message()); 58 | if (done) { 59 | done->Run(); 60 | } 61 | } 62 | }; 63 | 64 | void OnExit(int sig) 65 | { 66 | std::cerr << "Exiting on ^C " << sig << std::endl; 67 | } 68 | 69 | int main(int argc, char *argv[]) 70 | { 71 | signal(SIGINT, OnExit); 72 | try { 73 | nrpc::RpcServer rpc_server(ECHO_ENDPOINT_PORT); 74 | ::google::protobuf::Service *service = new EchoServiceImpl(); 75 | rpc_server.RegisterService(service); 76 | rpc_server.Start(); 77 | } catch (nn::exception& e) { 78 | std::cerr << "NN EXCEPTION : " << e.what() << std::endl; 79 | } catch (std::exception& e) { 80 | std::cerr << "STD EXCEPTION : " << e.what() << std::endl; 81 | } catch (...) { 82 | std::cerr << " UNTRAPPED EXCEPTION " << std::endl; 83 | } 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 R Roychowdhury 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ## NanoRPC 2 | CC = g++ 3 | CCFLAGS = -ansi -Wall -Wno-deprecated -O2 -DNDEBUG 4 | CCFLAGS += -I/opt/local/include 5 | CCFLAGS += -I/usr/local/include 6 | LDFLAGS = -rdynamic 7 | LDFLAGS += -L/opt/local/lib 8 | LDFLAGS += -L/usr/local/lib 9 | 10 | PROTOC = protoc 11 | MKDIR = mkdir -p 12 | 13 | PROTO_INCLUDE = -I/opt/local/include 14 | PROTO_LDFLAGS = -L/opt/local/lib -lprotobuf 15 | 16 | NANOMSG_INCLUDE = -I/usr/local/include 17 | NANOMSG_LDFLAGS = -L/usr/local/lib -lnanomsg 18 | 19 | CITYHASH_INCLUDE = -I/usr/local/include 20 | CITYHASH_LDFLAGS = -L/usr/local/lib -lcityhash 21 | 22 | USE_LDFLAGS = $(PROTO_LDFLAGS) $(CITYHASH_LDFLAGS) $(NANOMSG_LDFLAGS) 23 | 24 | TMPLIB = .libs 25 | 26 | SERVER_SOURCES = $(TMPLIB)/Server.o $(TMPLIB)/echo.pb.o 27 | CHANNEL_SOURCES = $(TMPLIB)/Channel.o $(TMPLIB)/echo.pb.o 28 | 29 | all: mkdir echo_client echo_server 30 | 31 | mkdir: 32 | $(MKDIR) $(TMPLIB) 33 | 34 | echo_client: $(CHANNEL_SOURCES) $(TMPLIB)/EchoClient.o 35 | $(CC) $(CCFLAGS) $(LDFLAGS) $(USE_LDFLAGS) -o echo_client $(CHANNEL_SOURCES) $(TMPLIB)/EchoClient.o 36 | 37 | echo_server: $(SERVER_SOURCES) $(TMPLIB)/EchoServer.o 38 | $(CC) $(CCFLAGS) $(LDFLAGS) $(USE_LDFLAGS) -o echo_server $(SERVER_SOURCES) $(TMPLIB)/EchoServer.o 39 | 40 | $(TMPLIB)/Channel.o: RpcChannel.cc RpcChannel.hh 41 | $(CC) -c $(CCFLAGS) RpcChannel.cc -o $(TMPLIB)/Channel.o 42 | 43 | $(TMPLIB)/Server.o: RpcServer.cc RpcServer.hh 44 | $(CC) -c $(CCFLAGS) RpcServer.cc -o $(TMPLIB)/Server.o 45 | 46 | $(TMPLIB)/EchoClient.o: EchoClient.cc EchoEndpoint.hh 47 | $(CC) -c $(CCFLAGS) EchoClient.cc -o $(TMPLIB)/EchoClient.o 48 | 49 | $(TMPLIB)/EchoServer.o: EchoServer.cc EchoEndpoint.hh 50 | $(CC) -c $(CCFLAGS) EchoServer.cc -o $(TMPLIB)/EchoServer.o 51 | 52 | $(TMPLIB)/echo.pb.o: echo.pb.cc echo.pb.h 53 | $(CC) -c $(CCFLAGS) echo.pb.cc -o $(TMPLIB)/echo.pb.o 54 | 55 | echo.pb.cc echo.pb.h: echo.proto 56 | $(PROTOC) --cpp_out=. echo.proto 57 | 58 | clean: 59 | rm -f echo_client echo_server $(TMPLIB)/*.o 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | nanorpc 2 | ======= 3 | 4 | Protobuf RPC implementation using nanomsg 5 | 6 | 7 | Requirements 8 | ------------ 9 | 10 | You will need nanomsg , protobuf and cityhash 11 | 12 | https://github.com/nanomsg/nanomsg.git 13 | 14 | http://code.google.com/p/protobuf/downloads/list 15 | 16 | http://code.google.com/p/cityhash/downloads/list 17 | 18 | Please edit the makefile to include location of these properly 19 | -------------------------------------------------------------------------------- /RpcChannel.cc: -------------------------------------------------------------------------------- 1 | /** 2 | * @project nanorpc 3 | * @file RpcChannel.cc 4 | * @author S Roychowdhury 5 | * @version 1.0 6 | * 7 | * @section LICENSE 8 | * 9 | * Copyright (c) 2013 S Roychowdhury 10 | * 11 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 12 | * this software and associated documentation files (the "Software"), to deal in 13 | * the Software without restriction, including without limitation the rights to 14 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 15 | * the Software, and to permit persons to whom the Software is furnished to do so, 16 | * subject to the following conditions: 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 20 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 22 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | * @section DESCRIPTION 26 | * 27 | * Channel Implementation for client 28 | * 29 | */ 30 | #include 31 | #include "RpcChannel.hh" 32 | #include 33 | #include 34 | 35 | nrpc::RpcChannel::RpcChannel(const char* url) : 36 | sock(AF_SP, NN_REQ), 37 | sockid(sock.connect(url)) 38 | { 39 | } 40 | 41 | nrpc::RpcChannel::~RpcChannel() 42 | { 43 | Close(); 44 | } 45 | 46 | void nrpc::RpcChannel::CallMethod(const google::protobuf::MethodDescriptor* method, 47 | google::protobuf::RpcController* controller, 48 | const google::protobuf::Message* request, 49 | google::protobuf::Message* response, 50 | google::protobuf::Closure* done) 51 | { 52 | std::string methodname=std::string(method->full_name()); 53 | uint64_t opcode = ::CityHash64(methodname.c_str(),methodname.length()); 54 | size_t msg_len = request->ByteSize() + sizeof(opcode); 55 | char* buf=NULL; 56 | buf = (char*)nn::allocmsg(msg_len,0); 57 | memcpy(buf, &opcode, sizeof(opcode)); 58 | request->SerializeToArray(buf + sizeof(opcode), request->ByteSize()); 59 | sock.send(buf,msg_len,0); 60 | nn::freemsg(buf); 61 | sock.recv(&buf, NN_MSG, 0); 62 | response->ParseFromString(buf); 63 | nn::freemsg(buf); 64 | } 65 | 66 | void nrpc::RpcChannel::Close() 67 | { 68 | if (sockid>0) { 69 | sock.shutdown (0); 70 | sockid=0; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /RpcChannel.hh: -------------------------------------------------------------------------------- 1 | /** 2 | * @project nanorpc 3 | * @file RpcChannel.hh 4 | * @author S Roychowdhury 5 | * @version 1.0 6 | * 7 | * @section LICENSE 8 | * 9 | * Copyright (c) 2013 S Roychowdhury 10 | * 11 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 12 | * this software and associated documentation files (the "Software"), to deal in 13 | * the Software without restriction, including without limitation the rights to 14 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 15 | * the Software, and to permit persons to whom the Software is furnished to do so, 16 | * subject to the following conditions: 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 20 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 22 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | * @section DESCRIPTION 26 | * 27 | * RpcChannel Headers for client 28 | * 29 | */ 30 | #ifndef _NRPC_CHANNEL_HH_ 31 | #define _NRPC_CHANNEL_HH_ 32 | #include 33 | #include 34 | #include "nn.hpp" 35 | #include 36 | #include 37 | #include 38 | 39 | namespace nrpc { 40 | class RpcChannel : public google::protobuf::RpcChannel { 41 | public: 42 | RpcChannel(const char* url); 43 | virtual ~RpcChannel(); 44 | virtual void CallMethod(const google::protobuf::MethodDescriptor* method, 45 | google::protobuf::RpcController* controller, 46 | const google::protobuf::Message* request, 47 | google::protobuf::Message* response, 48 | google::protobuf::Closure* done); 49 | 50 | void Close(); 51 | private: 52 | nn::socket sock; 53 | int sockid; 54 | }; 55 | } 56 | #endif 57 | -------------------------------------------------------------------------------- /RpcMethod.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @project nanorpc 3 | * @file RpcMethod.hpp 4 | * @author S Roychowdhury 5 | * @version 1.0 6 | * 7 | * @section LICENSE 8 | * 9 | * Copyright (c) 2013 S Roychowdhury 10 | * 11 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 12 | * this software and associated documentation files (the "Software"), to deal in 13 | * the Software without restriction, including without limitation the rights to 14 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 15 | * the Software, and to permit persons to whom the Software is furnished to do so, 16 | * subject to the following conditions: 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 20 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 22 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | * @section DESCRIPTION 26 | * 27 | * RpcMethod: definition of PB Rpc Method 28 | * 29 | */ 30 | #ifndef _NRPC_RPCMETHOD_HPP_ 31 | #define _NRPC_RPCMETHOD_HPP_ 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | namespace nrpc { 39 | struct RpcMethod { 40 | public: 41 | RpcMethod(google::protobuf::Service *service, 42 | const google::protobuf::Message *request, 43 | const google::protobuf::Message *response, 44 | const google::protobuf::MethodDescriptor *method) 45 | : service_(service), 46 | request_(request), 47 | response_(response), 48 | method_(method) { 49 | } 50 | 51 | google::protobuf::Service *service_; 52 | const google::protobuf::Message *request_; 53 | const google::protobuf::Message *response_; 54 | const google::protobuf::MethodDescriptor *method_; 55 | }; 56 | 57 | } // namespace 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /RpcServer.cc: -------------------------------------------------------------------------------- 1 | /** 2 | * @project nanorpc 3 | * @file RpcServer.cc 4 | * @author S Roychowdhury 5 | * @version 1.0 6 | * 7 | * @section LICENSE 8 | * 9 | * Copyright (c) 2013 S Roychowdhury 10 | * 11 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 12 | * this software and associated documentation files (the "Software"), to deal in 13 | * the Software without restriction, including without limitation the rights to 14 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 15 | * the Software, and to permit persons to whom the Software is furnished to do so, 16 | * subject to the following conditions: 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 20 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 22 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | * @section DESCRIPTION 26 | * 27 | * RpcServer Implementation 28 | * 29 | */ 30 | #include 31 | #include 32 | #include 33 | #include "RpcServer.hh" 34 | #include 35 | 36 | nrpc::RpcServer::RpcServer(const char* url) : 37 | sock(AF_SP, NN_REP), 38 | sockid(sock.bind(url)) 39 | { 40 | } 41 | 42 | nrpc::RpcServer::~RpcServer() 43 | { 44 | RemoveService(); 45 | Close(); 46 | } 47 | 48 | void nrpc::RpcServer::EndPoint(const char* url) 49 | { 50 | sock.bind(url); 51 | } 52 | 53 | void nrpc::RpcServer::RegisterService(google::protobuf::Service *service) 54 | { 55 | const google::protobuf::ServiceDescriptor *descriptor = service->GetDescriptor(); 56 | for (int i = 0; i < descriptor->method_count(); ++i) { 57 | const google::protobuf::MethodDescriptor *method = descriptor->method(i); 58 | const google::protobuf::Message *request = &service->GetRequestPrototype(method); 59 | const google::protobuf::Message *response = &service->GetResponsePrototype(method); 60 | RpcMethod *rpc_method = new RpcMethod(service, request, response, method); 61 | std::string methodname=std::string(method->full_name()); 62 | uint64_t hash = ::CityHash64(methodname.c_str(),methodname.length()); 63 | RpcMethodMap::const_iterator iter = rpc_method_map_.find(hash); 64 | if (iter == rpc_method_map_.end()) 65 | rpc_method_map_[hash] = rpc_method; 66 | } 67 | } 68 | 69 | 70 | void nrpc::RpcServer::Start() 71 | { 72 | uint64_t opcode = 0; 73 | while (1) { 74 | char* buf=NULL; 75 | int bytes = sock.recv(&buf, NN_MSG, 0); 76 | if (bytes<=0) continue; 77 | memcpy((char*)(&opcode), buf, sizeof(opcode)); 78 | RpcMethodMap::const_iterator iter = rpc_method_map_.find(opcode); 79 | if (iter == rpc_method_map_.end()) { 80 | continue; 81 | } 82 | RpcMethod *rpc_method = iter->second; 83 | const google::protobuf::MethodDescriptor *method = rpc_method->method_; 84 | google::protobuf::Message *request = rpc_method->request_->New(); 85 | google::protobuf::Message *response = rpc_method->response_->New(); 86 | request->ParseFromString(buf + sizeof(opcode)); 87 | nn::freemsg(buf); 88 | rpc_method->service_->CallMethod(method,NULL,request, response, NULL); 89 | size_t msg_len = response->ByteSize(); 90 | buf = (char*)nn::allocmsg(msg_len,0); 91 | response->SerializeToArray(buf,msg_len); 92 | sock.send(buf,msg_len,0); 93 | delete request; 94 | delete response; 95 | nn::freemsg(buf); 96 | } 97 | } 98 | 99 | void nrpc::RpcServer::RemoveService() 100 | { 101 | RpcMethodMap::iterator iter; 102 | for (RpcMethodMap::iterator it = rpc_method_map_.begin(); it != rpc_method_map_.end();) { 103 | RpcMethod *rpc_method = it->second; 104 | ++it; 105 | delete rpc_method; 106 | } 107 | } 108 | 109 | void nrpc::RpcServer::Close() 110 | { 111 | if (sockid>0) { 112 | sock.shutdown (0); 113 | sockid=0; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /RpcServer.hh: -------------------------------------------------------------------------------- 1 | /** 2 | * @project nanorpc 3 | * @file RpcServer.hh 4 | * @author S Roychowdhury 5 | * @version 1.0 6 | * 7 | * @section LICENSE 8 | * 9 | * Copyright (c) 2013 S Roychowdhury 10 | * 11 | * Permission is hereby granted, free of charge, to any person obtaining a copy of 12 | * this software and associated documentation files (the "Software"), to deal in 13 | * the Software without restriction, including without limitation the rights to 14 | * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 15 | * the Software, and to permit persons to whom the Software is furnished to do so, 16 | * subject to the following conditions: 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 20 | * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 21 | * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 22 | * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | * @section DESCRIPTION 26 | * 27 | * RpcServer Headers 28 | * 29 | */ 30 | #ifndef _NRPC_SERVER_HH_ 31 | #define _NRPC_SERVER_HH_ 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include "nn.hpp" 38 | 39 | #include "RpcMethod.hpp" 40 | 41 | namespace nrpc { 42 | 43 | class RpcServer { 44 | typedef std::map RpcMethodMap; 45 | public: 46 | RpcServer(const char* url); 47 | ~RpcServer(); 48 | // add more endpoints 49 | void EndPoint(const char* url); 50 | // start 51 | void Start(); 52 | // register a service 53 | void RegisterService(google::protobuf::Service *service); 54 | // remove all services 55 | void RemoveService(); 56 | // close 57 | void Close(); 58 | 59 | private: 60 | nn::socket sock; 61 | int sockid; 62 | RpcMethodMap rpc_method_map_; 63 | }; 64 | } 65 | #endif 66 | -------------------------------------------------------------------------------- /echo.pb.cc: -------------------------------------------------------------------------------- 1 | // Generated by the protocol buffer compiler. DO NOT EDIT! 2 | // source: echo.proto 3 | 4 | #define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION 5 | #include "echo.pb.h" 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | // @@protoc_insertion_point(includes) 18 | 19 | namespace echo { 20 | 21 | namespace { 22 | 23 | const ::google::protobuf::Descriptor* EchoRequest_descriptor_ = NULL; 24 | const ::google::protobuf::internal::GeneratedMessageReflection* 25 | EchoRequest_reflection_ = NULL; 26 | const ::google::protobuf::Descriptor* EchoResponse_descriptor_ = NULL; 27 | const ::google::protobuf::internal::GeneratedMessageReflection* 28 | EchoResponse_reflection_ = NULL; 29 | const ::google::protobuf::ServiceDescriptor* EchoService_descriptor_ = NULL; 30 | 31 | } // namespace 32 | 33 | 34 | void protobuf_AssignDesc_echo_2eproto() 35 | { 36 | protobuf_AddDesc_echo_2eproto(); 37 | const ::google::protobuf::FileDescriptor* file = 38 | ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( 39 | "echo.proto"); 40 | GOOGLE_CHECK(file != NULL); 41 | EchoRequest_descriptor_ = file->message_type(0); 42 | static const int EchoRequest_offsets_[1] = { 43 | GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EchoRequest, message_), 44 | }; 45 | EchoRequest_reflection_ = 46 | new ::google::protobuf::internal::GeneratedMessageReflection( 47 | EchoRequest_descriptor_, 48 | EchoRequest::default_instance_, 49 | EchoRequest_offsets_, 50 | GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EchoRequest, _has_bits_[0]), 51 | GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EchoRequest, _unknown_fields_), 52 | -1, 53 | ::google::protobuf::DescriptorPool::generated_pool(), 54 | ::google::protobuf::MessageFactory::generated_factory(), 55 | sizeof(EchoRequest)); 56 | EchoResponse_descriptor_ = file->message_type(1); 57 | static const int EchoResponse_offsets_[1] = { 58 | GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EchoResponse, response_), 59 | }; 60 | EchoResponse_reflection_ = 61 | new ::google::protobuf::internal::GeneratedMessageReflection( 62 | EchoResponse_descriptor_, 63 | EchoResponse::default_instance_, 64 | EchoResponse_offsets_, 65 | GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EchoResponse, _has_bits_[0]), 66 | GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EchoResponse, _unknown_fields_), 67 | -1, 68 | ::google::protobuf::DescriptorPool::generated_pool(), 69 | ::google::protobuf::MessageFactory::generated_factory(), 70 | sizeof(EchoResponse)); 71 | EchoService_descriptor_ = file->service(0); 72 | } 73 | 74 | namespace { 75 | 76 | GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); 77 | inline void protobuf_AssignDescriptorsOnce() 78 | { 79 | ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, 80 | &protobuf_AssignDesc_echo_2eproto); 81 | } 82 | 83 | void protobuf_RegisterTypes(const ::std::string&) 84 | { 85 | protobuf_AssignDescriptorsOnce(); 86 | ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( 87 | EchoRequest_descriptor_, &EchoRequest::default_instance()); 88 | ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( 89 | EchoResponse_descriptor_, &EchoResponse::default_instance()); 90 | } 91 | 92 | } // namespace 93 | 94 | void protobuf_ShutdownFile_echo_2eproto() 95 | { 96 | delete EchoRequest::default_instance_; 97 | delete EchoRequest_reflection_; 98 | delete EchoResponse::default_instance_; 99 | delete EchoResponse_reflection_; 100 | } 101 | 102 | void protobuf_AddDesc_echo_2eproto() 103 | { 104 | static bool already_here = false; 105 | if (already_here) return; 106 | already_here = true; 107 | GOOGLE_PROTOBUF_VERIFY_VERSION; 108 | 109 | ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( 110 | "\n\necho.proto\022\004echo\"\036\n\013EchoRequest\022\017\n\007mes" 111 | "sage\030\001 \002(\t\" \n\014EchoResponse\022\020\n\010response\030\001" 112 | " \002(\t2m\n\013EchoService\022.\n\005Echo1\022\021.echo.Echo" 113 | "Request\032\022.echo.EchoResponse\022.\n\005Echo2\022\021.e" 114 | "cho.EchoRequest\032\022.echo.EchoResponseB\003\200\001\001", 200); 115 | ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( 116 | "echo.proto", &protobuf_RegisterTypes); 117 | EchoRequest::default_instance_ = new EchoRequest(); 118 | EchoResponse::default_instance_ = new EchoResponse(); 119 | EchoRequest::default_instance_->InitAsDefaultInstance(); 120 | EchoResponse::default_instance_->InitAsDefaultInstance(); 121 | ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_echo_2eproto); 122 | } 123 | 124 | // Force AddDescriptors() to be called at static initialization time. 125 | struct StaticDescriptorInitializer_echo_2eproto { 126 | StaticDescriptorInitializer_echo_2eproto() { 127 | protobuf_AddDesc_echo_2eproto(); 128 | } 129 | } static_descriptor_initializer_echo_2eproto_; 130 | 131 | // =================================================================== 132 | 133 | #ifndef _MSC_VER 134 | const int EchoRequest::kMessageFieldNumber; 135 | #endif // !_MSC_VER 136 | 137 | EchoRequest::EchoRequest() 138 | : ::google::protobuf::Message() 139 | { 140 | SharedCtor(); 141 | } 142 | 143 | void EchoRequest::InitAsDefaultInstance() 144 | { 145 | } 146 | 147 | EchoRequest::EchoRequest(const EchoRequest& from) 148 | : ::google::protobuf::Message() 149 | { 150 | SharedCtor(); 151 | MergeFrom(from); 152 | } 153 | 154 | void EchoRequest::SharedCtor() 155 | { 156 | _cached_size_ = 0; 157 | message_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); 158 | ::memset(_has_bits_, 0, sizeof(_has_bits_)); 159 | } 160 | 161 | EchoRequest::~EchoRequest() 162 | { 163 | SharedDtor(); 164 | } 165 | 166 | void EchoRequest::SharedDtor() 167 | { 168 | if (message_ != &::google::protobuf::internal::kEmptyString) { 169 | delete message_; 170 | } 171 | if (this != default_instance_) { 172 | } 173 | } 174 | 175 | void EchoRequest::SetCachedSize(int size) const 176 | { 177 | GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); 178 | _cached_size_ = size; 179 | GOOGLE_SAFE_CONCURRENT_WRITES_END(); 180 | } 181 | const ::google::protobuf::Descriptor* EchoRequest::descriptor() 182 | { 183 | protobuf_AssignDescriptorsOnce(); 184 | return EchoRequest_descriptor_; 185 | } 186 | 187 | const EchoRequest& EchoRequest::default_instance() 188 | { 189 | if (default_instance_ == NULL) protobuf_AddDesc_echo_2eproto(); 190 | return *default_instance_; 191 | } 192 | 193 | EchoRequest* EchoRequest::default_instance_ = NULL; 194 | 195 | EchoRequest* EchoRequest::New() const 196 | { 197 | return new EchoRequest; 198 | } 199 | 200 | void EchoRequest::Clear() 201 | { 202 | if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { 203 | if (has_message()) { 204 | if (message_ != &::google::protobuf::internal::kEmptyString) { 205 | message_->clear(); 206 | } 207 | } 208 | } 209 | ::memset(_has_bits_, 0, sizeof(_has_bits_)); 210 | mutable_unknown_fields()->Clear(); 211 | } 212 | 213 | bool EchoRequest::MergePartialFromCodedStream( 214 | ::google::protobuf::io::CodedInputStream* input) 215 | { 216 | #define DO_(EXPRESSION) if (!(EXPRESSION)) return false 217 | ::google::protobuf::uint32 tag; 218 | while ((tag = input->ReadTag()) != 0) { 219 | switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { 220 | // required string message = 1; 221 | case 1: { 222 | if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == 223 | ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { 224 | DO_(::google::protobuf::internal::WireFormatLite::ReadString( 225 | input, this->mutable_message())); 226 | ::google::protobuf::internal::WireFormat::VerifyUTF8String( 227 | this->message().data(), this->message().length(), 228 | ::google::protobuf::internal::WireFormat::PARSE); 229 | } else { 230 | goto handle_uninterpreted; 231 | } 232 | if (input->ExpectAtEnd()) return true; 233 | break; 234 | } 235 | 236 | default: { 237 | handle_uninterpreted: 238 | if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == 239 | ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { 240 | return true; 241 | } 242 | DO_(::google::protobuf::internal::WireFormat::SkipField( 243 | input, tag, mutable_unknown_fields())); 244 | break; 245 | } 246 | } 247 | } 248 | return true; 249 | #undef DO_ 250 | } 251 | 252 | void EchoRequest::SerializeWithCachedSizes( 253 | ::google::protobuf::io::CodedOutputStream* output) const 254 | { 255 | // required string message = 1; 256 | if (has_message()) { 257 | ::google::protobuf::internal::WireFormat::VerifyUTF8String( 258 | this->message().data(), this->message().length(), 259 | ::google::protobuf::internal::WireFormat::SERIALIZE); 260 | ::google::protobuf::internal::WireFormatLite::WriteString( 261 | 1, this->message(), output); 262 | } 263 | 264 | if (!unknown_fields().empty()) { 265 | ::google::protobuf::internal::WireFormat::SerializeUnknownFields( 266 | unknown_fields(), output); 267 | } 268 | } 269 | 270 | ::google::protobuf::uint8* EchoRequest::SerializeWithCachedSizesToArray( 271 | ::google::protobuf::uint8* target) const 272 | { 273 | // required string message = 1; 274 | if (has_message()) { 275 | ::google::protobuf::internal::WireFormat::VerifyUTF8String( 276 | this->message().data(), this->message().length(), 277 | ::google::protobuf::internal::WireFormat::SERIALIZE); 278 | target = 279 | ::google::protobuf::internal::WireFormatLite::WriteStringToArray( 280 | 1, this->message(), target); 281 | } 282 | 283 | if (!unknown_fields().empty()) { 284 | target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( 285 | unknown_fields(), target); 286 | } 287 | return target; 288 | } 289 | 290 | int EchoRequest::ByteSize() const 291 | { 292 | int total_size = 0; 293 | 294 | if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { 295 | // required string message = 1; 296 | if (has_message()) { 297 | total_size += 1 + 298 | ::google::protobuf::internal::WireFormatLite::StringSize( 299 | this->message()); 300 | } 301 | 302 | } 303 | if (!unknown_fields().empty()) { 304 | total_size += 305 | ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( 306 | unknown_fields()); 307 | } 308 | GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); 309 | _cached_size_ = total_size; 310 | GOOGLE_SAFE_CONCURRENT_WRITES_END(); 311 | return total_size; 312 | } 313 | 314 | void EchoRequest::MergeFrom(const ::google::protobuf::Message& from) 315 | { 316 | GOOGLE_CHECK_NE(&from, this); 317 | const EchoRequest* source = 318 | ::google::protobuf::internal::dynamic_cast_if_available( 319 | &from); 320 | if (source == NULL) { 321 | ::google::protobuf::internal::ReflectionOps::Merge(from, this); 322 | } else { 323 | MergeFrom(*source); 324 | } 325 | } 326 | 327 | void EchoRequest::MergeFrom(const EchoRequest& from) 328 | { 329 | GOOGLE_CHECK_NE(&from, this); 330 | if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { 331 | if (from.has_message()) { 332 | set_message(from.message()); 333 | } 334 | } 335 | mutable_unknown_fields()->MergeFrom(from.unknown_fields()); 336 | } 337 | 338 | void EchoRequest::CopyFrom(const ::google::protobuf::Message& from) 339 | { 340 | if (&from == this) return; 341 | Clear(); 342 | MergeFrom(from); 343 | } 344 | 345 | void EchoRequest::CopyFrom(const EchoRequest& from) 346 | { 347 | if (&from == this) return; 348 | Clear(); 349 | MergeFrom(from); 350 | } 351 | 352 | bool EchoRequest::IsInitialized() const 353 | { 354 | if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; 355 | 356 | return true; 357 | } 358 | 359 | void EchoRequest::Swap(EchoRequest* other) 360 | { 361 | if (other != this) { 362 | std::swap(message_, other->message_); 363 | std::swap(_has_bits_[0], other->_has_bits_[0]); 364 | _unknown_fields_.Swap(&other->_unknown_fields_); 365 | std::swap(_cached_size_, other->_cached_size_); 366 | } 367 | } 368 | 369 | ::google::protobuf::Metadata EchoRequest::GetMetadata() const 370 | { 371 | protobuf_AssignDescriptorsOnce(); 372 | ::google::protobuf::Metadata metadata; 373 | metadata.descriptor = EchoRequest_descriptor_; 374 | metadata.reflection = EchoRequest_reflection_; 375 | return metadata; 376 | } 377 | 378 | 379 | // =================================================================== 380 | 381 | #ifndef _MSC_VER 382 | const int EchoResponse::kResponseFieldNumber; 383 | #endif // !_MSC_VER 384 | 385 | EchoResponse::EchoResponse() 386 | : ::google::protobuf::Message() 387 | { 388 | SharedCtor(); 389 | } 390 | 391 | void EchoResponse::InitAsDefaultInstance() 392 | { 393 | } 394 | 395 | EchoResponse::EchoResponse(const EchoResponse& from) 396 | : ::google::protobuf::Message() 397 | { 398 | SharedCtor(); 399 | MergeFrom(from); 400 | } 401 | 402 | void EchoResponse::SharedCtor() 403 | { 404 | _cached_size_ = 0; 405 | response_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); 406 | ::memset(_has_bits_, 0, sizeof(_has_bits_)); 407 | } 408 | 409 | EchoResponse::~EchoResponse() 410 | { 411 | SharedDtor(); 412 | } 413 | 414 | void EchoResponse::SharedDtor() 415 | { 416 | if (response_ != &::google::protobuf::internal::kEmptyString) { 417 | delete response_; 418 | } 419 | if (this != default_instance_) { 420 | } 421 | } 422 | 423 | void EchoResponse::SetCachedSize(int size) const 424 | { 425 | GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); 426 | _cached_size_ = size; 427 | GOOGLE_SAFE_CONCURRENT_WRITES_END(); 428 | } 429 | const ::google::protobuf::Descriptor* EchoResponse::descriptor() 430 | { 431 | protobuf_AssignDescriptorsOnce(); 432 | return EchoResponse_descriptor_; 433 | } 434 | 435 | const EchoResponse& EchoResponse::default_instance() 436 | { 437 | if (default_instance_ == NULL) protobuf_AddDesc_echo_2eproto(); 438 | return *default_instance_; 439 | } 440 | 441 | EchoResponse* EchoResponse::default_instance_ = NULL; 442 | 443 | EchoResponse* EchoResponse::New() const 444 | { 445 | return new EchoResponse; 446 | } 447 | 448 | void EchoResponse::Clear() 449 | { 450 | if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { 451 | if (has_response()) { 452 | if (response_ != &::google::protobuf::internal::kEmptyString) { 453 | response_->clear(); 454 | } 455 | } 456 | } 457 | ::memset(_has_bits_, 0, sizeof(_has_bits_)); 458 | mutable_unknown_fields()->Clear(); 459 | } 460 | 461 | bool EchoResponse::MergePartialFromCodedStream( 462 | ::google::protobuf::io::CodedInputStream* input) 463 | { 464 | #define DO_(EXPRESSION) if (!(EXPRESSION)) return false 465 | ::google::protobuf::uint32 tag; 466 | while ((tag = input->ReadTag()) != 0) { 467 | switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { 468 | // required string response = 1; 469 | case 1: { 470 | if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == 471 | ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { 472 | DO_(::google::protobuf::internal::WireFormatLite::ReadString( 473 | input, this->mutable_response())); 474 | ::google::protobuf::internal::WireFormat::VerifyUTF8String( 475 | this->response().data(), this->response().length(), 476 | ::google::protobuf::internal::WireFormat::PARSE); 477 | } else { 478 | goto handle_uninterpreted; 479 | } 480 | if (input->ExpectAtEnd()) return true; 481 | break; 482 | } 483 | 484 | default: { 485 | handle_uninterpreted: 486 | if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == 487 | ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { 488 | return true; 489 | } 490 | DO_(::google::protobuf::internal::WireFormat::SkipField( 491 | input, tag, mutable_unknown_fields())); 492 | break; 493 | } 494 | } 495 | } 496 | return true; 497 | #undef DO_ 498 | } 499 | 500 | void EchoResponse::SerializeWithCachedSizes( 501 | ::google::protobuf::io::CodedOutputStream* output) const 502 | { 503 | // required string response = 1; 504 | if (has_response()) { 505 | ::google::protobuf::internal::WireFormat::VerifyUTF8String( 506 | this->response().data(), this->response().length(), 507 | ::google::protobuf::internal::WireFormat::SERIALIZE); 508 | ::google::protobuf::internal::WireFormatLite::WriteString( 509 | 1, this->response(), output); 510 | } 511 | 512 | if (!unknown_fields().empty()) { 513 | ::google::protobuf::internal::WireFormat::SerializeUnknownFields( 514 | unknown_fields(), output); 515 | } 516 | } 517 | 518 | ::google::protobuf::uint8* EchoResponse::SerializeWithCachedSizesToArray( 519 | ::google::protobuf::uint8* target) const 520 | { 521 | // required string response = 1; 522 | if (has_response()) { 523 | ::google::protobuf::internal::WireFormat::VerifyUTF8String( 524 | this->response().data(), this->response().length(), 525 | ::google::protobuf::internal::WireFormat::SERIALIZE); 526 | target = 527 | ::google::protobuf::internal::WireFormatLite::WriteStringToArray( 528 | 1, this->response(), target); 529 | } 530 | 531 | if (!unknown_fields().empty()) { 532 | target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( 533 | unknown_fields(), target); 534 | } 535 | return target; 536 | } 537 | 538 | int EchoResponse::ByteSize() const 539 | { 540 | int total_size = 0; 541 | 542 | if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { 543 | // required string response = 1; 544 | if (has_response()) { 545 | total_size += 1 + 546 | ::google::protobuf::internal::WireFormatLite::StringSize( 547 | this->response()); 548 | } 549 | 550 | } 551 | if (!unknown_fields().empty()) { 552 | total_size += 553 | ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( 554 | unknown_fields()); 555 | } 556 | GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); 557 | _cached_size_ = total_size; 558 | GOOGLE_SAFE_CONCURRENT_WRITES_END(); 559 | return total_size; 560 | } 561 | 562 | void EchoResponse::MergeFrom(const ::google::protobuf::Message& from) 563 | { 564 | GOOGLE_CHECK_NE(&from, this); 565 | const EchoResponse* source = 566 | ::google::protobuf::internal::dynamic_cast_if_available( 567 | &from); 568 | if (source == NULL) { 569 | ::google::protobuf::internal::ReflectionOps::Merge(from, this); 570 | } else { 571 | MergeFrom(*source); 572 | } 573 | } 574 | 575 | void EchoResponse::MergeFrom(const EchoResponse& from) 576 | { 577 | GOOGLE_CHECK_NE(&from, this); 578 | if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { 579 | if (from.has_response()) { 580 | set_response(from.response()); 581 | } 582 | } 583 | mutable_unknown_fields()->MergeFrom(from.unknown_fields()); 584 | } 585 | 586 | void EchoResponse::CopyFrom(const ::google::protobuf::Message& from) 587 | { 588 | if (&from == this) return; 589 | Clear(); 590 | MergeFrom(from); 591 | } 592 | 593 | void EchoResponse::CopyFrom(const EchoResponse& from) 594 | { 595 | if (&from == this) return; 596 | Clear(); 597 | MergeFrom(from); 598 | } 599 | 600 | bool EchoResponse::IsInitialized() const 601 | { 602 | if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; 603 | 604 | return true; 605 | } 606 | 607 | void EchoResponse::Swap(EchoResponse* other) 608 | { 609 | if (other != this) { 610 | std::swap(response_, other->response_); 611 | std::swap(_has_bits_[0], other->_has_bits_[0]); 612 | _unknown_fields_.Swap(&other->_unknown_fields_); 613 | std::swap(_cached_size_, other->_cached_size_); 614 | } 615 | } 616 | 617 | ::google::protobuf::Metadata EchoResponse::GetMetadata() const 618 | { 619 | protobuf_AssignDescriptorsOnce(); 620 | ::google::protobuf::Metadata metadata; 621 | metadata.descriptor = EchoResponse_descriptor_; 622 | metadata.reflection = EchoResponse_reflection_; 623 | return metadata; 624 | } 625 | 626 | 627 | // =================================================================== 628 | 629 | EchoService::~EchoService() {} 630 | 631 | const ::google::protobuf::ServiceDescriptor* EchoService::descriptor() 632 | { 633 | protobuf_AssignDescriptorsOnce(); 634 | return EchoService_descriptor_; 635 | } 636 | 637 | const ::google::protobuf::ServiceDescriptor* EchoService::GetDescriptor() 638 | { 639 | protobuf_AssignDescriptorsOnce(); 640 | return EchoService_descriptor_; 641 | } 642 | 643 | void EchoService::Echo1(::google::protobuf::RpcController* controller, 644 | const ::echo::EchoRequest*, 645 | ::echo::EchoResponse*, 646 | ::google::protobuf::Closure* done) 647 | { 648 | controller->SetFailed("Method Echo1() not implemented."); 649 | done->Run(); 650 | } 651 | 652 | void EchoService::Echo2(::google::protobuf::RpcController* controller, 653 | const ::echo::EchoRequest*, 654 | ::echo::EchoResponse*, 655 | ::google::protobuf::Closure* done) 656 | { 657 | controller->SetFailed("Method Echo2() not implemented."); 658 | done->Run(); 659 | } 660 | 661 | void EchoService::CallMethod(const ::google::protobuf::MethodDescriptor* method, 662 | ::google::protobuf::RpcController* controller, 663 | const ::google::protobuf::Message* request, 664 | ::google::protobuf::Message* response, 665 | ::google::protobuf::Closure* done) 666 | { 667 | GOOGLE_DCHECK_EQ(method->service(), EchoService_descriptor_); 668 | switch(method->index()) { 669 | case 0: 670 | Echo1(controller, 671 | ::google::protobuf::down_cast(request), 672 | ::google::protobuf::down_cast< ::echo::EchoResponse*>(response), 673 | done); 674 | break; 675 | case 1: 676 | Echo2(controller, 677 | ::google::protobuf::down_cast(request), 678 | ::google::protobuf::down_cast< ::echo::EchoResponse*>(response), 679 | done); 680 | break; 681 | default: 682 | GOOGLE_LOG(FATAL) << "Bad method index; this should never happen."; 683 | break; 684 | } 685 | } 686 | 687 | const ::google::protobuf::Message& EchoService::GetRequestPrototype( 688 | const ::google::protobuf::MethodDescriptor* method) const 689 | { 690 | GOOGLE_DCHECK_EQ(method->service(), descriptor()); 691 | switch(method->index()) { 692 | case 0: 693 | return ::echo::EchoRequest::default_instance(); 694 | case 1: 695 | return ::echo::EchoRequest::default_instance(); 696 | default: 697 | GOOGLE_LOG(FATAL) << "Bad method index; this should never happen."; 698 | return *reinterpret_cast< ::google::protobuf::Message*>(NULL); 699 | } 700 | } 701 | 702 | const ::google::protobuf::Message& EchoService::GetResponsePrototype( 703 | const ::google::protobuf::MethodDescriptor* method) const 704 | { 705 | GOOGLE_DCHECK_EQ(method->service(), descriptor()); 706 | switch(method->index()) { 707 | case 0: 708 | return ::echo::EchoResponse::default_instance(); 709 | case 1: 710 | return ::echo::EchoResponse::default_instance(); 711 | default: 712 | GOOGLE_LOG(FATAL) << "Bad method index; this should never happen."; 713 | return *reinterpret_cast< ::google::protobuf::Message*>(NULL); 714 | } 715 | } 716 | 717 | EchoService_Stub::EchoService_Stub(::google::protobuf::RpcChannel* channel) 718 | : channel_(channel), owns_channel_(false) {} 719 | EchoService_Stub::EchoService_Stub( 720 | ::google::protobuf::RpcChannel* channel, 721 | ::google::protobuf::Service::ChannelOwnership ownership) 722 | : channel_(channel), 723 | owns_channel_(ownership == ::google::protobuf::Service::STUB_OWNS_CHANNEL) {} 724 | EchoService_Stub::~EchoService_Stub() 725 | { 726 | if (owns_channel_) delete channel_; 727 | } 728 | 729 | void EchoService_Stub::Echo1(::google::protobuf::RpcController* controller, 730 | const ::echo::EchoRequest* request, 731 | ::echo::EchoResponse* response, 732 | ::google::protobuf::Closure* done) 733 | { 734 | channel_->CallMethod(descriptor()->method(0), 735 | controller, request, response, done); 736 | } 737 | void EchoService_Stub::Echo2(::google::protobuf::RpcController* controller, 738 | const ::echo::EchoRequest* request, 739 | ::echo::EchoResponse* response, 740 | ::google::protobuf::Closure* done) 741 | { 742 | channel_->CallMethod(descriptor()->method(1), 743 | controller, request, response, done); 744 | } 745 | 746 | // @@protoc_insertion_point(namespace_scope) 747 | 748 | } // namespace echo 749 | 750 | // @@protoc_insertion_point(global_scope) 751 | -------------------------------------------------------------------------------- /echo.pb.h: -------------------------------------------------------------------------------- 1 | // Generated by the protocol buffer compiler. DO NOT EDIT! 2 | // source: echo.proto 3 | 4 | #ifndef PROTOBUF_echo_2eproto__INCLUDED 5 | #define PROTOBUF_echo_2eproto__INCLUDED 6 | 7 | #include 8 | 9 | #include 10 | 11 | #if GOOGLE_PROTOBUF_VERSION < 2005000 12 | #error This file was generated by a newer version of protoc which is 13 | #error incompatible with your Protocol Buffer headers. Please update 14 | #error your headers. 15 | #endif 16 | #if 2005000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 17 | #error This file was generated by an older version of protoc which is 18 | #error incompatible with your Protocol Buffer headers. Please 19 | #error regenerate this file with a newer version of protoc. 20 | #endif 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | // @@protoc_insertion_point(includes) 29 | 30 | namespace echo { 31 | 32 | // Internal implementation detail -- do not call these. 33 | void protobuf_AddDesc_echo_2eproto(); 34 | void protobuf_AssignDesc_echo_2eproto(); 35 | void protobuf_ShutdownFile_echo_2eproto(); 36 | 37 | class EchoRequest; 38 | class EchoResponse; 39 | 40 | // =================================================================== 41 | 42 | class EchoRequest : public ::google::protobuf::Message { 43 | public: 44 | EchoRequest(); 45 | virtual ~EchoRequest(); 46 | 47 | EchoRequest(const EchoRequest& from); 48 | 49 | inline EchoRequest& operator=(const EchoRequest& from) { 50 | CopyFrom(from); 51 | return *this; 52 | } 53 | 54 | inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { 55 | return _unknown_fields_; 56 | } 57 | 58 | inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { 59 | return &_unknown_fields_; 60 | } 61 | 62 | static const ::google::protobuf::Descriptor* descriptor(); 63 | static const EchoRequest& default_instance(); 64 | 65 | void Swap(EchoRequest* other); 66 | 67 | // implements Message ---------------------------------------------- 68 | 69 | EchoRequest* New() const; 70 | void CopyFrom(const ::google::protobuf::Message& from); 71 | void MergeFrom(const ::google::protobuf::Message& from); 72 | void CopyFrom(const EchoRequest& from); 73 | void MergeFrom(const EchoRequest& from); 74 | void Clear(); 75 | bool IsInitialized() const; 76 | 77 | int ByteSize() const; 78 | bool MergePartialFromCodedStream( 79 | ::google::protobuf::io::CodedInputStream* input); 80 | void SerializeWithCachedSizes( 81 | ::google::protobuf::io::CodedOutputStream* output) const; 82 | ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; 83 | int GetCachedSize() const { 84 | return _cached_size_; 85 | } 86 | private: 87 | void SharedCtor(); 88 | void SharedDtor(); 89 | void SetCachedSize(int size) const; 90 | public: 91 | 92 | ::google::protobuf::Metadata GetMetadata() const; 93 | 94 | // nested types ---------------------------------------------------- 95 | 96 | // accessors ------------------------------------------------------- 97 | 98 | // required string message = 1; 99 | inline bool has_message() const; 100 | inline void clear_message(); 101 | static const int kMessageFieldNumber = 1; 102 | inline const ::std::string& message() const; 103 | inline void set_message(const ::std::string& value); 104 | inline void set_message(const char* value); 105 | inline void set_message(const char* value, size_t size); 106 | inline ::std::string* mutable_message(); 107 | inline ::std::string* release_message(); 108 | inline void set_allocated_message(::std::string* message); 109 | 110 | // @@protoc_insertion_point(class_scope:echo.EchoRequest) 111 | private: 112 | inline void set_has_message(); 113 | inline void clear_has_message(); 114 | 115 | ::google::protobuf::UnknownFieldSet _unknown_fields_; 116 | 117 | ::std::string* message_; 118 | 119 | mutable int _cached_size_; 120 | ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; 121 | 122 | friend void protobuf_AddDesc_echo_2eproto(); 123 | friend void protobuf_AssignDesc_echo_2eproto(); 124 | friend void protobuf_ShutdownFile_echo_2eproto(); 125 | 126 | void InitAsDefaultInstance(); 127 | static EchoRequest* default_instance_; 128 | }; 129 | // ------------------------------------------------------------------- 130 | 131 | class EchoResponse : public ::google::protobuf::Message { 132 | public: 133 | EchoResponse(); 134 | virtual ~EchoResponse(); 135 | 136 | EchoResponse(const EchoResponse& from); 137 | 138 | inline EchoResponse& operator=(const EchoResponse& from) { 139 | CopyFrom(from); 140 | return *this; 141 | } 142 | 143 | inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { 144 | return _unknown_fields_; 145 | } 146 | 147 | inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { 148 | return &_unknown_fields_; 149 | } 150 | 151 | static const ::google::protobuf::Descriptor* descriptor(); 152 | static const EchoResponse& default_instance(); 153 | 154 | void Swap(EchoResponse* other); 155 | 156 | // implements Message ---------------------------------------------- 157 | 158 | EchoResponse* New() const; 159 | void CopyFrom(const ::google::protobuf::Message& from); 160 | void MergeFrom(const ::google::protobuf::Message& from); 161 | void CopyFrom(const EchoResponse& from); 162 | void MergeFrom(const EchoResponse& from); 163 | void Clear(); 164 | bool IsInitialized() const; 165 | 166 | int ByteSize() const; 167 | bool MergePartialFromCodedStream( 168 | ::google::protobuf::io::CodedInputStream* input); 169 | void SerializeWithCachedSizes( 170 | ::google::protobuf::io::CodedOutputStream* output) const; 171 | ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; 172 | int GetCachedSize() const { 173 | return _cached_size_; 174 | } 175 | private: 176 | void SharedCtor(); 177 | void SharedDtor(); 178 | void SetCachedSize(int size) const; 179 | public: 180 | 181 | ::google::protobuf::Metadata GetMetadata() const; 182 | 183 | // nested types ---------------------------------------------------- 184 | 185 | // accessors ------------------------------------------------------- 186 | 187 | // required string response = 1; 188 | inline bool has_response() const; 189 | inline void clear_response(); 190 | static const int kResponseFieldNumber = 1; 191 | inline const ::std::string& response() const; 192 | inline void set_response(const ::std::string& value); 193 | inline void set_response(const char* value); 194 | inline void set_response(const char* value, size_t size); 195 | inline ::std::string* mutable_response(); 196 | inline ::std::string* release_response(); 197 | inline void set_allocated_response(::std::string* response); 198 | 199 | // @@protoc_insertion_point(class_scope:echo.EchoResponse) 200 | private: 201 | inline void set_has_response(); 202 | inline void clear_has_response(); 203 | 204 | ::google::protobuf::UnknownFieldSet _unknown_fields_; 205 | 206 | ::std::string* response_; 207 | 208 | mutable int _cached_size_; 209 | ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; 210 | 211 | friend void protobuf_AddDesc_echo_2eproto(); 212 | friend void protobuf_AssignDesc_echo_2eproto(); 213 | friend void protobuf_ShutdownFile_echo_2eproto(); 214 | 215 | void InitAsDefaultInstance(); 216 | static EchoResponse* default_instance_; 217 | }; 218 | // =================================================================== 219 | 220 | class EchoService_Stub; 221 | 222 | class EchoService : public ::google::protobuf::Service { 223 | protected: 224 | // This class should be treated as an abstract interface. 225 | inline EchoService() {}; 226 | public: 227 | virtual ~EchoService(); 228 | 229 | typedef EchoService_Stub Stub; 230 | 231 | static const ::google::protobuf::ServiceDescriptor* descriptor(); 232 | 233 | virtual void Echo1(::google::protobuf::RpcController* controller, 234 | const ::echo::EchoRequest* request, 235 | ::echo::EchoResponse* response, 236 | ::google::protobuf::Closure* done); 237 | virtual void Echo2(::google::protobuf::RpcController* controller, 238 | const ::echo::EchoRequest* request, 239 | ::echo::EchoResponse* response, 240 | ::google::protobuf::Closure* done); 241 | 242 | // implements Service ---------------------------------------------- 243 | 244 | const ::google::protobuf::ServiceDescriptor* GetDescriptor(); 245 | void CallMethod(const ::google::protobuf::MethodDescriptor* method, 246 | ::google::protobuf::RpcController* controller, 247 | const ::google::protobuf::Message* request, 248 | ::google::protobuf::Message* response, 249 | ::google::protobuf::Closure* done); 250 | const ::google::protobuf::Message& GetRequestPrototype( 251 | const ::google::protobuf::MethodDescriptor* method) const; 252 | const ::google::protobuf::Message& GetResponsePrototype( 253 | const ::google::protobuf::MethodDescriptor* method) const; 254 | 255 | private: 256 | GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EchoService); 257 | }; 258 | 259 | class EchoService_Stub : public EchoService { 260 | public: 261 | EchoService_Stub(::google::protobuf::RpcChannel* channel); 262 | EchoService_Stub(::google::protobuf::RpcChannel* channel, 263 | ::google::protobuf::Service::ChannelOwnership ownership); 264 | ~EchoService_Stub(); 265 | 266 | inline ::google::protobuf::RpcChannel* channel() { 267 | return channel_; 268 | } 269 | 270 | // implements EchoService ------------------------------------------ 271 | 272 | void Echo1(::google::protobuf::RpcController* controller, 273 | const ::echo::EchoRequest* request, 274 | ::echo::EchoResponse* response, 275 | ::google::protobuf::Closure* done); 276 | void Echo2(::google::protobuf::RpcController* controller, 277 | const ::echo::EchoRequest* request, 278 | ::echo::EchoResponse* response, 279 | ::google::protobuf::Closure* done); 280 | private: 281 | ::google::protobuf::RpcChannel* channel_; 282 | bool owns_channel_; 283 | GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EchoService_Stub); 284 | }; 285 | 286 | 287 | // =================================================================== 288 | 289 | 290 | // =================================================================== 291 | 292 | // EchoRequest 293 | 294 | // required string message = 1; 295 | inline bool EchoRequest::has_message() const 296 | { 297 | return (_has_bits_[0] & 0x00000001u) != 0; 298 | } 299 | inline void EchoRequest::set_has_message() 300 | { 301 | _has_bits_[0] |= 0x00000001u; 302 | } 303 | inline void EchoRequest::clear_has_message() 304 | { 305 | _has_bits_[0] &= ~0x00000001u; 306 | } 307 | inline void EchoRequest::clear_message() 308 | { 309 | if (message_ != &::google::protobuf::internal::kEmptyString) { 310 | message_->clear(); 311 | } 312 | clear_has_message(); 313 | } 314 | inline const ::std::string& EchoRequest::message() const 315 | { 316 | return *message_; 317 | } 318 | inline void EchoRequest::set_message(const ::std::string& value) 319 | { 320 | set_has_message(); 321 | if (message_ == &::google::protobuf::internal::kEmptyString) { 322 | message_ = new ::std::string; 323 | } 324 | message_->assign(value); 325 | } 326 | inline void EchoRequest::set_message(const char* value) 327 | { 328 | set_has_message(); 329 | if (message_ == &::google::protobuf::internal::kEmptyString) { 330 | message_ = new ::std::string; 331 | } 332 | message_->assign(value); 333 | } 334 | inline void EchoRequest::set_message(const char* value, size_t size) 335 | { 336 | set_has_message(); 337 | if (message_ == &::google::protobuf::internal::kEmptyString) { 338 | message_ = new ::std::string; 339 | } 340 | message_->assign(reinterpret_cast(value), size); 341 | } 342 | inline ::std::string* EchoRequest::mutable_message() 343 | { 344 | set_has_message(); 345 | if (message_ == &::google::protobuf::internal::kEmptyString) { 346 | message_ = new ::std::string; 347 | } 348 | return message_; 349 | } 350 | inline ::std::string* EchoRequest::release_message() 351 | { 352 | clear_has_message(); 353 | if (message_ == &::google::protobuf::internal::kEmptyString) { 354 | return NULL; 355 | } else { 356 | ::std::string* temp = message_; 357 | message_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); 358 | return temp; 359 | } 360 | } 361 | inline void EchoRequest::set_allocated_message(::std::string* message) 362 | { 363 | if (message_ != &::google::protobuf::internal::kEmptyString) { 364 | delete message_; 365 | } 366 | if (message) { 367 | set_has_message(); 368 | message_ = message; 369 | } else { 370 | clear_has_message(); 371 | message_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); 372 | } 373 | } 374 | 375 | // ------------------------------------------------------------------- 376 | 377 | // EchoResponse 378 | 379 | // required string response = 1; 380 | inline bool EchoResponse::has_response() const 381 | { 382 | return (_has_bits_[0] & 0x00000001u) != 0; 383 | } 384 | inline void EchoResponse::set_has_response() 385 | { 386 | _has_bits_[0] |= 0x00000001u; 387 | } 388 | inline void EchoResponse::clear_has_response() 389 | { 390 | _has_bits_[0] &= ~0x00000001u; 391 | } 392 | inline void EchoResponse::clear_response() 393 | { 394 | if (response_ != &::google::protobuf::internal::kEmptyString) { 395 | response_->clear(); 396 | } 397 | clear_has_response(); 398 | } 399 | inline const ::std::string& EchoResponse::response() const 400 | { 401 | return *response_; 402 | } 403 | inline void EchoResponse::set_response(const ::std::string& value) 404 | { 405 | set_has_response(); 406 | if (response_ == &::google::protobuf::internal::kEmptyString) { 407 | response_ = new ::std::string; 408 | } 409 | response_->assign(value); 410 | } 411 | inline void EchoResponse::set_response(const char* value) 412 | { 413 | set_has_response(); 414 | if (response_ == &::google::protobuf::internal::kEmptyString) { 415 | response_ = new ::std::string; 416 | } 417 | response_->assign(value); 418 | } 419 | inline void EchoResponse::set_response(const char* value, size_t size) 420 | { 421 | set_has_response(); 422 | if (response_ == &::google::protobuf::internal::kEmptyString) { 423 | response_ = new ::std::string; 424 | } 425 | response_->assign(reinterpret_cast(value), size); 426 | } 427 | inline ::std::string* EchoResponse::mutable_response() 428 | { 429 | set_has_response(); 430 | if (response_ == &::google::protobuf::internal::kEmptyString) { 431 | response_ = new ::std::string; 432 | } 433 | return response_; 434 | } 435 | inline ::std::string* EchoResponse::release_response() 436 | { 437 | clear_has_response(); 438 | if (response_ == &::google::protobuf::internal::kEmptyString) { 439 | return NULL; 440 | } else { 441 | ::std::string* temp = response_; 442 | response_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); 443 | return temp; 444 | } 445 | } 446 | inline void EchoResponse::set_allocated_response(::std::string* response) 447 | { 448 | if (response_ != &::google::protobuf::internal::kEmptyString) { 449 | delete response_; 450 | } 451 | if (response) { 452 | set_has_response(); 453 | response_ = response; 454 | } else { 455 | clear_has_response(); 456 | response_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); 457 | } 458 | } 459 | 460 | 461 | // @@protoc_insertion_point(namespace_scope) 462 | 463 | } // namespace echo 464 | 465 | #ifndef SWIG 466 | namespace google { 467 | namespace protobuf { 468 | 469 | 470 | } // namespace google 471 | } // namespace protobuf 472 | #endif // SWIG 473 | 474 | // @@protoc_insertion_point(global_scope) 475 | 476 | #endif // PROTOBUF_echo_2eproto__INCLUDED 477 | -------------------------------------------------------------------------------- /echo.proto: -------------------------------------------------------------------------------- 1 | // Specs for Echo 2 | option cc_generic_services = true; 3 | package echo; 4 | 5 | message EchoRequest 6 | { 7 | required string message = 1; 8 | }; 9 | 10 | message EchoResponse 11 | { 12 | required string response = 1; 13 | }; 14 | 15 | service EchoService 16 | { 17 | rpc Echo1(EchoRequest) returns (EchoResponse); 18 | rpc Echo2(EchoRequest) returns (EchoResponse); 19 | }; 20 | -------------------------------------------------------------------------------- /nn.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 250bpm s.r.o. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), 6 | to deal in the Software without restriction, including without limitation 7 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | and/or sell copies of the Software, and to permit persons to whom 9 | the Software is furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included 12 | in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef NN_HPP_INCLUDED 24 | #define NN_HPP_INCLUDED 25 | 26 | #include 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #if defined __GNUC__ 34 | #define nn_slow(x) __builtin_expect ((x), 0) 35 | #else 36 | #define nn_slow(x) (x) 37 | #endif 38 | 39 | namespace nn { 40 | 41 | class exception : public std::exception { 42 | public: 43 | 44 | exception () : err (nn_errno ()) {} 45 | 46 | virtual const char *what () const throw () { 47 | return nn_strerror (err); 48 | } 49 | 50 | int num () const { 51 | return err; 52 | } 53 | 54 | private: 55 | 56 | int err; 57 | }; 58 | 59 | inline const char *symbol (int i, int *value) 60 | { 61 | return nn_symbol (i, value); 62 | } 63 | 64 | inline void *allocmsg (size_t size, int type) 65 | { 66 | void *msg = nn_allocmsg (size, type); 67 | if (nn_slow (!msg)) 68 | throw nn::exception (); 69 | return msg; 70 | } 71 | 72 | inline int freemsg (void *msg) 73 | { 74 | int rc = nn_freemsg (msg); 75 | if (nn_slow (rc != 0)) 76 | throw nn::exception (); 77 | return rc; 78 | } 79 | 80 | class socket { 81 | public: 82 | 83 | inline socket (int domain, int protocol) { 84 | s = nn_socket (domain, protocol); 85 | if (nn_slow (s < 0)) 86 | throw nn::exception (); 87 | } 88 | 89 | inline ~socket () { 90 | int rc = nn_close (s); 91 | assert (rc == 0); 92 | } 93 | 94 | inline void setsockopt (int level, int option, const void *optval, 95 | size_t optvallen) { 96 | int rc = nn_setsockopt (s, level, option, optval, optvallen); 97 | if (nn_slow (rc != 0)) 98 | throw nn::exception (); 99 | } 100 | 101 | inline void getsockopt (int level, int option, void *optval, 102 | size_t *optvallen) { 103 | int rc = nn_getsockopt (s, level, option, optval, optvallen); 104 | if (nn_slow (rc != 0)) 105 | throw nn::exception (); 106 | } 107 | 108 | inline int bind (const char *addr) { 109 | int rc = nn_bind (s, addr); 110 | if (nn_slow (rc < 0)) 111 | throw nn::exception (); 112 | return rc; 113 | } 114 | 115 | inline int connect (const char *addr) { 116 | int rc = nn_connect (s, addr); 117 | if (nn_slow (rc < 0)) 118 | throw nn::exception (); 119 | return rc; 120 | } 121 | 122 | inline void shutdown (int how) { 123 | int rc = nn_shutdown (s, how); 124 | if (nn_slow (rc != 0)) 125 | throw nn::exception (); 126 | } 127 | 128 | inline int send (const void *buf, size_t len, int flags) { 129 | int rc = nn_send (s, buf, len, flags); 130 | if (nn_slow (rc < 0)) { 131 | if (nn_slow (nn_errno () != EAGAIN)) 132 | throw nn::exception (); 133 | return -1; 134 | } 135 | return rc; 136 | } 137 | 138 | inline int recv (void *buf, size_t len, int flags) { 139 | int rc = nn_recv (s, buf, len, flags); 140 | if (nn_slow (rc < 0)) { 141 | if (nn_slow (nn_errno () != EAGAIN)) 142 | throw nn::exception (); 143 | return -1; 144 | } 145 | return rc; 146 | } 147 | 148 | inline int sendmsg (const struct nn_msghdr *msghdr, int flags) { 149 | int rc = nn_sendmsg (s, msghdr, flags); 150 | if (nn_slow (rc < 0)) { 151 | if (nn_slow (nn_errno () != EAGAIN)) 152 | throw nn::exception (); 153 | return -1; 154 | } 155 | return rc; 156 | } 157 | 158 | inline int recvmsg (struct nn_msghdr *msghdr, int flags) { 159 | int rc = nn_recvmsg (s, msghdr, flags); 160 | if (nn_slow (rc < 0)) { 161 | if (nn_slow (nn_errno () != EAGAIN)) 162 | throw nn::exception (); 163 | return -1; 164 | } 165 | return rc; 166 | } 167 | 168 | private: 169 | 170 | int s; 171 | 172 | /* Prevent making copies of the socket by accident. */ 173 | socket (const socket&); 174 | void operator = (const socket&); 175 | }; 176 | 177 | inline void term () 178 | { 179 | nn_term (); 180 | } 181 | 182 | } 183 | 184 | #undef nn_slow 185 | 186 | #endif 187 | 188 | 189 | 190 | --------------------------------------------------------------------------------