From 2dde7dbb2ebaba40d5758b200bf8d2945b1e5ebf Mon Sep 17 00:00:00 2001 From: Mahdi <80265960+Mahdi-zarei@users.noreply.github.com> Date: Sat, 2 Aug 2025 13:49:32 +0330 Subject: [PATCH] Migrate to protorpc (#598) * refactor: migrate from grpc to protorpc * fix * fix * fix * cleanup * Update mainwindow_grpc.cpp * Update RPC.cpp * fix --------- Co-authored-by: parhelia512 <0011d3@gmail.com> --- .github/workflows/build.yml | 2 +- 3rdparty/protorpc/rpc_client.cc | 97 + 3rdparty/protorpc/rpc_client.h | 53 + 3rdparty/protorpc/rpc_conn.cc | 98 + 3rdparty/protorpc/rpc_conn.h | 49 + 3rdparty/protorpc/rpc_conn_posix.cc | 145 ++ 3rdparty/protorpc/rpc_conn_windows.cc | 150 ++ 3rdparty/protorpc/rpc_error.h | 32 + 3rdparty/protorpc/rpc_wire.cc | 158 ++ 3rdparty/protorpc/rpc_wire.h | 48 + 3rdparty/protorpc/wire.pb/wire.pb.cc | 197 ++ 3rdparty/protorpc/wire.pb/wire.pb.h | 85 + 3rdparty/protorpc/wire.pb/wire.proto | 50 + CMakeLists.txt | 7 +- core/protorpc/.editorconfig | 29 + core/protorpc/.travis.yml | 12 + core/protorpc/Dockerfile | 24 + core/protorpc/LICENSE | 27 + core/protorpc/README.md | 173 ++ core/protorpc/changelog.md | 23 + core/protorpc/client.go | 135 ++ core/protorpc/conn.go | 117 ++ core/protorpc/doc.go | 111 ++ core/protorpc/examples/message.pb/arith.pb.go | 90 + core/protorpc/examples/message.pb/arith.proto | 16 + core/protorpc/examples/message.pb/echo.pb.go | 62 + core/protorpc/examples/message.pb/echo.proto | 15 + core/protorpc/examples/message.pb/proto.go | 7 + core/protorpc/examples/proto3.pb/Makefile | 14 + core/protorpc/examples/proto3.pb/proto.go | 8 + core/protorpc/examples/proto3.pb/proto3.pb.go | 220 ++ .../examples/proto3.pb/proto3.pb.protorpc.go | 171 ++ core/protorpc/examples/proto3.pb/proto3.proto | 41 + .../examples/proto3.pb/proto3_proto_test.go | 72 + core/protorpc/examples/service.pb/Makefile | 14 + core/protorpc/examples/service.pb/all_test.go | 193 ++ core/protorpc/examples/service.pb/arith.go | 33 + core/protorpc/examples/service.pb/arith.pb.go | 93 + .../examples/service.pb/arith.pb.protorpc.go | 291 +++ core/protorpc/examples/service.pb/arith.proto | 23 + .../examples/service.pb/arith_test.go | 34 + core/protorpc/examples/service.pb/echo.go | 17 + core/protorpc/examples/service.pb/echo.pb.go | 65 + .../examples/service.pb/echo.pb.protorpc.go | 211 ++ core/protorpc/examples/service.pb/echo.proto | 20 + .../protorpc/examples/service.pb/echo_test.go | 698 +++++++ core/protorpc/examples/service.pb/proto.go | 8 + core/protorpc/examples/stdrpc.pb/Makefile | 13 + core/protorpc/examples/stdrpc.pb/arith.pb.go | 401 ++++ core/protorpc/examples/stdrpc.pb/arith.proto | 23 + core/protorpc/examples/stdrpc.pb/echo.pb.go | 301 +++ core/protorpc/examples/stdrpc.pb/echo.proto | 20 + core/protorpc/go.mod | 11 + core/protorpc/hello.go | 62 + core/protorpc/hello2.go | 65 + core/protorpc/protoc-gen-plugin/generator.go | 52 + core/protorpc/protoc-gen-plugin/main.go | 115 ++ .../protorpc/protoc-gen-plugin/main_plugin.go | 119 ++ core/protorpc/protoc-gen-protorpc/env.go | 7 + core/protorpc/protoc-gen-protorpc/main.go | 381 ++++ .../protoc-gen-stdrpc/_main-ignore.go | 342 ++++ core/protorpc/protoc-gen-stdrpc/main.go | 103 + core/protorpc/protoc-gen-stdrpc/netrpc.go | 350 ++++ core/protorpc/rpc_test.go | 256 +++ core/protorpc/server.go | 134 ++ core/protorpc/wire.go | 173 ++ core/protorpc/wire.pb/proto.go | 7 + core/protorpc/wire.pb/wire.pb.go | 296 +++ core/protorpc/wire.pb/wire.proto | 50 + core/server/gen/libcore.pb.go | 1762 ----------------- core/server/gen/libcore.proto | 3 +- core/server/gen/libcore_grpc.pb.go | 691 ------- core/server/go.mod | 10 +- core/server/go.sum | 28 +- core/server/main.go | 18 +- core/server/server.go | 146 +- core/server/server_darwin.go | 9 + core/server/server_linux.go | 9 + core/server/server_windows.go | 7 +- include/api/{gRPC.h => RPC.h} | 10 +- script/build_go.sh | 2 +- src/api/RPC.cpp | 295 +++ src/api/gRPC.cpp | 474 ----- src/configs/ConfigBuilder.cpp | 2 +- src/global/Configs.cpp | 2 +- .../connectionLister/connectionLister.cpp | 2 +- src/stats/traffic/TrafficLooper.cpp | 2 +- src/ui/mainwindow.cpp | 1 - src/ui/mainwindow_grpc.cpp | 36 +- src/ui/setting/RouteItem.cpp | 2 +- src/ui/setting/dialog_manage_routes.cpp | 2 +- 91 files changed, 7947 insertions(+), 3085 deletions(-) create mode 100644 3rdparty/protorpc/rpc_client.cc create mode 100644 3rdparty/protorpc/rpc_client.h create mode 100644 3rdparty/protorpc/rpc_conn.cc create mode 100644 3rdparty/protorpc/rpc_conn.h create mode 100644 3rdparty/protorpc/rpc_conn_posix.cc create mode 100644 3rdparty/protorpc/rpc_conn_windows.cc create mode 100644 3rdparty/protorpc/rpc_error.h create mode 100644 3rdparty/protorpc/rpc_wire.cc create mode 100644 3rdparty/protorpc/rpc_wire.h create mode 100644 3rdparty/protorpc/wire.pb/wire.pb.cc create mode 100644 3rdparty/protorpc/wire.pb/wire.pb.h create mode 100644 3rdparty/protorpc/wire.pb/wire.proto create mode 100644 core/protorpc/.editorconfig create mode 100644 core/protorpc/.travis.yml create mode 100644 core/protorpc/Dockerfile create mode 100644 core/protorpc/LICENSE create mode 100644 core/protorpc/README.md create mode 100644 core/protorpc/changelog.md create mode 100644 core/protorpc/client.go create mode 100644 core/protorpc/conn.go create mode 100644 core/protorpc/doc.go create mode 100644 core/protorpc/examples/message.pb/arith.pb.go create mode 100644 core/protorpc/examples/message.pb/arith.proto create mode 100644 core/protorpc/examples/message.pb/echo.pb.go create mode 100644 core/protorpc/examples/message.pb/echo.proto create mode 100644 core/protorpc/examples/message.pb/proto.go create mode 100644 core/protorpc/examples/proto3.pb/Makefile create mode 100644 core/protorpc/examples/proto3.pb/proto.go create mode 100644 core/protorpc/examples/proto3.pb/proto3.pb.go create mode 100644 core/protorpc/examples/proto3.pb/proto3.pb.protorpc.go create mode 100644 core/protorpc/examples/proto3.pb/proto3.proto create mode 100644 core/protorpc/examples/proto3.pb/proto3_proto_test.go create mode 100644 core/protorpc/examples/service.pb/Makefile create mode 100644 core/protorpc/examples/service.pb/all_test.go create mode 100644 core/protorpc/examples/service.pb/arith.go create mode 100644 core/protorpc/examples/service.pb/arith.pb.go create mode 100644 core/protorpc/examples/service.pb/arith.pb.protorpc.go create mode 100644 core/protorpc/examples/service.pb/arith.proto create mode 100644 core/protorpc/examples/service.pb/arith_test.go create mode 100644 core/protorpc/examples/service.pb/echo.go create mode 100644 core/protorpc/examples/service.pb/echo.pb.go create mode 100644 core/protorpc/examples/service.pb/echo.pb.protorpc.go create mode 100644 core/protorpc/examples/service.pb/echo.proto create mode 100644 core/protorpc/examples/service.pb/echo_test.go create mode 100644 core/protorpc/examples/service.pb/proto.go create mode 100644 core/protorpc/examples/stdrpc.pb/Makefile create mode 100644 core/protorpc/examples/stdrpc.pb/arith.pb.go create mode 100644 core/protorpc/examples/stdrpc.pb/arith.proto create mode 100644 core/protorpc/examples/stdrpc.pb/echo.pb.go create mode 100644 core/protorpc/examples/stdrpc.pb/echo.proto create mode 100644 core/protorpc/go.mod create mode 100644 core/protorpc/hello.go create mode 100644 core/protorpc/hello2.go create mode 100644 core/protorpc/protoc-gen-plugin/generator.go create mode 100644 core/protorpc/protoc-gen-plugin/main.go create mode 100644 core/protorpc/protoc-gen-plugin/main_plugin.go create mode 100644 core/protorpc/protoc-gen-protorpc/env.go create mode 100644 core/protorpc/protoc-gen-protorpc/main.go create mode 100644 core/protorpc/protoc-gen-stdrpc/_main-ignore.go create mode 100644 core/protorpc/protoc-gen-stdrpc/main.go create mode 100644 core/protorpc/protoc-gen-stdrpc/netrpc.go create mode 100644 core/protorpc/rpc_test.go create mode 100644 core/protorpc/server.go create mode 100644 core/protorpc/wire.go create mode 100644 core/protorpc/wire.pb/proto.go create mode 100644 core/protorpc/wire.pb/wire.pb.go create mode 100644 core/protorpc/wire.pb/wire.proto delete mode 100644 core/server/gen/libcore.pb.go delete mode 100644 core/server/gen/libcore_grpc.pb.go create mode 100644 core/server/server_darwin.go create mode 100644 core/server/server_linux.go rename include/api/{gRPC.h => RPC.h} (84%) create mode 100644 src/api/RPC.cpp delete mode 100644 src/api/gRPC.cpp diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a95e178..3f686a2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -72,7 +72,7 @@ jobs: if: matrix.cross_os != 'public_res' run: | go install github.com/golang/protobuf/protoc-gen-go@latest - go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest + go install github.com/chai2010/protorpc/protoc-gen-protorpc@latest - name: Build golang parts if: steps.cache-common.outputs.cache-hit != 'true' shell: bash diff --git a/3rdparty/protorpc/rpc_client.cc b/3rdparty/protorpc/rpc_client.cc new file mode 100644 index 0000000..fb7f694 --- /dev/null +++ b/3rdparty/protorpc/rpc_client.cc @@ -0,0 +1,97 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "3rdparty/protorpc/rpc_client.h" +#include "3rdparty/protorpc/rpc_wire.h" + +namespace protorpc { + +Client::Client(const char* host, int port): + conn_(0), host_(host), port_(port), seq_(0) { + // +} +Client::~Client() { + Close(); +} + +const ::protorpc::Error Client::CallMethod( + const std::string& method, + const ::std::string* request, + ::std::string* response +) { + if(!checkMothdValid(method, request, response)) { + return ::protorpc::Error::New( + std::string("protorpc.Client.CallMethod: Invalid method, method: ") + method + ); + } + return callMethod(method, request, response); +} + +// Close the connection +void Client::Close() { + conn_.Close(); +} + +// -------------------------------------------------------- + +const ::protorpc::Error Client::callMethod( + const std::string& method, + const ::std::string* request, + ::std::string* response +) { + if(!conn_.IsValid()) { + if(!conn_.DialTCP(host_.c_str(), port_)) { + return ::protorpc::Error::New( + std::string("protorpc.Client.callMethod: DialTCP fail, ") + + std::string("host: ") + host_ + std::string(":") + std::to_string(static_cast(port_)) + ); + } + } + + Error err; + + uint64_t id = seq_++; + wire::ResponseHeader respHeader; + + // send request + err = wire::SendRequest(&conn_, id, method, request); + if(!err.IsNil()) { + return err; + } + + // recv response hdr + err = wire::RecvResponseHeader(&conn_, &respHeader); + if(!err.IsNil()) { + return err; + } + // recv response body + err = wire::RecvResponseBody(&conn_, &respHeader, response); + if(!err.IsNil()) { + return err; + } + if(respHeader.id != id) { + return Error::New("protorpc.Client.callMethod: unexpected call id."); + } + if(!respHeader.error.empty()) { + return Error::New(respHeader.error); + } + + return Error::Nil(); +} + +// -------------------------------------------------------- + +bool Client::checkMothdValid( + const std::string& method, + const ::std::string* request, + ::std::string* response +) const { + if(method.empty()) return false; + if(!request) return false; + if(!response) return false; + return true; +} + +} // namespace protorpc + diff --git a/3rdparty/protorpc/rpc_client.h b/3rdparty/protorpc/rpc_client.h new file mode 100644 index 0000000..c0a6328 --- /dev/null +++ b/3rdparty/protorpc/rpc_client.h @@ -0,0 +1,53 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#pragma once + +#ifndef PROTORPC_CLIENT_H__ +#define PROTORPC_CLIENT_H__ + +#include "3rdparty/protorpc/rpc_conn.h" +#include "3rdparty/protorpc/rpc_error.h" + +#include +#include + +namespace protorpc { + +class Client { +public: + Client(const char* host, int port); + ~Client(); + + const ::protorpc::Error CallMethod( + const std::string& method, + const ::std::string* request, + ::std::string* response + ); + + // Close the connection + void Close(); + +private: + const ::protorpc::Error callMethod( + const std::string& method, + const ::std::string* request, + ::std::string* response + ); + + bool checkMothdValid( + const std::string& method, + const ::std::string* request, + ::std::string* response + ) const; + + std::string host_; + int port_; + Conn conn_; + uint64_t seq_; +}; + +} // namespace protorpc + +#endif // PROTORPC_CLIENT_H__ diff --git a/3rdparty/protorpc/rpc_conn.cc b/3rdparty/protorpc/rpc_conn.cc new file mode 100644 index 0000000..9e3b2bf --- /dev/null +++ b/3rdparty/protorpc/rpc_conn.cc @@ -0,0 +1,98 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "3rdparty/protorpc/rpc_conn.h" + +#if (defined(_WIN32) || defined(_WIN64)) +# include "./rpc_conn_windows.cc" +#else +# include "./rpc_conn_posix.cc" +#endif + +namespace protorpc { + +// MaxVarintLenN is the maximum length of a varint-encoded N-bit integer. +static const int maxVarintLen16 = 3; +static const int maxVarintLen32 = 5; +static const int maxVarintLen64 = 10; + +// PutUvarint encodes a uint64 into buf and returns the number of bytes written. +// If the buffer is too small, PutUvarint will panic. +static int putUvarint(uint8_t buf[], uint64_t x) { + auto i = 0; + while(x >= 0x80) { + buf[i] = uint8_t(x) | 0x80; + x >>= 7; + i++; + } + buf[i] = uint8_t(x); + return i + 1; +} + +// ReadUvarint reads an encoded unsigned integer from r and returns it as a uint64. +bool Conn::ReadUvarint(uint64_t* rx) { + uint64_t x; + uint8_t s, b; + + *rx = 0; + x = 0; + s = 0; + + for(int i = 0; ; i++) { + if(!Read(&b, 1)) { + return false; + } + if(b < 0x80) { + if(i > 9 || i == 9 && b > 1){ + printf("protorpc.Conn.ReadUvarint: varint overflows a 64-bit integer\n"); + return false; + } + *rx = (x | uint64_t(b)<resize(size_t(size)); + if(!Read((void*)data->data(), int(size))) { + data->clear(); + return false; + } + } + return true; +} + +bool Conn::SendFrame(const ::std::string* data) { + if(data == NULL) { + return WriteUvarint(uint64_t(0)); + } + + if(!WriteUvarint(uint64_t(data->size()))) { + return false; + } + if(!Write((void*)data->data(), data->size())) { + return false; + } + return true; +} + +} // namespace protorpc diff --git a/3rdparty/protorpc/rpc_conn.h b/3rdparty/protorpc/rpc_conn.h new file mode 100644 index 0000000..fabab2b --- /dev/null +++ b/3rdparty/protorpc/rpc_conn.h @@ -0,0 +1,49 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#pragma once + +#ifndef PROTORPC_CONN_H__ +#define PROTORPC_CONN_H__ + +#include +#include +#include + +namespace protorpc { + +// Initialize socket services +bool InitSocket(); + +// Stream-oriented network connection. +class Conn { +public: + Conn(int fd=0): sock_(fd) { InitSocket(); } + ~Conn() {} + + bool IsValid() const; + bool DialTCP(const char* host, int port); + bool ListenTCP(int port, int backlog=5); + void Close(); + + Conn* Accept(); + + bool Read(void* buf, int len); + bool Write(void* buf, int len); + + bool ReadUvarint(uint64_t* x); + bool WriteUvarint(uint64_t x); + + bool RecvFrame(::std::string* data); + bool SendFrame(const ::std::string* data); + +private: + + int sock_; +}; + +} // namespace protorpc + +#endif // PROTORPC_CONN_H__ + diff --git a/3rdparty/protorpc/rpc_conn_posix.cc b/3rdparty/protorpc/rpc_conn_posix.cc new file mode 100644 index 0000000..eae39c9 --- /dev/null +++ b/3rdparty/protorpc/rpc_conn_posix.cc @@ -0,0 +1,145 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "3rdparty/protorpc/rpc_conn.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__APPLE__) && !defined(MSG_NOSIGNAL) +# define MSG_NOSIGNAL 0x4000 +#endif + +#ifndef NI_MAXSERV +# define NI_MAXSERV 32 +#endif + +namespace protorpc { + +// [static] +// Initialize socket services +bool InitSocket() { + return true; +} + +bool Conn::IsValid() const { + return sock_ != 0; +} + +bool Conn::DialTCP(const char* host, int port) { + struct sockaddr_in sa; + int status, len; + + if(IsValid()) Close(); + if((sock_ = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + printf("protorpc.Conn.DialTCP: socket failed.\n"); + sock_ = 0; + return false; + } + + memset(sa.sin_zero, 0 , sizeof(sa.sin_zero)); + sa.sin_family = AF_INET; + sa.sin_port = htons(port); + sa.sin_addr.s_addr = inet_addr(host); + size_t addressSize = sizeof(sa); + + if(connect(sock_, (struct sockaddr*)&sa, addressSize) == -1) { + printf("protorpc.Conn.DialTCP: connect failed.\n"); + Close(); + return false; + } + + int flag = 1; + setsockopt(sock_, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(flag)); + return true; +} + +bool Conn::ListenTCP(int port, int backlog) { + if(IsValid()) Close(); + if((sock_ = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + printf("protorpc.Conn.ListenTCP: socket failed.\n"); + sock_ = 0; + return false; + } + + struct sockaddr_in saddr; + memset(&saddr, 0, sizeof(saddr)); + saddr.sin_family = AF_INET; + saddr.sin_addr.s_addr = htonl(INADDR_ANY); + saddr.sin_port = htons((u_short) port); + + if(bind(sock_, (struct sockaddr*)&saddr, sizeof(saddr)) == -1) { + printf("protorpc.Conn.ListenTCP: bind failed.\n"); + Close(); + return false; + } + if(::listen(sock_, backlog) != 0) { + printf("protorpc.Conn.ListenTCP: listen failed.\n"); + Close(); + return false; + } + + int flag = 1; + setsockopt(sock_, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(flag)); + return true; +} + +void Conn::Close() { + if(IsValid()) { + ::close(sock_); + sock_ = 0; + } +} + +Conn* Conn::Accept() { + struct sockaddr_in addr; + socklen_t addrlen = sizeof(addr); + int sock = ::accept(sock_, (struct sockaddr*)&addr, &addrlen); + if(sock == 0) { + printf("protorpc.Conn.Accept: failed.\n"); + return NULL; + } + return new Conn(sock); +} + +bool Conn::Read (void* buf, int len) { + char *cbuf = (char*)buf; + while(len > 0) { + int sent = recv(sock_, cbuf, len, 0); + if(sent == 0 || sent == -1) { + printf("protorpc.Conn.Read: IO error, err = %d.\n", errno); + return false; + } + cbuf += sent; + len -= sent; + } + return true; +} +bool Conn::Write(void* buf, int len) { + const char *cbuf = (char*)buf; + int flags = MSG_NOSIGNAL; + + while(len > 0) { + int sent = send(sock_, cbuf, len, flags); + if(sent == -1) { + printf("protorpc.Conn.Write: IO error, err = %d.\n", errno); + return false; + } + cbuf += sent; + len -= sent; + } + return true; +} + +} // namespace protorpc diff --git a/3rdparty/protorpc/rpc_conn_windows.cc b/3rdparty/protorpc/rpc_conn_windows.cc new file mode 100644 index 0000000..2ea5083 --- /dev/null +++ b/3rdparty/protorpc/rpc_conn_windows.cc @@ -0,0 +1,150 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "3rdparty/protorpc/rpc_conn.h" + +#include + +#ifdef _MSC_VER +# include /* send,recv,socklen_t etc */ +# include /* addrinfo */ +# pragma comment(lib, "ws2_32.lib") +#else +# include /* send,recv,socklen_t etc */ +# include +typedef int socklen_t; +#endif + +#ifndef NI_MAXSERV +# define NI_MAXSERV 32 +#endif + +namespace protorpc { + +// [static] +// Initialize socket services +bool InitSocket() { + WSADATA wsaData; + WORD wVers; + static bool called_once = false; + static bool retval = false; + + if(called_once) return retval; + + called_once = true; + wVers = MAKEWORD(1, 1); + retval = (WSAStartup(wVers, &wsaData) == 0); + + return retval; +} + +bool Conn::IsValid() const { + return sock_ != 0; +} + +bool Conn::DialTCP(const char* host, int port) { + if(IsValid()) Close(); + if((sock_ = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + printf("protorpc.Conn.DialTCP: socket failed.\n"); + sock_ = 0; + return false; + } + + struct sockaddr_in sa; + socklen_t addressSize; + memset(sa.sin_zero, 0 , sizeof(sa.sin_zero)); + sa.sin_family = AF_INET; + sa.sin_port = htons(port); + sa.sin_addr.s_addr = inet_addr(host); + addressSize = sizeof(sa); + + if(connect(sock_, ( struct sockaddr*)&sa, addressSize) == -1 ) { + printf("protorpc.Conn.DialTCP: connect failed.\n"); + Close(); + return false; + } + + int flag = 1; + setsockopt(sock_, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(flag)); + return true; +} + +bool Conn::ListenTCP(int port, int backlog) { + if(IsValid()) Close(); + if((sock_ = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + printf("protorpc.Conn.ListenTCP: socket failed.\n"); + sock_ = 0; + return false; + } + + struct sockaddr_in saddr; + memset(&saddr, 0, sizeof(saddr)); + saddr.sin_family = AF_INET; + saddr.sin_addr.s_addr = htonl(INADDR_ANY); + saddr.sin_port = htons((u_short) port); + + if(bind(sock_, (struct sockaddr*)&saddr, sizeof(saddr)) == -1) { + printf("protorpc.Conn.ListenTCP: bind failed.\n"); + Close(); + return false; + } + if(::listen(sock_, backlog) != 0) { + printf("protorpc.Conn.ListenTCP: listen failed.\n"); + Close(); + return false; + } + + int flag = 1; + setsockopt(sock_, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(flag)); + return true; +} + +void Conn::Close() { + if(IsValid()) { + ::closesocket(sock_); + sock_ = 0; + } +} + +Conn* Conn::Accept() { + struct sockaddr_in addr; + int addrlen = sizeof(addr); + int sock = ::accept(sock_, (struct sockaddr*)&addr, &addrlen); + if(sock == 0) { + printf("protorpc.Conn.Accept: failed.\n"); + return NULL; + } + return new Conn(sock); +} + +bool Conn::Read (void* buf, int len) { + char *cbuf = (char*)buf; + while(len > 0) { + int sent = recv(sock_, cbuf, len, 0); + if(sent == 0 || sent == -1) { + printf("protorpc.Conn.Read: IO error, err = %d.\n", WSAGetLastError()); + return false; + } + cbuf += sent; + len -= sent; + } + return true; +} +bool Conn::Write(void* buf, int len) { + const char *cbuf = (char*)buf; + int flags = 0; + + while(len > 0) { + int sent = send(sock_, cbuf, len, flags ); + if(sent == -1) { + printf("protorpc.Conn.Write: IO error, err = %d.\n", WSAGetLastError()); + return false; + } + cbuf += sent; + len -= sent; + } + return true; +} + +} // namespace protorpc diff --git a/3rdparty/protorpc/rpc_error.h b/3rdparty/protorpc/rpc_error.h new file mode 100644 index 0000000..d7f7647 --- /dev/null +++ b/3rdparty/protorpc/rpc_error.h @@ -0,0 +1,32 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#pragma once + +#ifndef PROTORPC_ERROR_H__ +#define PROTORPC_ERROR_H__ + +namespace protorpc { + +// Error +class Error { +public: + Error(){} + Error(const std::string& err): err_text_(err) {} + Error(const Error& err): err_text_(err.err_text_) {} + ~Error(){} + + static Error Nil() { return Error(); } + static Error New(const std::string& err) { return Error(err); } + + bool IsNil()const { return err_text_.empty(); } + const std::string& String()const { return err_text_; } + +private: + std::string err_text_; +}; + +} // namespace protorpc + +#endif // PROTORPC_ERROR_H__ diff --git a/3rdparty/protorpc/rpc_wire.cc b/3rdparty/protorpc/rpc_wire.cc new file mode 100644 index 0000000..a45febd --- /dev/null +++ b/3rdparty/protorpc/rpc_wire.cc @@ -0,0 +1,158 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "3rdparty/protorpc/rpc_wire.h" + +namespace protorpc { +namespace wire { + +Error SendRequest(Conn* conn, + uint64_t id, const std::string& serviceMethod, + const ::std::string* request +) { + // marshal request + std::string pbRequest; + if(request != NULL) { + pbRequest = *request; + } + + // generate header + RequestHeader header; + + header.id = id; + header.method = serviceMethod; + + header.raw_request_len = pbRequest.size(); + + // check header size + std::string pbHeader = spb::pb::serialize(header); + if(pbHeader.size() > (unsigned int)protorpc::wire::Const::MAX_REQUEST_HEADER_LEN) { + return Error::New("protorpc.SendRequest: header larger than max_header_len."); + } + + // send header + if(!conn->SendFrame(&pbHeader)) { + return Error::New("protorpc.SendRequest: SendFrame header failed."); + } + + // send body + if(!conn->SendFrame(&pbRequest)) { + return Error::New("protorpc.SendRequest: SendFrame body failed."); + } + + return Error::Nil(); +} + +Error RecvRequestHeader(Conn* conn, + RequestHeader* header +) { + // recv header + std::string pbHeader; + if(!conn->RecvFrame(&pbHeader)) { + return Error::New("protorpc.RecvRequestHeader: RecvFrame failed."); + } + if(pbHeader.size() > (unsigned int)protorpc::wire::Const::MAX_REQUEST_HEADER_LEN) { + return Error::New("protorpc.RecvRequestHeader: RecvFrame larger than max_header_len."); + } + + // Marshal Header + *header = spb::pb::deserialize(pbHeader); + + return Error::Nil(); +} + +Error RecvRequestBody(Conn* conn, + const RequestHeader* header, + ::std::string* request +) { + // recv body + std::string pbRequest; + if(!conn->RecvFrame(&pbRequest)) { + return Error::New("protorpc.RecvRequestBody: RecvFrame failed."); + } + + // check wire header: rawMsgLen + if(pbRequest.size() != header->raw_request_len) { + return Error::New("protorpc.RecvRequestBody: Unexcpeted raw msg len."); + } + + // marshal request + *request = pbRequest; + + return Error::Nil(); +} + +Error SendResponse(Conn* conn, + uint64_t id, const std::string& error, + const ::std::string* response +) { + // marshal response + std::string pbResponse; + if(response != NULL) { + pbResponse = *response; + } + + // generate header + ResponseHeader header; + + header.id = id; + header.error = error; + + header.raw_response_len = pbResponse.size(); + + // check header size + std::string pbHeader = spb::pb::serialize(header); + + + // send header + if(!conn->SendFrame(&pbHeader)) { + return Error::New("protorpc.SendResponse: SendFrame header failed."); + } + + // send body + if(!conn->SendFrame(&pbResponse)) { + return Error::New("protorpc.SendResponse: SendFrame body failed."); + } + + return Error::Nil(); +} + +Error RecvResponseHeader(Conn* conn, + ResponseHeader* header +) { + // recv header + std::string pbHeader; + if(!conn->RecvFrame(&pbHeader)) { + return Error::New("protorpc.RecvResponseHeader: RecvFrame failed."); + } + + // Marshal Header + *header = spb::pb::deserialize(pbHeader); + + return Error::Nil(); +} + +Error RecvResponseBody(Conn* conn, + const ResponseHeader* header, + ::std::string* response +) { + // recv body + std::string pbResponse; + if(!conn->RecvFrame(&pbResponse)) { + return Error::New("protorpc.RecvResponseBody: RecvFrame failed."); + } + + // check wire header: rawMsgLen + if(pbResponse.size() != header->raw_response_len) { + return Error::New("protorpc.RecvResponseBody: Unexcpeted raw msg len."); + } + + // marshal response + *response = pbResponse; + + return Error::Nil(); +} + +} // namespace wire +} // namespace protorpc diff --git a/3rdparty/protorpc/rpc_wire.h b/3rdparty/protorpc/rpc_wire.h new file mode 100644 index 0000000..2e13e23 --- /dev/null +++ b/3rdparty/protorpc/rpc_wire.h @@ -0,0 +1,48 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#pragma once + +#ifndef PROTORPC_WIRE_H__ +#define PROTORPC_WIRE_H__ + +#include +#include + +#include "3rdparty/protorpc/wire.pb/wire.pb.h" +#include "3rdparty/protorpc/rpc_error.h" +#include "3rdparty/protorpc/rpc_conn.h" + +namespace protorpc { +namespace wire { + +Error SendRequest(Conn* conn, + uint64_t id, const std::string& serviceMethod, + const ::std::string* request +); +Error RecvRequestHeader(Conn* conn, + RequestHeader* header +); +Error RecvRequestBody(Conn* conn, + const RequestHeader* header, + ::std::string* request +); + +Error SendResponse(Conn* conn, + uint64_t id, const std::string& error, + const ::std::string* response +); +Error RecvResponseHeader(Conn* conn, + ResponseHeader* header +); +Error RecvResponseBody(Conn* conn, + const ResponseHeader* header, + ::std::string* request +); + +} // namespace wire +} // namespace protorpc + +#endif // PROTORPC_WIRE_H__ + diff --git a/3rdparty/protorpc/wire.pb/wire.pb.cc b/3rdparty/protorpc/wire.pb/wire.pb.cc new file mode 100644 index 0000000..c2c29d2 --- /dev/null +++ b/3rdparty/protorpc/wire.pb/wire.pb.cc @@ -0,0 +1,197 @@ +#include "wire.pb.h" +#include +#include +#include + +namespace spb::json +{ +namespace detail +{ +void serialize_value( detail::ostream & stream, const ::protorpc::wire::Const & value ) +{ + switch( value ) + { + case ::protorpc::wire::Const::ZERO: + return stream.serialize( "ZERO"sv); + case ::protorpc::wire::Const::MAX_REQUEST_HEADER_LEN: + return stream.serialize( "MAX_REQUEST_HEADER_LEN"sv); + default: + throw std::system_error( std::make_error_code( std::errc::invalid_argument ) ); + } +} + +void deserialize_value( detail::istream & stream, ::protorpc::wire::Const & value ) +{ + auto enum_value = stream.deserialize_string_or_int( 4, 22 ); + std::visit( detail::overloaded{ + [&]( std::string_view enum_str ) + { + const auto enum_hash = djb2_hash( enum_str ); + switch( enum_hash ) + { + case detail::djb2_hash( "ZERO"sv ): + if( enum_str == "ZERO"sv ){ + value = ::protorpc::wire::Const::ZERO; + return ; } + break ; + case detail::djb2_hash( "MAX_REQUEST_HEADER_LEN"sv ): + if( enum_str == "MAX_REQUEST_HEADER_LEN"sv ){ + value = ::protorpc::wire::Const::MAX_REQUEST_HEADER_LEN; + return ; } + break ; + } + throw std::system_error( std::make_error_code( std::errc::invalid_argument ) ); + }, + [&]( int32_t enum_int ) + { + switch( ::protorpc::wire::Const( enum_int ) ) + { + case ::protorpc::wire::Const::ZERO: + case ::protorpc::wire::Const::MAX_REQUEST_HEADER_LEN: + value = ::protorpc::wire::Const( enum_int ); + return ; + } + throw std::system_error( std::make_error_code( std::errc::invalid_argument ) ); + } + }, enum_value ); +} + +} // namespace detail +namespace detail +{ +void serialize_value( detail::ostream & stream, const ::protorpc::wire::RequestHeader & value ) +{ + stream.serialize( "id"sv, value.id ); + stream.serialize( "method"sv, value.method ); + stream.serialize( "raw_request_len"sv, value.raw_request_len ); +} +void deserialize_value( detail::istream & stream, ::protorpc::wire::RequestHeader & value ) +{ + auto key = stream.deserialize_key( 2, 15 ); + switch( djb2_hash( key ) ) + { + case detail::djb2_hash( "id"sv ): + if( key == "id"sv ) + { + return stream.deserialize( value.id ); + } + break; + case detail::djb2_hash( "method"sv ): + if( key == "method"sv ) + { + return stream.deserialize( value.method ); + } + break; + case detail::djb2_hash( "raw_request_len"sv ): + if( key == "raw_request_len"sv ) + { + return stream.deserialize( value.raw_request_len ); + } + break; + case detail::djb2_hash( "rawRequestLen"sv ): + if( key == "rawRequestLen"sv ) + { + return stream.deserialize( value.raw_request_len ); + } + break; + } + return stream.skip_value( ); +} +} // namespace detail +namespace detail +{ +void serialize_value( detail::ostream & stream, const ::protorpc::wire::ResponseHeader & value ) +{ + stream.serialize( "id"sv, value.id ); + stream.serialize( "error"sv, value.error ); + stream.serialize( "raw_response_len"sv, value.raw_response_len ); +} +void deserialize_value( detail::istream & stream, ::protorpc::wire::ResponseHeader & value ) +{ + auto key = stream.deserialize_key( 2, 16 ); + switch( djb2_hash( key ) ) + { + case detail::djb2_hash( "id"sv ): + if( key == "id"sv ) + { + return stream.deserialize( value.id ); + } + break; + case detail::djb2_hash( "error"sv ): + if( key == "error"sv ) + { + return stream.deserialize( value.error ); + } + break; + case detail::djb2_hash( "rawResponseLen"sv ): + if( key == "rawResponseLen"sv ) + { + return stream.deserialize( value.raw_response_len ); + } + break; + case detail::djb2_hash( "raw_response_len"sv ): + if( key == "raw_response_len"sv ) + { + return stream.deserialize( value.raw_response_len ); + } + break; + } + return stream.skip_value( ); +} +} // namespace detail +} // namespace spb::json +#include "wire.pb.h" +#include +#include + +namespace spb::pb +{ +namespace detail +{ +void serialize( detail::ostream & stream, const ::protorpc::wire::RequestHeader & value ) +{ + stream.serialize_as( 1, value.id ); + stream.serialize( 2, value.method ); + stream.serialize_as( 3, value.raw_request_len ); +} +void deserialize_value( detail::istream & stream, ::protorpc::wire::RequestHeader & value, uint32_t tag ) +{ + switch( field_from_tag( tag ) ) + { + case 1: + return stream.deserialize_as( value.id, tag ); + case 2: + return stream.deserialize( value.method, tag ); + case 3: + return stream.deserialize_as( value.raw_request_len, tag ); + default: + return stream.skip( tag ); +} +} + +} // namespace detail +namespace detail +{ +void serialize( detail::ostream & stream, const ::protorpc::wire::ResponseHeader & value ) +{ + stream.serialize_as( 1, value.id ); + stream.serialize( 2, value.error ); + stream.serialize_as( 3, value.raw_response_len ); +} +void deserialize_value( detail::istream & stream, ::protorpc::wire::ResponseHeader & value, uint32_t tag ) +{ + switch( field_from_tag( tag ) ) + { + case 1: + return stream.deserialize_as( value.id, tag ); + case 2: + return stream.deserialize( value.error, tag ); + case 3: + return stream.deserialize_as( value.raw_response_len, tag ); + default: + return stream.skip( tag ); +} +} + +} // namespace detail +} // namespace spb::pb diff --git a/3rdparty/protorpc/wire.pb/wire.pb.h b/3rdparty/protorpc/wire.pb/wire.pb.h new file mode 100644 index 0000000..06b21c2 --- /dev/null +++ b/3rdparty/protorpc/wire.pb/wire.pb.h @@ -0,0 +1,85 @@ +#pragma once + +#include +#include +#include +#include +#include + +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// protorpc wire format wrapper +// +// 0. Frame Format +// len : uvarint64 +// data: byte[len] +// +// 1. Client Send Request +// Send RequestHeader: sendFrame(zsock, hdr, len(hdr)) +// Send Request: sendFrame(zsock, body, hdr.snappy_compressed_request_len) +// +// 2. Server Recv Request +// Recv RequestHeader: recvFrame(zsock, hdr, max_hdr_len, 0) +// Recv Request: recvFrame(zsock, body, hdr.snappy_compressed_request_len, 0) +// +// 3. Server Send Response +// Send ResponseHeader: sendFrame(zsock, hdr, len(hdr)) +// Send Response: sendFrame(zsock, body, hdr.snappy_compressed_response_len) +// +// 4. Client Recv Response +// Recv ResponseHeader: recvFrame(zsock, hdr, max_hdr_len, 0) +// Recv Response: recvFrame(zsock, body, hdr.snappy_compressed_response_len, 0) +// +namespace protorpc::wire +{ +enum class Const : int32_t +{ +ZERO = 0, +MAX_REQUEST_HEADER_LEN = 1024, +}; +struct RequestHeader +{ +uint64_t id; +std::string method; +uint32_t raw_request_len; +}; +struct ResponseHeader +{ +uint64_t id; +std::string error; +uint32_t raw_response_len; +}; +}// namespace protorpc::wire + +namespace spb::json::detail +{ +struct ostream; +struct istream; + +void serialize_value( ostream & stream, const protorpc::wire::RequestHeader & value ); +void deserialize_value( istream & stream, protorpc::wire::RequestHeader & value ); + + +void serialize_value( ostream & stream, const protorpc::wire::ResponseHeader & value ); +void deserialize_value( istream & stream, protorpc::wire::ResponseHeader & value ); + + +void serialize_value( ostream & stream, const protorpc::wire::Const & value ); +void deserialize_value( istream & stream, protorpc::wire::Const & value ); + +} // namespace spb::json::detail +namespace spb::pb::detail +{ +struct ostream; +struct istream; + +void serialize( ostream & stream, const protorpc::wire::RequestHeader & value ); +void deserialize_value( istream & stream, protorpc::wire::RequestHeader & value, uint32_t tag ); + + +void serialize( ostream & stream, const protorpc::wire::ResponseHeader & value ); +void deserialize_value( istream & stream, protorpc::wire::ResponseHeader & value, uint32_t tag ); + +} // namespace spb::pb::detail diff --git a/3rdparty/protorpc/wire.pb/wire.proto b/3rdparty/protorpc/wire.pb/wire.proto new file mode 100644 index 0000000..f1e1df5 --- /dev/null +++ b/3rdparty/protorpc/wire.pb/wire.proto @@ -0,0 +1,50 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +syntax = "proto2"; + +// +// protorpc wire format wrapper +// +// 0. Frame Format +// len : uvarint64 +// data: byte[len] +// +// 1. Client Send Request +// Send RequestHeader: sendFrame(zsock, hdr, len(hdr)) +// Send Request: sendFrame(zsock, body, hdr.snappy_compressed_request_len) +// +// 2. Server Recv Request +// Recv RequestHeader: recvFrame(zsock, hdr, max_hdr_len, 0) +// Recv Request: recvFrame(zsock, body, hdr.snappy_compressed_request_len, 0) +// +// 3. Server Send Response +// Send ResponseHeader: sendFrame(zsock, hdr, len(hdr)) +// Send Response: sendFrame(zsock, body, hdr.snappy_compressed_response_len) +// +// 4. Client Recv Response +// Recv ResponseHeader: recvFrame(zsock, hdr, max_hdr_len, 0) +// Recv Response: recvFrame(zsock, body, hdr.snappy_compressed_response_len, 0) +// +package protorpc.wire; +option go_package = "protorpc.wire"; + +enum Const { + ZERO = 0; + MAX_REQUEST_HEADER_LEN = 1024; +} + +message RequestHeader { + required uint64 id = 1; + required string method = 2; + + required uint32 raw_request_len = 3; +} + +message ResponseHeader { + required uint64 id = 1; + required string error = 2; + + required uint32 raw_response_len = 3; +} diff --git a/CMakeLists.txt b/CMakeLists.txt index ccbd3a6..db9b752 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,7 +85,12 @@ set(PROJECT_SOURCES 3rdparty/quirc/quirc.c 3rdparty/quirc/version_db.c - src/api/gRPC.cpp + 3rdparty/protorpc/rpc_client.cc + 3rdparty/protorpc/rpc_conn.cc + 3rdparty/protorpc/rpc_wire.cc + 3rdparty/protorpc/wire.pb/wire.pb.cc + + src/api/RPC.cpp src/dataStore/Database.cpp src/stats/traffic/TrafficLooper.cpp diff --git a/core/protorpc/.editorconfig b/core/protorpc/.editorconfig new file mode 100644 index 0000000..4aff529 --- /dev/null +++ b/core/protorpc/.editorconfig @@ -0,0 +1,29 @@ +# Copyright 2018 . All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +# http://editorconfig.org/ + +root = true + +# Unix-style newlines with a newline ending every file +[*] +charset = utf-8 +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = true + +[*] +indent_style = tab +indent_size = 4 +tab_width = 4 + +[*.{go,proto}] +charset = utf-8 +indent_style = tab +tab_width = 4 + +# Matches the exact files either package.json or .travis.yml +[{package.json,.travis.yml}] +indent_style = space +indent_size = 2 diff --git a/core/protorpc/.travis.yml b/core/protorpc/.travis.yml new file mode 100644 index 0000000..1f85d88 --- /dev/null +++ b/core/protorpc/.travis.yml @@ -0,0 +1,12 @@ +language: go + +go: + - 1.13 + - 1.14 + - 1.15 + - 1.16 + - tip + +before_script: + - go get github.com/golang/snappy + - go get github.com/golang/protobuf/proto diff --git a/core/protorpc/Dockerfile b/core/protorpc/Dockerfile new file mode 100644 index 0000000..31074fd --- /dev/null +++ b/core/protorpc/Dockerfile @@ -0,0 +1,24 @@ +# Copyright 2018 . All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +FROM golang:1.9.2-alpine3.6 as builder + +RUN apk add --no-cache git curl openssl + +RUN go get github.com/golang/protobuf/protoc-gen-go +RUN go get github.com/chai2010/protorpc/protoc-gen-protorpc +RUN go get github.com/chai2010/protorpc/protoc-gen-stdrpc + +# the protoc can't run on alpine, +# we only need the protobuf's stdarnd library in the `/protoc/include`. +RUN mkdir -p /protoc && cd /protoc \ + && wget https://github.com/google/protobuf/releases/download/v3.5.0/protoc-3.5.0-linux-x86_64.zip \ + && unzip protoc-3.5.0-linux-x86_64.zip + +FROM golang:1.9.2-alpine3.6 + +RUN apk add --no-cache git protobuf make curl openssl + +COPY --from=builder /protoc/include /usr/local/include +COPY --from=builder /go/bin /go/bin \ No newline at end of file diff --git a/core/protorpc/LICENSE b/core/protorpc/LICENSE new file mode 100644 index 0000000..9dd820a --- /dev/null +++ b/core/protorpc/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2014, chai2010 +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the {organization} nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/core/protorpc/README.md b/core/protorpc/README.md new file mode 100644 index 0000000..cc46abd --- /dev/null +++ b/core/protorpc/README.md @@ -0,0 +1,173 @@ +- *Go语言QQ群: 102319854, 1055927514* +- *凹语言(凹读音“Wa”)(The Wa Programming Language): https://github.com/wa-lang/wa* + +---- + +# protorpc + +``` +██████╗ ██████╗ ██████╗ ████████╗ ██████╗ ██████╗ ██████╗ ██████╗ +██╔══██╗██╔══██╗██╔═══██╗╚══██╔══╝██╔═══██╗ ██╔══██╗██╔══██╗██╔════╝ +██████╔╝██████╔╝██║ ██║ ██║ ██║ ██║█████╗██████╔╝██████╔╝██║ +██╔═══╝ ██╔══██╗██║ ██║ ██║ ██║ ██║╚════╝██╔══██╗██╔═══╝ ██║ +██║ ██║ ██║╚██████╔╝ ██║ ╚██████╔╝ ██║ ██║██║ ╚██████╗ +╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═════╝ +``` + +[![Build Status](https://travis-ci.org/chai2010/protorpc.svg)](https://travis-ci.org/chai2010/protorpc) +[![GoDoc](https://godoc.org/github.com/chai2010/protorpc?status.svg)](https://godoc.org/github.com/chai2010/protorpc) + +- C++ Version(Proto2): [https://github.com/chai2010/protorpc.cxx](https://github.com/chai2010/protorpc.cxx) +- C++ Version(Proto3): [https://github.com/chai2010/protorpc3-cxx](https://github.com/chai2010/protorpc3-cxx) +- Talks: [Go/C++语言Protobuf-RPC简介](http://go-talks.appspot.com/github.com/chai2010/talks/chai2010-protorpc-intro.slide) + +# Install + +Install `protorpc` package: + +1. `go install github.com/golang/protobuf/protoc-gen-go` +1. `go get github.com/chai2010/protorpc` +1. `go run hello.go` + +Install `protoc-gen-go` plugin: + +1. install `protoc` at first: http://github.com/google/protobuf/releases +1. `go get github.com/golang/protobuf/protoc-gen-go` +1. `go get github.com/chai2010/protorpc/protoc-gen-protorpc` +1. `go generate github.com/chai2010/protorpc/examples/service.pb` +1. `go test github.com/chai2010/protorpc/examples/service.pb` + + +# Examples + +First, create [echo.proto](examples/service.pb/echo.proto): + +```Proto +syntax = "proto3"; + +package service; + +message EchoRequest { + string msg = 1; +} + +message EchoResponse { + string msg = 1; +} + +service EchoService { + rpc Echo (EchoRequest) returns (EchoResponse); + rpc EchoTwice (EchoRequest) returns (EchoResponse); +} +``` + +Second, generate [echo.pb.go](examples/service.pb/echo.pb.go) and [echo.pb.protorpc.go](examples/service.pb/echo.pb.protorpc.go) +from [echo.proto](examples/service.pb/echo.proto) (we can use `go generate` to invoke this command, see [proto.go](examples/service.pb/proto.go)). + + protoc --go_out=. echo.proto + protoc --protorpc_out=. echo.proto + + +Now, we can use the stub code like this: + +```Go +package main + +import ( + "fmt" + "log" + + "github.com/chai2010/protorpc" + service "github.com/chai2010/protorpc/examples/service.pb" +) + +type Echo int + +func (t *Echo) Echo(args *service.EchoRequest, reply *service.EchoResponse) error { + reply.Msg = args.Msg + return nil +} + +func (t *Echo) EchoTwice(args *service.EchoRequest, reply *service.EchoResponse) error { + reply.Msg = args.Msg + args.Msg + return nil +} + +func init() { + go service.ListenAndServeEchoService("tcp", `127.0.0.1:9527`, new(Echo)) +} + +func main() { + echoClient, err := service.DialEchoService("tcp", `127.0.0.1:9527`) + if err != nil { + log.Fatalf("service.DialEchoService: %v", err) + } + defer echoClient.Close() + + args := &service.EchoRequest{Msg: "你好, 世界!"} + reply, err := echoClient.EchoTwice(args) + if err != nil { + log.Fatalf("echoClient.EchoTwice: %v", err) + } + fmt.Println(reply.Msg) + + // or use normal client + client, err := protorpc.Dial("tcp", `127.0.0.1:9527`) + if err != nil { + log.Fatalf("protorpc.Dial: %v", err) + } + defer client.Close() + + echoClient1 := &service.EchoServiceClient{client} + echoClient2 := &service.EchoServiceClient{client} + reply, err = echoClient1.EchoTwice(args) + reply, err = echoClient2.EchoTwice(args) + _, _ = reply, err + + // Output: + // 你好, 世界!你好, 世界! +} +``` + +[More examples](examples). + +# standard net/rpc + +First, create [echo.proto](examples/stdrpc.pb/echo.proto): + +```Proto +syntax = "proto3"; + +package service; + +message EchoRequest { + string msg = 1; +} + +message EchoResponse { + string msg = 1; +} + +service EchoService { + rpc Echo (EchoRequest) returns (EchoResponse); + rpc EchoTwice (EchoRequest) returns (EchoResponse); +} +``` + +Second, generate [echo.pb.go](examples/stdrpc.pb/echo.pb.go) from [echo.proto](examples/stdrpc.pb/echo.proto) with `protoc-gen-stdrpc` plugin. + + protoc --stdrpc_out=. echo.proto + +The stdrpc plugin generated code do not depends **protorpc** package, it use gob as the default rpc encoding. + +# Add prefix + +``` +$ ENV_PROTOC_GEN_PROTORPC_FLAG_PREFIX=abc protoc --protorpc_out=. x.proto +``` + +# BUGS + +Report bugs to . + +Thanks! diff --git a/core/protorpc/changelog.md b/core/protorpc/changelog.md new file mode 100644 index 0000000..e50dec6 --- /dev/null +++ b/core/protorpc/changelog.md @@ -0,0 +1,23 @@ +# Changelogs + +## 1.1.3 - 2021.7.12 + +- fix `readRequestHeader` maxSize, response error maybe very long + +## 1.1.2 - 2021.7.6 + +- fix `UseSnappy` typo + +## 1.1.1 - 2021.7.4 + +- protoc-gen-plugin: ignore format error + +## 1.1.0 - 2021.7.4 + +- add `UseSappy` and `UseCrc32ChecksumIEEE` +- add `ENV_PROTOC_GEN_PROTORPC_FLAG_PREFIX` env flag +- fix frame size overflow panic (issue12) + +## 1.0.0 - go mod version (2018) + +- init version diff --git a/core/protorpc/client.go b/core/protorpc/client.go new file mode 100644 index 0000000..2348d95 --- /dev/null +++ b/core/protorpc/client.go @@ -0,0 +1,135 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package protorpc + +import ( + "fmt" + "io" + "net" + "net/rpc" + "sync" + "time" + + wire "github.com/chai2010/protorpc/wire.pb" + "github.com/golang/protobuf/proto" +) + +type clientCodec struct { + r io.Reader + w io.Writer + c io.Closer + + // temporary work space + respHeader wire.ResponseHeader + + // Protobuf-RPC responses include the request id but not the request method. + // Package rpc expects both. + // We save the request method in pending when sending a request + // and then look it up by request ID when filling out the rpc Response. + mutex sync.Mutex // protects pending + pending map[uint64]string // map request id to method name +} + +// NewClientCodec returns a new rpc.ClientCodec using Protobuf-RPC on conn. +func NewClientCodec(conn io.ReadWriteCloser) rpc.ClientCodec { + return &clientCodec{ + r: conn, + w: conn, + c: conn, + pending: make(map[uint64]string), + } +} + +func (c *clientCodec) WriteRequest(r *rpc.Request, param interface{}) error { + c.mutex.Lock() + c.pending[r.Seq] = r.ServiceMethod + c.mutex.Unlock() + + var request proto.Message + if param != nil { + var ok bool + if request, ok = param.(proto.Message); !ok { + return fmt.Errorf( + "protorpc.ClientCodec.WriteRequest: %T does not implement proto.Message", + param, + ) + } + } + err := writeRequest(c.w, r.Seq, r.ServiceMethod, request) + if err != nil { + return err + } + + return nil +} + +func (c *clientCodec) ReadResponseHeader(r *rpc.Response) error { + header := wire.ResponseHeader{} + err := readResponseHeader(c.r, &header) + if err != nil { + return err + } + + c.mutex.Lock() + r.Seq = *header.Id + r.Error = *header.Error + r.ServiceMethod = c.pending[r.Seq] + delete(c.pending, r.Seq) + c.mutex.Unlock() + + c.respHeader = header + return nil +} + +func (c *clientCodec) ReadResponseBody(x interface{}) error { + var response proto.Message + if x != nil { + var ok bool + response, ok = x.(proto.Message) + if !ok { + return fmt.Errorf( + "protorpc.ClientCodec.ReadResponseBody: %T does not implement proto.Message", + x, + ) + } + } + + err := readResponseBody(c.r, &c.respHeader, response) + if err != nil { + return nil + } + + c.respHeader = wire.ResponseHeader{} + return nil +} + +// Close closes the underlying connection. +func (c *clientCodec) Close() error { + return c.c.Close() +} + +// NewClient returns a new rpc.Client to handle requests to the +// set of services at the other end of the connection. +func NewClient(conn io.ReadWriteCloser) *rpc.Client { + return rpc.NewClientWithCodec(NewClientCodec(conn)) +} + +// Dial connects to a Protobuf-RPC server at the specified network address. +func Dial(network, address string) (*rpc.Client, error) { + conn, err := net.Dial(network, address) + if err != nil { + return nil, err + } + return NewClient(conn), err +} + +// DialTimeout connects to a Protobuf-RPC server at the specified network address. +func DialTimeout(network, address string, timeout time.Duration) (*rpc.Client, error) { + conn, err := net.DialTimeout(network, address, timeout) + if err != nil { + return nil, err + } + return NewClient(conn), err +} diff --git a/core/protorpc/conn.go b/core/protorpc/conn.go new file mode 100644 index 0000000..a97c993 --- /dev/null +++ b/core/protorpc/conn.go @@ -0,0 +1,117 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package protorpc + +import ( + "encoding/binary" + "errors" + "fmt" + "io" + "net" +) + +func sendFrame(w io.Writer, data []byte) (err error) { + // Allocate enough space for the biggest uvarint + var size [binary.MaxVarintLen64]byte + + if data == nil || len(data) == 0 { + n := binary.PutUvarint(size[:], uint64(0)) + if err = write(w, size[:n], false); err != nil { + return + } + return + } + + // Write the size and data + n := binary.PutUvarint(size[:], uint64(len(data))) + if err = write(w, size[:n], false); err != nil { + return + } + if err = write(w, data, false); err != nil { + return + } + return +} + +func recvFrame(r io.Reader, maxSize int) (data []byte, err error) { + size, err := readUvarint(r) + if err != nil { + return nil, err + } + if maxSize > 0 { + if int(size) > maxSize { + return nil, fmt.Errorf("protorpc: varint overflows maxSize(%d)", maxSize) + } + } + if size != 0 { + data = make([]byte, size) + if err = read(r, data); err != nil { + return nil, err + } + } + return data, nil +} + +// ReadUvarint reads an encoded unsigned integer from r and returns it as a uint64. +func readUvarint(r io.Reader) (uint64, error) { + var x uint64 + var s uint + for i := 0; ; i++ { + var b byte + b, err := readByte(r) + if err != nil { + return 0, err + } + if b < 0x80 { + if i > 9 || i == 9 && b > 1 { + return x, errors.New("protorpc: varint overflows a 64-bit integer") + } + return x | uint64(b)<. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Package protorpc implements a Protobuf-RPC ClientCodec and ServerCodec +for the rpc package. + +To install it, you must first have Go (version 1) installed +(see http://golang.org/doc/install). Next, install the standard +protocol buffer implementation from http://github.com/google/protobuf/; +you must be running version 2.3 or higher. + +Finally run + + go get github.com/chai2010/protorpc + go get github.com/chai2010/protorpc/protoc-gen-protorpc + +to install the support library and protocol compiler. + +Here is a simple proto file("arith.pb/arith.proto"): + + package arith; + + message ArithRequest { + optional int32 a = 1; + optional int32 b = 2; + } + + message ArithResponse { + optional int32 val = 1; + optional int32 quo = 2; + optional int32 rem = 3; + } + + service ArithService { + rpc multiply (ArithRequest) returns (ArithResponse); + rpc divide (ArithRequest) returns (ArithResponse); + } + +Then use "protoc-gen-go" to generate "arith.pb.go" file: + + cd arith.pb && protoc --go_out=. arith.proto + + +Use "protoc-gen-protorpc" to generate "arith.pb.protorpc.go" file (include stub code): + + cd arith.pb && protoc --protorpc_out=. arith.proto + +The server calls (for TCP service): + + package server + + import ( + "errors" + + "github.com/golang/protobuf/proto" + + "./arith.pb" + ) + + type Arith int + + func (t *Arith) Multiply(args *arith.ArithRequest, reply *arith.ArithResponse) error { + reply.Val = proto.Int32(args.GetA() * args.GetB()) + return nil + } + + func (t *Arith) Divide(args *arith.ArithRequest, reply *arith.ArithResponse) error { + if args.GetB() == 0 { + return errors.New("divide by zero") + } + reply.Quo = proto.Int32(args.GetA() / args.GetB()) + reply.Rem = proto.Int32(args.GetA() % args.GetB()) + return nil + } + + func main() { + arith.ListenAndServeArithService("tcp", ":1984", new(Arith)) + } + +At this point, clients can see a service "Arith" with methods "ArithService.Multiply" and +"ArithService.Divide". To invoke one, a client first dials the server: + + stub, err := arith.DialArithService("tcp", "127.0.0.1:1984") + if err != nil { + log.Fatal(`arith.DialArithService("tcp", "127.0.0.1:1984"):`, err) + } + defer stub.Close() + +Then it can make a remote call with stub: + + var args ArithRequest + + args.A = proto.Int32(7) + args.B = proto.Int32(8) + reply, err := stub.Multiply(&args, &reply) + if err != nil { + log.Fatal("arith error:", err) + } + fmt.Printf("Arith: %d*%d=%d", args.GetA(), args.GetB(), reply.GetVal()) + +More example: + + go test github.com/chai2010/protorpc/internal/service.pb + +Report bugs to . + +Thanks! +*/ +package protorpc // import "github.com/chai2010/protorpc" diff --git a/core/protorpc/examples/message.pb/arith.pb.go b/core/protorpc/examples/message.pb/arith.pb.go new file mode 100644 index 0000000..e2e7e05 --- /dev/null +++ b/core/protorpc/examples/message.pb/arith.pb.go @@ -0,0 +1,90 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: arith.proto + +/* +Package message is a generated protocol buffer package. + +It is generated from these files: + arith.proto + echo.proto + +It has these top-level messages: + ArithRequest + ArithResponse + EchoRequest + EchoResponse +*/ +package message + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +type ArithRequest struct { + A int32 `protobuf:"varint,1,opt,name=a" json:"a,omitempty"` + B int32 `protobuf:"varint,2,opt,name=b" json:"b,omitempty"` +} + +func (m *ArithRequest) Reset() { *m = ArithRequest{} } +func (m *ArithRequest) String() string { return proto.CompactTextString(m) } +func (*ArithRequest) ProtoMessage() {} +func (*ArithRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +func (m *ArithRequest) GetA() int32 { + if m != nil { + return m.A + } + return 0 +} + +func (m *ArithRequest) GetB() int32 { + if m != nil { + return m.B + } + return 0 +} + +type ArithResponse struct { + C int32 `protobuf:"varint,1,opt,name=c" json:"c,omitempty"` +} + +func (m *ArithResponse) Reset() { *m = ArithResponse{} } +func (m *ArithResponse) String() string { return proto.CompactTextString(m) } +func (*ArithResponse) ProtoMessage() {} +func (*ArithResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +func (m *ArithResponse) GetC() int32 { + if m != nil { + return m.C + } + return 0 +} + +func init() { + proto.RegisterType((*ArithRequest)(nil), "message.ArithRequest") + proto.RegisterType((*ArithResponse)(nil), "message.ArithResponse") +} + +func init() { proto.RegisterFile("arith.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 104 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4e, 0x2c, 0xca, 0x2c, + 0xc9, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xcf, 0x4d, 0x2d, 0x2e, 0x4e, 0x4c, 0x4f, + 0x55, 0xd2, 0xe2, 0xe2, 0x71, 0x04, 0x89, 0x07, 0xa5, 0x16, 0x96, 0xa6, 0x16, 0x97, 0x08, 0xf1, + 0x70, 0x31, 0x26, 0x4a, 0x30, 0x2a, 0x30, 0x6a, 0xb0, 0x06, 0x31, 0x26, 0x82, 0x78, 0x49, 0x12, + 0x4c, 0x10, 0x5e, 0x92, 0x92, 0x2c, 0x17, 0x2f, 0x54, 0x6d, 0x71, 0x41, 0x7e, 0x5e, 0x71, 0x2a, + 0x48, 0x3a, 0x19, 0xa6, 0x38, 0x39, 0x89, 0x0d, 0x6c, 0xb4, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, + 0x61, 0x27, 0x57, 0x32, 0x69, 0x00, 0x00, 0x00, +} diff --git a/core/protorpc/examples/message.pb/arith.proto b/core/protorpc/examples/message.pb/arith.proto new file mode 100644 index 0000000..a6a94dd --- /dev/null +++ b/core/protorpc/examples/message.pb/arith.proto @@ -0,0 +1,16 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +syntax = "proto3"; + +package message; + +message ArithRequest { + int32 a = 1; + int32 b = 2; +} + +message ArithResponse { + int32 c = 1; +} diff --git a/core/protorpc/examples/message.pb/echo.pb.go b/core/protorpc/examples/message.pb/echo.pb.go new file mode 100644 index 0000000..70b1cd3 --- /dev/null +++ b/core/protorpc/examples/message.pb/echo.pb.go @@ -0,0 +1,62 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: echo.proto + +package message + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +type EchoRequest struct { + Msg string `protobuf:"bytes,1,opt,name=msg" json:"msg,omitempty"` +} + +func (m *EchoRequest) Reset() { *m = EchoRequest{} } +func (m *EchoRequest) String() string { return proto.CompactTextString(m) } +func (*EchoRequest) ProtoMessage() {} +func (*EchoRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} } + +func (m *EchoRequest) GetMsg() string { + if m != nil { + return m.Msg + } + return "" +} + +type EchoResponse struct { + Msg string `protobuf:"bytes,1,opt,name=msg" json:"msg,omitempty"` +} + +func (m *EchoResponse) Reset() { *m = EchoResponse{} } +func (m *EchoResponse) String() string { return proto.CompactTextString(m) } +func (*EchoResponse) ProtoMessage() {} +func (*EchoResponse) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{1} } + +func (m *EchoResponse) GetMsg() string { + if m != nil { + return m.Msg + } + return "" +} + +func init() { + proto.RegisterType((*EchoRequest)(nil), "message.EchoRequest") + proto.RegisterType((*EchoResponse)(nil), "message.EchoResponse") +} + +func init() { proto.RegisterFile("echo.proto", fileDescriptor1) } + +var fileDescriptor1 = []byte{ + // 95 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4a, 0x4d, 0xce, 0xc8, + 0xd7, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xcf, 0x4d, 0x2d, 0x2e, 0x4e, 0x4c, 0x4f, 0x55, + 0x92, 0xe7, 0xe2, 0x76, 0x4d, 0xce, 0xc8, 0x0f, 0x4a, 0x2d, 0x2c, 0x4d, 0x2d, 0x2e, 0x11, 0x12, + 0xe0, 0x62, 0xce, 0x2d, 0x4e, 0x97, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x02, 0x31, 0x95, 0x14, + 0xb8, 0x78, 0x20, 0x0a, 0x8a, 0x0b, 0xf2, 0xf3, 0x8a, 0x53, 0x31, 0x55, 0x24, 0xb1, 0x81, 0x8d, + 0x34, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xcb, 0xea, 0xe4, 0xa6, 0x60, 0x00, 0x00, 0x00, +} diff --git a/core/protorpc/examples/message.pb/echo.proto b/core/protorpc/examples/message.pb/echo.proto new file mode 100644 index 0000000..a570e22 --- /dev/null +++ b/core/protorpc/examples/message.pb/echo.proto @@ -0,0 +1,15 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +syntax = "proto3"; + +package message; + +message EchoRequest { + string msg = 1; +} + +message EchoResponse { + string msg = 1; +} diff --git a/core/protorpc/examples/message.pb/proto.go b/core/protorpc/examples/message.pb/proto.go new file mode 100644 index 0000000..ba491c0 --- /dev/null +++ b/core/protorpc/examples/message.pb/proto.go @@ -0,0 +1,7 @@ +// Copyright 2014 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:generate protoc --go_out=. arith.proto echo.proto + +package message diff --git a/core/protorpc/examples/proto3.pb/Makefile b/core/protorpc/examples/proto3.pb/Makefile new file mode 100644 index 0000000..ed789ad --- /dev/null +++ b/core/protorpc/examples/proto3.pb/Makefile @@ -0,0 +1,14 @@ +# Copyright 2013 . All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +PROTO_FILES=$(sort $(wildcard ./*.proto)) + +default: $(PROTO_FILES) Makefile + go install github.com/golang/protobuf/protoc-gen-go + go install github.com/chai2010/protorpc/protoc-gen-protorpc + protoc --go_out=. ${PROTO_FILES} + protoc --protorpc_out=. ${PROTO_FILES} + go test + +clean: diff --git a/core/protorpc/examples/proto3.pb/proto.go b/core/protorpc/examples/proto3.pb/proto.go new file mode 100644 index 0000000..5077734 --- /dev/null +++ b/core/protorpc/examples/proto3.pb/proto.go @@ -0,0 +1,8 @@ +// Copyright 2014 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:generate protoc --go_out=. proto3.proto +//go:generate protoc --protorpc_out=. proto3.proto + +package proto3_proto diff --git a/core/protorpc/examples/proto3.pb/proto3.pb.go b/core/protorpc/examples/proto3.pb/proto3.pb.go new file mode 100644 index 0000000..f238c21 --- /dev/null +++ b/core/protorpc/examples/proto3.pb/proto3.pb.go @@ -0,0 +1,220 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: proto3.proto + +/* +Package proto3_proto is a generated protocol buffer package. + +It is generated from these files: + proto3.proto + +It has these top-level messages: + Message + Nested + MessageWithMap +*/ +package proto3_proto + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +type Message_Humour int32 + +const ( + Message_UNKNOWN Message_Humour = 0 + Message_PUNS Message_Humour = 1 + Message_SLAPSTICK Message_Humour = 2 + Message_BILL_BAILEY Message_Humour = 3 +) + +var Message_Humour_name = map[int32]string{ + 0: "UNKNOWN", + 1: "PUNS", + 2: "SLAPSTICK", + 3: "BILL_BAILEY", +} +var Message_Humour_value = map[string]int32{ + "UNKNOWN": 0, + "PUNS": 1, + "SLAPSTICK": 2, + "BILL_BAILEY": 3, +} + +func (x Message_Humour) String() string { + return proto.EnumName(Message_Humour_name, int32(x)) +} +func (Message_Humour) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 0} } + +type Message struct { + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Hilarity Message_Humour `protobuf:"varint,2,opt,name=hilarity,enum=proto3_proto.Message_Humour" json:"hilarity,omitempty"` + HeightInCm uint32 `protobuf:"varint,3,opt,name=height_in_cm,json=heightInCm" json:"height_in_cm,omitempty"` + Data []byte `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"` + ResultCount int64 `protobuf:"varint,7,opt,name=result_count,json=resultCount" json:"result_count,omitempty"` + TrueScotsman bool `protobuf:"varint,8,opt,name=true_scotsman,json=trueScotsman" json:"true_scotsman,omitempty"` + Score float32 `protobuf:"fixed32,9,opt,name=score" json:"score,omitempty"` + Key []uint64 `protobuf:"varint,5,rep,packed,name=key" json:"key,omitempty"` + Nested *Nested `protobuf:"bytes,6,opt,name=nested" json:"nested,omitempty"` + Terrain map[string]*Nested `protobuf:"bytes,10,rep,name=terrain" json:"terrain,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` +} + +func (m *Message) Reset() { *m = Message{} } +func (m *Message) String() string { return proto.CompactTextString(m) } +func (*Message) ProtoMessage() {} +func (*Message) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +func (m *Message) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Message) GetHilarity() Message_Humour { + if m != nil { + return m.Hilarity + } + return Message_UNKNOWN +} + +func (m *Message) GetHeightInCm() uint32 { + if m != nil { + return m.HeightInCm + } + return 0 +} + +func (m *Message) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +func (m *Message) GetResultCount() int64 { + if m != nil { + return m.ResultCount + } + return 0 +} + +func (m *Message) GetTrueScotsman() bool { + if m != nil { + return m.TrueScotsman + } + return false +} + +func (m *Message) GetScore() float32 { + if m != nil { + return m.Score + } + return 0 +} + +func (m *Message) GetKey() []uint64 { + if m != nil { + return m.Key + } + return nil +} + +func (m *Message) GetNested() *Nested { + if m != nil { + return m.Nested + } + return nil +} + +func (m *Message) GetTerrain() map[string]*Nested { + if m != nil { + return m.Terrain + } + return nil +} + +type Nested struct { + Bunny string `protobuf:"bytes,1,opt,name=bunny" json:"bunny,omitempty"` +} + +func (m *Nested) Reset() { *m = Nested{} } +func (m *Nested) String() string { return proto.CompactTextString(m) } +func (*Nested) ProtoMessage() {} +func (*Nested) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +func (m *Nested) GetBunny() string { + if m != nil { + return m.Bunny + } + return "" +} + +type MessageWithMap struct { + ByteMapping map[bool][]byte `protobuf:"bytes,1,rep,name=byte_mapping,json=byteMapping" json:"byte_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (m *MessageWithMap) Reset() { *m = MessageWithMap{} } +func (m *MessageWithMap) String() string { return proto.CompactTextString(m) } +func (*MessageWithMap) ProtoMessage() {} +func (*MessageWithMap) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } + +func (m *MessageWithMap) GetByteMapping() map[bool][]byte { + if m != nil { + return m.ByteMapping + } + return nil +} + +func init() { + proto.RegisterType((*Message)(nil), "proto3_proto.Message") + proto.RegisterType((*Nested)(nil), "proto3_proto.Nested") + proto.RegisterType((*MessageWithMap)(nil), "proto3_proto.MessageWithMap") + proto.RegisterEnum("proto3_proto.Message_Humour", Message_Humour_name, Message_Humour_value) +} + +func init() { proto.RegisterFile("proto3.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 473 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x90, 0x5f, 0x8b, 0xd3, 0x40, + 0x14, 0xc5, 0x9d, 0xa6, 0xdb, 0x3f, 0x37, 0xe9, 0x1a, 0x86, 0x0a, 0x43, 0x11, 0x19, 0xeb, 0xcb, + 0x20, 0xda, 0x87, 0xea, 0xc3, 0x22, 0xa2, 0x6c, 0x4b, 0xc1, 0xb2, 0x6d, 0x2d, 0xd3, 0x5d, 0x16, + 0x9f, 0xc2, 0x34, 0x3b, 0xb4, 0xc1, 0x66, 0x52, 0x26, 0x93, 0x85, 0x7c, 0x1d, 0x3f, 0xa7, 0x0f, + 0x92, 0x4c, 0xaa, 0x51, 0xea, 0xd3, 0xdc, 0x7b, 0xe6, 0xdc, 0x99, 0x73, 0x7f, 0xe0, 0x1d, 0x75, + 0x62, 0x92, 0x77, 0xa3, 0xf2, 0xc0, 0x55, 0x17, 0x94, 0xc7, 0xf0, 0xa7, 0x03, 0xed, 0xa5, 0x4c, + 0x53, 0xb1, 0x93, 0x18, 0x43, 0x53, 0x89, 0x58, 0x12, 0x44, 0x11, 0xeb, 0xf2, 0xb2, 0xc6, 0x57, + 0xd0, 0xd9, 0x47, 0x07, 0xa1, 0x23, 0x93, 0x93, 0x06, 0x45, 0xec, 0x72, 0xfc, 0x7c, 0x54, 0x7f, + 0x60, 0x54, 0x0d, 0x8f, 0xbe, 0x64, 0x71, 0x92, 0x69, 0xfe, 0xdb, 0x8d, 0x29, 0x78, 0x7b, 0x19, + 0xed, 0xf6, 0x26, 0x88, 0x54, 0x10, 0xc6, 0xc4, 0xa1, 0x88, 0xf5, 0x38, 0x58, 0x6d, 0xae, 0xa6, + 0x71, 0xf1, 0xdf, 0x83, 0x30, 0x82, 0x34, 0x29, 0x62, 0x1e, 0x2f, 0x6b, 0xfc, 0x12, 0x3c, 0x2d, + 0xd3, 0xec, 0x60, 0x82, 0x30, 0xc9, 0x94, 0x21, 0x6d, 0x8a, 0x98, 0xc3, 0x5d, 0xab, 0x4d, 0x0b, + 0x09, 0xbf, 0x82, 0x9e, 0xd1, 0x99, 0x0c, 0xd2, 0x30, 0x31, 0x69, 0x2c, 0x14, 0xe9, 0x50, 0xc4, + 0x3a, 0xdc, 0x2b, 0xc4, 0x4d, 0xa5, 0xe1, 0x3e, 0x5c, 0xa4, 0x61, 0xa2, 0x25, 0xe9, 0x52, 0xc4, + 0x1a, 0xdc, 0x36, 0xd8, 0x07, 0xe7, 0xbb, 0xcc, 0xc9, 0x05, 0x75, 0x58, 0x93, 0x17, 0x25, 0x7e, + 0x03, 0x2d, 0x25, 0x53, 0x23, 0x1f, 0x48, 0x8b, 0x22, 0xe6, 0x8e, 0xfb, 0x7f, 0x6f, 0xb7, 0x2a, + 0xef, 0x78, 0xe5, 0xc1, 0x1f, 0xa1, 0x6d, 0xa4, 0xd6, 0x22, 0x52, 0x04, 0xa8, 0xc3, 0xdc, 0xf1, + 0xf0, 0x3c, 0x8c, 0x5b, 0x6b, 0x9a, 0x29, 0xa3, 0x73, 0x7e, 0x1a, 0x19, 0xac, 0xc1, 0xab, 0x5f, + 0x9c, 0xd2, 0x58, 0xdc, 0x65, 0x9a, 0xd7, 0x70, 0xf1, 0x28, 0x0e, 0x99, 0x2c, 0x51, 0xff, 0x2f, + 0x8c, 0xb5, 0x7c, 0x68, 0x5c, 0xa1, 0xe1, 0x67, 0x68, 0x59, 0xee, 0xd8, 0x85, 0xf6, 0xdd, 0xea, + 0x66, 0xf5, 0xf5, 0x7e, 0xe5, 0x3f, 0xc1, 0x1d, 0x68, 0xae, 0xef, 0x56, 0x1b, 0x1f, 0xe1, 0x1e, + 0x74, 0x37, 0x8b, 0xeb, 0xf5, 0xe6, 0x76, 0x3e, 0xbd, 0xf1, 0x1b, 0xf8, 0x29, 0xb8, 0x93, 0xf9, + 0x62, 0x11, 0x4c, 0xae, 0xe7, 0x8b, 0xd9, 0x37, 0xdf, 0x19, 0xbe, 0x80, 0x96, 0x7d, 0xb5, 0x00, + 0xb6, 0xcd, 0x94, 0x3a, 0xc5, 0xb1, 0xcd, 0xf0, 0x07, 0x82, 0xcb, 0x6a, 0xa9, 0xfb, 0xc8, 0xec, + 0x97, 0xe2, 0x88, 0xd7, 0xe0, 0x6d, 0x73, 0x23, 0x83, 0x58, 0x1c, 0x8f, 0x91, 0xda, 0x11, 0x54, + 0x82, 0x78, 0x7b, 0x16, 0x44, 0x35, 0x33, 0x9a, 0xe4, 0x46, 0x2e, 0xad, 0xdf, 0x32, 0x71, 0xb7, + 0x7f, 0x94, 0xc1, 0x27, 0xf0, 0xff, 0x35, 0xd4, 0xd9, 0x74, 0x2c, 0x9b, 0x7e, 0x9d, 0x8d, 0x57, + 0xa3, 0x30, 0x9e, 0x82, 0x3b, 0x0b, 0xf7, 0xc9, 0x46, 0xea, 0xc7, 0x28, 0x94, 0xf8, 0x3d, 0x34, + 0x8b, 0x16, 0x3f, 0x3b, 0x1b, 0x69, 0x70, 0x5e, 0xde, 0xb6, 0xac, 0xfa, 0x2b, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xc1, 0x87, 0xd6, 0x2d, 0x03, 0x00, 0x00, +} diff --git a/core/protorpc/examples/proto3.pb/proto3.pb.protorpc.go b/core/protorpc/examples/proto3.pb/proto3.pb.protorpc.go new file mode 100644 index 0000000..16f2e3d --- /dev/null +++ b/core/protorpc/examples/proto3.pb/proto3.pb.protorpc.go @@ -0,0 +1,171 @@ +// Code generated by protoc-gen-protorpc. DO NOT EDIT. +// +// plugin: https://github.com/chai2010/protorpc/tree/master/protoc-gen-protorpc +// plugin: https://github.com/chai2010/protorpc/tree/master/protoc-plugin-common +// +// source: proto3.proto + +package proto3_proto + +import ( + "fmt" + "io" + "log" + "net" + "net/rpc" + "time" + + "github.com/chai2010/protorpc" + "github.com/golang/protobuf/proto" +) + +var ( + _ = fmt.Sprint + _ = io.Reader(nil) + _ = log.Print + _ = net.Addr(nil) + _ = rpc.Call{} + _ = time.Second + + _ = proto.String + _ = protorpc.Dial +) + +type EchoService interface { + Echo(in *Message, out *Message) error +} + +// AcceptEchoServiceClient accepts connections on the listener and serves requests +// for each incoming connection. Accept blocks; the caller typically +// invokes it in a go statement. +func AcceptEchoServiceClient(lis net.Listener, x EchoService) { + srv := rpc.NewServer() + if err := srv.RegisterName("EchoService", x); err != nil { + log.Fatal(err) + } + + for { + conn, err := lis.Accept() + if err != nil { + log.Fatalf("lis.Accept(): %v\n", err) + } + go srv.ServeCodec(protorpc.NewServerCodec(conn)) + } +} + +// RegisterEchoService publish the given EchoService implementation on the server. +func RegisterEchoService(srv *rpc.Server, x EchoService) error { + if err := srv.RegisterName("EchoService", x); err != nil { + return err + } + return nil +} + +// NewEchoServiceServer returns a new EchoService Server. +func NewEchoServiceServer(x EchoService) *rpc.Server { + srv := rpc.NewServer() + if err := srv.RegisterName("EchoService", x); err != nil { + log.Fatal(err) + } + return srv +} + +// ListenAndServeEchoService listen announces on the local network address laddr +// and serves the given EchoService implementation. +func ListenAndServeEchoService(network, addr string, x EchoService) error { + lis, err := net.Listen(network, addr) + if err != nil { + return err + } + defer lis.Close() + + srv := rpc.NewServer() + if err := srv.RegisterName("EchoService", x); err != nil { + return err + } + + for { + conn, err := lis.Accept() + if err != nil { + log.Fatalf("lis.Accept(): %v\n", err) + } + go srv.ServeCodec(protorpc.NewServerCodec(conn)) + } +} + +// ServeEchoService serves the given EchoService implementation. +func ServeEchoService(conn io.ReadWriteCloser, x EchoService) { + srv := rpc.NewServer() + if err := srv.RegisterName("EchoService", x); err != nil { + log.Fatal(err) + } + srv.ServeCodec(protorpc.NewServerCodec(conn)) +} + +type EchoServiceClient struct { + *rpc.Client +} + +// NewEchoServiceClient returns a EchoService stub to handle +// requests to the set of EchoService at the other end of the connection. +func NewEchoServiceClient(conn io.ReadWriteCloser) *EchoServiceClient { + c := rpc.NewClientWithCodec(protorpc.NewClientCodec(conn)) + return &EchoServiceClient{c} +} + +func (c *EchoServiceClient) Echo(in *Message) (out *Message, err error) { + if in == nil { + in = new(Message) + } + + type Validator interface { + Validate() error + } + if x, ok := proto.Message(in).(Validator); ok { + if err := x.Validate(); err != nil { + return nil, err + } + } + + out = new(Message) + if err = c.Call("EchoService.Echo", in, out); err != nil { + return nil, err + } + + if x, ok := proto.Message(out).(Validator); ok { + if err := x.Validate(); err != nil { + return out, err + } + } + + return out, nil +} + +func (c *EchoServiceClient) AsyncEcho(in *Message, out *Message, done chan *rpc.Call) *rpc.Call { + if in == nil { + in = new(Message) + } + return c.Go( + "EchoService.Echo", + in, out, + done, + ) +} + +// DialEchoService connects to an EchoService at the specified network address. +func DialEchoService(network, addr string) (*EchoServiceClient, error) { + c, err := protorpc.Dial(network, addr) + if err != nil { + return nil, err + } + return &EchoServiceClient{c}, nil +} + +// DialEchoServiceTimeout connects to an EchoService at the specified network address. +func DialEchoServiceTimeout(network, addr string, timeout time.Duration) (*EchoServiceClient, error) { + c, err := protorpc.DialTimeout(network, addr, timeout) + if err != nil { + return nil, err + } + return &EchoServiceClient{c}, nil +} diff --git a/core/protorpc/examples/proto3.pb/proto3.proto b/core/protorpc/examples/proto3.pb/proto3.proto new file mode 100644 index 0000000..efd3dae --- /dev/null +++ b/core/protorpc/examples/proto3.pb/proto3.proto @@ -0,0 +1,41 @@ +// Copyright 2015 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +syntax = "proto3"; + +package proto3_proto; + +message Message { + enum Humour { + UNKNOWN = 0; + PUNS = 1; + SLAPSTICK = 2; + BILL_BAILEY = 3; + } + + string name = 1; + Humour hilarity = 2; + uint32 height_in_cm = 3; + bytes data = 4; + int64 result_count = 7; + bool true_scotsman = 8; + float score = 9; + + repeated uint64 key = 5; + Nested nested = 6; + + map terrain = 10; +} + +message Nested { + string bunny = 1; +} + +message MessageWithMap { + map byte_mapping = 1; +} + +service EchoService { + rpc Echo(Message) returns (Message); +} diff --git a/core/protorpc/examples/proto3.pb/proto3_proto_test.go b/core/protorpc/examples/proto3.pb/proto3_proto_test.go new file mode 100644 index 0000000..e3b3979 --- /dev/null +++ b/core/protorpc/examples/proto3.pb/proto3_proto_test.go @@ -0,0 +1,72 @@ +// Copyright 2015 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto3_proto + +import ( + "bytes" + "encoding/gob" + "log" + "os" + "reflect" + "testing" + "time" +) + +type tEchoService struct { + private int +} + +func (p *tEchoService) Echo(in *Message, out *Message) error { + var buf bytes.Buffer + if err := gob.NewEncoder(&buf).Encode(in); err != nil { + return err + } + if err := gob.NewDecoder(bytes.NewBuffer(buf.Bytes())).Decode(out); err != nil { + return err + } + return nil +} + +func TestMain(m *testing.M) { + go func() { + if err := ListenAndServeEchoService("tcp", "127.0.0.1:3000", new(tEchoService)); err != nil { + log.Fatal(err) + } + }() + time.Sleep(time.Second * 3) // wait for start the server + os.Exit(m.Run()) +} + +func TestEchoService(t *testing.T) { + c, err := DialEchoService("tcp", "127.0.0.1:3000") + if err != nil { + t.Fatal(err) + } + defer c.Close() + + in := Message{ + Name: "github.com/chai2010/protorpc", + Hilarity: Message_PUNS, + HeightInCm: 13, + Data: []byte("bin data"), + ResultCount: 2<<35 + 1, + TrueScotsman: true, + Score: 3.14, + Key: []uint64{1, 1001}, + Nested: &Nested{Bunny: "{{Bunny}}"}, + Terrain: map[string]*Nested{ + "A": &Nested{Bunny: "{{A}}"}, + "B": &Nested{Bunny: "{{B}}"}, + }, + } + + out, err := c.Echo(&in) + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(&in, out) { + t.Fatalf("not euqal, got = %v\n", &out) + } +} diff --git a/core/protorpc/examples/service.pb/Makefile b/core/protorpc/examples/service.pb/Makefile new file mode 100644 index 0000000..c3efd49 --- /dev/null +++ b/core/protorpc/examples/service.pb/Makefile @@ -0,0 +1,14 @@ +# Copyright 2013 . All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +PROTO_FILES=$(sort $(wildcard ./*.proto)) + +default: $(PROTO_FILES) Makefile + go install github.com/golang/protobuf/protoc-gen-go + go install github.com/chai2010/protorpc/protoc-gen-protorpc + protoc --go_out=. ${PROTO_FILES} + ENV_PROTOC_GEN_PROTORPC_FLAG_PREFIX= protoc --protorpc_out=. ${PROTO_FILES} + go test + +clean: diff --git a/core/protorpc/examples/service.pb/all_test.go b/core/protorpc/examples/service.pb/all_test.go new file mode 100644 index 0000000..102360b --- /dev/null +++ b/core/protorpc/examples/service.pb/all_test.go @@ -0,0 +1,193 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package service + +import ( + "log" + "net" + "net/rpc" + "testing" + + "github.com/chai2010/protorpc" +) + +func init() { + err := listenAndServeArithAndEchoService("tcp", "127.0.0.1:1984") + if err != nil { + log.Fatalf("listenAndServeArithAndEchoService: %v", err) + } +} + +func TestAll(t *testing.T) { + conn, err := net.Dial("tcp", "127.0.0.1:1984") + if err != nil { + t.Fatalf(`net.Dial("tcp", "127.0.0.1:1984"): %v`, err) + } + client := rpc.NewClientWithCodec(protorpc.NewClientCodec(conn)) + defer client.Close() + + testArithClient(t, client) + testEchoClient(t, client) + + arithStub := &ArithServiceClient{client} + echoStub := &EchoServiceClient{client} + + testArithStub(t, arithStub) + testEchoStub(t, echoStub) +} + +func listenAndServeArithAndEchoService(network, addr string) error { + clients, err := net.Listen(network, addr) + if err != nil { + return err + } + srv := rpc.NewServer() + if err := RegisterArithService(srv, new(Arith)); err != nil { + return err + } + if err := RegisterEchoService(srv, new(Echo)); err != nil { + return err + } + go func() { + for { + conn, err := clients.Accept() + if err != nil { + log.Printf("clients.Accept(): %v\n", err) + continue + } + go srv.ServeCodec(protorpc.NewServerCodec(conn)) + } + }() + return nil +} + +func testArithClient(t *testing.T, client *rpc.Client) { + var args ArithRequest + var reply ArithResponse + var err error + + // Add + args.A = 1 + args.B = 2 + if err = client.Call("ArithService.Add", &args, &reply); err != nil { + t.Fatalf(`arith.Add: %v`, err) + } + if reply.C != 3 { + t.Fatalf(`arith.Add: expected = %d, got = %d`, 3, reply.C) + } + + // Mul + args.A = 2 + args.B = 3 + if err = client.Call("ArithService.Mul", &args, &reply); err != nil { + t.Fatalf(`arith.Mul: %v`, err) + } + if reply.C != 6 { + t.Fatalf(`arith.Mul: expected = %d, got = %d`, 6, reply.C) + } + + // Div + args.A = 13 + args.B = 5 + if err = client.Call("ArithService.Div", &args, &reply); err != nil { + t.Fatalf(`arith.Div: %v`, err) + } + if reply.C != 2 { + t.Fatalf(`arith.Div: expected = %d, got = %d`, 2, reply.C) + } + + // Div zero + args.A = 1 + args.B = 0 + if err = client.Call("ArithService.Div", &args, &reply); err.Error() != "divide by zero" { + t.Fatalf(`arith.Div: expected = "%s", got = "%s"`, "divide by zero", err.Error()) + } + + // Error + args.A = 1 + args.B = 2 + if err = client.Call("ArithService.Error", &args, &reply); err.Error() != "ArithError" { + t.Fatalf(`arith.Error: expected = "%s", got = "%s"`, "ArithError", err.Error()) + } +} + +func testEchoClient(t *testing.T, client *rpc.Client) { + var args EchoRequest + var reply EchoResponse + var err error + + // EchoService.Echo + args.Msg = "Hello, Protobuf-RPC" + if err = client.Call("EchoService.Echo", &args, &reply); err != nil { + t.Fatalf(`echo.Echo: %v`, err) + } + if reply.Msg != args.Msg { + t.Fatalf(`echo.Echo: expected = "%s", got = "%s"`, args.Msg, reply.Msg) + } +} + +func testArithStub(t *testing.T, stub *ArithServiceClient) { + var args ArithRequest + var reply *ArithResponse + var err error + + // Add + args.A = 1 + args.B = 2 + if reply, err = stub.Add(&args); err != nil { + t.Fatalf(`stub.Add: %v`, err) + } + if reply.C != 3 { + t.Fatalf(`stub.Add: expected = %d, got = %d`, 3, reply.C) + } + + // Mul + args.A = 2 + args.B = 3 + if reply, err = stub.Mul(&args); err != nil { + t.Fatalf(`stub.Mul: %v`, err) + } + if reply.C != 6 { + t.Fatalf(`stub.Mul: expected = %d, got = %d`, 6, reply.C) + } + + // Div + args.A = 13 + args.B = 5 + if reply, err = stub.Div(&args); err != nil { + t.Fatalf(`stub.Div: %v`, err) + } + if reply.C != 2 { + t.Fatalf(`stub.Div: expected = %d, got = %d`, 2, reply.C) + } + + // Div zero + args.A = 1 + args.B = 0 + if reply, err = stub.Div(&args); err.Error() != "divide by zero" { + t.Fatalf(`stub.Div: expected = "%s", got = "%s"`, "divide by zero", err.Error()) + } + + // Error + args.A = 1 + args.B = 2 + if reply, err = stub.Error(&args); err.Error() != "ArithError" { + t.Fatalf(`stub.Error: expected = "%s", got = "%s"`, "ArithError", err.Error()) + } +} +func testEchoStub(t *testing.T, stub *EchoServiceClient) { + var args EchoRequest + var reply *EchoResponse + var err error + + // EchoService.Echo + args.Msg = "Hello, Protobuf-RPC" + if reply, err = stub.Echo(&args); err != nil { + t.Fatalf(`stub.Echo: %v`, err) + } + if reply.Msg != args.Msg { + t.Fatalf(`stub.Echo: expected = "%s", got = "%s"`, args.Msg, reply.Msg) + } +} diff --git a/core/protorpc/examples/service.pb/arith.go b/core/protorpc/examples/service.pb/arith.go new file mode 100644 index 0000000..adce625 --- /dev/null +++ b/core/protorpc/examples/service.pb/arith.go @@ -0,0 +1,33 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package service + +import ( + "errors" +) + +type Arith int + +func (t *Arith) Add(args *ArithRequest, reply *ArithResponse) error { + reply.C = args.A + args.B + return nil +} + +func (t *Arith) Mul(args *ArithRequest, reply *ArithResponse) error { + reply.C = args.A * args.B + return nil +} + +func (t *Arith) Div(args *ArithRequest, reply *ArithResponse) error { + if args.B == 0 { + return errors.New("divide by zero") + } + reply.C = args.A / args.B + return nil +} + +func (t *Arith) Error(args *ArithRequest, reply *ArithResponse) error { + return errors.New("ArithError") +} diff --git a/core/protorpc/examples/service.pb/arith.pb.go b/core/protorpc/examples/service.pb/arith.pb.go new file mode 100644 index 0000000..63a1da3 --- /dev/null +++ b/core/protorpc/examples/service.pb/arith.pb.go @@ -0,0 +1,93 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: arith.proto + +/* +Package service is a generated protocol buffer package. + +It is generated from these files: + arith.proto + echo.proto + +It has these top-level messages: + ArithRequest + ArithResponse + EchoRequest + EchoResponse +*/ +package service + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +type ArithRequest struct { + A int32 `protobuf:"varint,1,opt,name=a" json:"a,omitempty"` + B int32 `protobuf:"varint,2,opt,name=b" json:"b,omitempty"` +} + +func (m *ArithRequest) Reset() { *m = ArithRequest{} } +func (m *ArithRequest) String() string { return proto.CompactTextString(m) } +func (*ArithRequest) ProtoMessage() {} +func (*ArithRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +func (m *ArithRequest) GetA() int32 { + if m != nil { + return m.A + } + return 0 +} + +func (m *ArithRequest) GetB() int32 { + if m != nil { + return m.B + } + return 0 +} + +type ArithResponse struct { + C int32 `protobuf:"varint,1,opt,name=c" json:"c,omitempty"` +} + +func (m *ArithResponse) Reset() { *m = ArithResponse{} } +func (m *ArithResponse) String() string { return proto.CompactTextString(m) } +func (*ArithResponse) ProtoMessage() {} +func (*ArithResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +func (m *ArithResponse) GetC() int32 { + if m != nil { + return m.C + } + return 0 +} + +func init() { + proto.RegisterType((*ArithRequest)(nil), "service.ArithRequest") + proto.RegisterType((*ArithResponse)(nil), "service.ArithResponse") +} + +func init() { proto.RegisterFile("arith.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 159 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4e, 0x2c, 0xca, 0x2c, + 0xc9, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x2f, 0x4e, 0x2d, 0x2a, 0xcb, 0x4c, 0x4e, + 0x55, 0xd2, 0xe2, 0xe2, 0x71, 0x04, 0x89, 0x07, 0xa5, 0x16, 0x96, 0xa6, 0x16, 0x97, 0x08, 0xf1, + 0x70, 0x31, 0x26, 0x4a, 0x30, 0x2a, 0x30, 0x6a, 0xb0, 0x06, 0x31, 0x26, 0x82, 0x78, 0x49, 0x12, + 0x4c, 0x10, 0x5e, 0x92, 0x92, 0x2c, 0x17, 0x2f, 0x54, 0x6d, 0x71, 0x41, 0x7e, 0x5e, 0x71, 0x2a, + 0x48, 0x3a, 0x19, 0xa6, 0x38, 0xd9, 0xe8, 0x05, 0x23, 0xd4, 0xac, 0x60, 0x88, 0xd9, 0x42, 0x26, + 0x5c, 0xcc, 0x89, 0x29, 0x29, 0x42, 0xa2, 0x7a, 0x50, 0xcb, 0xf4, 0x90, 0x6d, 0x92, 0x12, 0x43, + 0x17, 0x86, 0x1a, 0x6a, 0xc2, 0xc5, 0x9c, 0x5b, 0x9a, 0x43, 0x86, 0xae, 0x94, 0xcc, 0x32, 0x52, + 0x75, 0x99, 0x71, 0xb1, 0xa6, 0x16, 0x15, 0xe5, 0x17, 0x91, 0xa8, 0x2f, 0x89, 0x0d, 0x1c, 0x8a, + 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa2, 0x62, 0xfd, 0xbd, 0x54, 0x01, 0x00, 0x00, +} diff --git a/core/protorpc/examples/service.pb/arith.pb.protorpc.go b/core/protorpc/examples/service.pb/arith.pb.protorpc.go new file mode 100644 index 0000000..ce506b1 --- /dev/null +++ b/core/protorpc/examples/service.pb/arith.pb.protorpc.go @@ -0,0 +1,291 @@ +// Code generated by protoc-gen-protorpc. DO NOT EDIT. +// +// plugin: https://github.com/chai2010/protorpc/tree/master/protoc-gen-plugin +// plugin: https://github.com/chai2010/protorpc/tree/master/protoc-gen-protorpc +// +// source: arith.proto + +package service + +import ( + "fmt" + "io" + "log" + "net" + "net/rpc" + "time" + + "github.com/chai2010/protorpc" + "github.com/golang/protobuf/proto" +) + +var ( + _ = fmt.Sprint + _ = io.Reader(nil) + _ = log.Print + _ = net.Addr(nil) + _ = rpc.Call{} + _ = time.Second + + _ = proto.String + _ = protorpc.Dial +) + +type ArithService interface { + Add(in *ArithRequest, out *ArithResponse) error + Mul(in *ArithRequest, out *ArithResponse) error + Div(in *ArithRequest, out *ArithResponse) error + Error(in *ArithRequest, out *ArithResponse) error +} + +// AcceptArithServiceClient accepts connections on the listener and serves requests +// for each incoming connection. Accept blocks; the caller typically +// invokes it in a go statement. +func AcceptArithServiceClient(lis net.Listener, x ArithService) { + srv := rpc.NewServer() + if err := srv.RegisterName("ArithService", x); err != nil { + log.Fatal(err) + } + + for { + conn, err := lis.Accept() + if err != nil { + log.Fatalf("lis.Accept(): %v\n", err) + } + go srv.ServeCodec(protorpc.NewServerCodec(conn)) + } +} + +// RegisterArithService publish the given ArithService implementation on the server. +func RegisterArithService(srv *rpc.Server, x ArithService) error { + if err := srv.RegisterName("ArithService", x); err != nil { + return err + } + return nil +} + +// NewArithServiceServer returns a new ArithService Server. +func NewArithServiceServer(x ArithService) *rpc.Server { + srv := rpc.NewServer() + if err := srv.RegisterName("ArithService", x); err != nil { + log.Fatal(err) + } + return srv +} + +// ListenAndServeArithService listen announces on the local network address laddr +// and serves the given ArithService implementation. +func ListenAndServeArithService(network, addr string, x ArithService) error { + lis, err := net.Listen(network, addr) + if err != nil { + return err + } + defer lis.Close() + + srv := rpc.NewServer() + if err := srv.RegisterName("ArithService", x); err != nil { + return err + } + + for { + conn, err := lis.Accept() + if err != nil { + log.Fatalf("lis.Accept(): %v\n", err) + } + go srv.ServeCodec(protorpc.NewServerCodec(conn)) + } +} + +// ServeArithService serves the given ArithService implementation. +func ServeArithService(conn io.ReadWriteCloser, x ArithService) { + srv := rpc.NewServer() + if err := srv.RegisterName("ArithService", x); err != nil { + log.Fatal(err) + } + srv.ServeCodec(protorpc.NewServerCodec(conn)) +} + +type ArithServiceClient struct { + *rpc.Client +} + +// NewArithServiceClient returns a ArithService stub to handle +// requests to the set of ArithService at the other end of the connection. +func NewArithServiceClient(conn io.ReadWriteCloser) *ArithServiceClient { + c := rpc.NewClientWithCodec(protorpc.NewClientCodec(conn)) + return &ArithServiceClient{c} +} + +func (c *ArithServiceClient) Add(in *ArithRequest) (out *ArithResponse, err error) { + if in == nil { + in = new(ArithRequest) + } + + type Validator interface { + Validate() error + } + if x, ok := proto.Message(in).(Validator); ok { + if err := x.Validate(); err != nil { + return nil, err + } + } + + out = new(ArithResponse) + if err = c.Call("ArithService.Add", in, out); err != nil { + return nil, err + } + + if x, ok := proto.Message(out).(Validator); ok { + if err := x.Validate(); err != nil { + return out, err + } + } + + return out, nil +} + +func (c *ArithServiceClient) AsyncAdd(in *ArithRequest, out *ArithResponse, done chan *rpc.Call) *rpc.Call { + if in == nil { + in = new(ArithRequest) + } + return c.Go( + "ArithService.Add", + in, out, + done, + ) +} + +func (c *ArithServiceClient) Mul(in *ArithRequest) (out *ArithResponse, err error) { + if in == nil { + in = new(ArithRequest) + } + + type Validator interface { + Validate() error + } + if x, ok := proto.Message(in).(Validator); ok { + if err := x.Validate(); err != nil { + return nil, err + } + } + + out = new(ArithResponse) + if err = c.Call("ArithService.Mul", in, out); err != nil { + return nil, err + } + + if x, ok := proto.Message(out).(Validator); ok { + if err := x.Validate(); err != nil { + return out, err + } + } + + return out, nil +} + +func (c *ArithServiceClient) AsyncMul(in *ArithRequest, out *ArithResponse, done chan *rpc.Call) *rpc.Call { + if in == nil { + in = new(ArithRequest) + } + return c.Go( + "ArithService.Mul", + in, out, + done, + ) +} + +func (c *ArithServiceClient) Div(in *ArithRequest) (out *ArithResponse, err error) { + if in == nil { + in = new(ArithRequest) + } + + type Validator interface { + Validate() error + } + if x, ok := proto.Message(in).(Validator); ok { + if err := x.Validate(); err != nil { + return nil, err + } + } + + out = new(ArithResponse) + if err = c.Call("ArithService.Div", in, out); err != nil { + return nil, err + } + + if x, ok := proto.Message(out).(Validator); ok { + if err := x.Validate(); err != nil { + return out, err + } + } + + return out, nil +} + +func (c *ArithServiceClient) AsyncDiv(in *ArithRequest, out *ArithResponse, done chan *rpc.Call) *rpc.Call { + if in == nil { + in = new(ArithRequest) + } + return c.Go( + "ArithService.Div", + in, out, + done, + ) +} + +func (c *ArithServiceClient) Error(in *ArithRequest) (out *ArithResponse, err error) { + if in == nil { + in = new(ArithRequest) + } + + type Validator interface { + Validate() error + } + if x, ok := proto.Message(in).(Validator); ok { + if err := x.Validate(); err != nil { + return nil, err + } + } + + out = new(ArithResponse) + if err = c.Call("ArithService.Error", in, out); err != nil { + return nil, err + } + + if x, ok := proto.Message(out).(Validator); ok { + if err := x.Validate(); err != nil { + return out, err + } + } + + return out, nil +} + +func (c *ArithServiceClient) AsyncError(in *ArithRequest, out *ArithResponse, done chan *rpc.Call) *rpc.Call { + if in == nil { + in = new(ArithRequest) + } + return c.Go( + "ArithService.Error", + in, out, + done, + ) +} + +// DialArithService connects to an ArithService at the specified network address. +func DialArithService(network, addr string) (*ArithServiceClient, error) { + c, err := protorpc.Dial(network, addr) + if err != nil { + return nil, err + } + return &ArithServiceClient{c}, nil +} + +// DialArithServiceTimeout connects to an ArithService at the specified network address. +func DialArithServiceTimeout(network, addr string, timeout time.Duration) (*ArithServiceClient, error) { + c, err := protorpc.DialTimeout(network, addr, timeout) + if err != nil { + return nil, err + } + return &ArithServiceClient{c}, nil +} diff --git a/core/protorpc/examples/service.pb/arith.proto b/core/protorpc/examples/service.pb/arith.proto new file mode 100644 index 0000000..7c92e4f --- /dev/null +++ b/core/protorpc/examples/service.pb/arith.proto @@ -0,0 +1,23 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +syntax = "proto3"; + +package service; + +message ArithRequest { + int32 a = 1; + int32 b = 2; +} + +message ArithResponse { + int32 c = 1; +} + +service ArithService { + rpc add (ArithRequest) returns (ArithResponse); + rpc mul (ArithRequest) returns (ArithResponse); + rpc div (ArithRequest) returns (ArithResponse); + rpc error (ArithRequest) returns (ArithResponse); +} diff --git a/core/protorpc/examples/service.pb/arith_test.go b/core/protorpc/examples/service.pb/arith_test.go new file mode 100644 index 0000000..ab55977 --- /dev/null +++ b/core/protorpc/examples/service.pb/arith_test.go @@ -0,0 +1,34 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package service + +import ( + "fmt" + "log" + "sync" +) + +var ( + arithHost = "127.0.0.1" + arithPort = 2010 + + onceArith sync.Once +) + +func setupArithServer() { + var wg sync.WaitGroup + wg.Add(1) + defer wg.Wait() + + go func() { + wg.Done() + + addr := fmt.Sprintf("127.0.0.1:%d", arithPort) + err := ListenAndServeArithService("tcp", addr, new(Arith)) + if err != nil { + log.Fatalf("ListenAndServeArithService: %v", err) + } + }() +} diff --git a/core/protorpc/examples/service.pb/echo.go b/core/protorpc/examples/service.pb/echo.go new file mode 100644 index 0000000..fcdad39 --- /dev/null +++ b/core/protorpc/examples/service.pb/echo.go @@ -0,0 +1,17 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package service + +type Echo int + +func (t *Echo) Echo(args *EchoRequest, reply *EchoResponse) error { + reply.Msg = args.Msg + return nil +} + +func (t *Echo) EchoTwice(args *EchoRequest, reply *EchoResponse) error { + reply.Msg = args.Msg + args.Msg + return nil +} diff --git a/core/protorpc/examples/service.pb/echo.pb.go b/core/protorpc/examples/service.pb/echo.pb.go new file mode 100644 index 0000000..8dbffc0 --- /dev/null +++ b/core/protorpc/examples/service.pb/echo.pb.go @@ -0,0 +1,65 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: echo.proto + +package service + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +type EchoRequest struct { + Msg string `protobuf:"bytes,1,opt,name=msg" json:"msg,omitempty"` +} + +func (m *EchoRequest) Reset() { *m = EchoRequest{} } +func (m *EchoRequest) String() string { return proto.CompactTextString(m) } +func (*EchoRequest) ProtoMessage() {} +func (*EchoRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} } + +func (m *EchoRequest) GetMsg() string { + if m != nil { + return m.Msg + } + return "" +} + +type EchoResponse struct { + Msg string `protobuf:"bytes,1,opt,name=msg" json:"msg,omitempty"` +} + +func (m *EchoResponse) Reset() { *m = EchoResponse{} } +func (m *EchoResponse) String() string { return proto.CompactTextString(m) } +func (*EchoResponse) ProtoMessage() {} +func (*EchoResponse) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{1} } + +func (m *EchoResponse) GetMsg() string { + if m != nil { + return m.Msg + } + return "" +} + +func init() { + proto.RegisterType((*EchoRequest)(nil), "service.EchoRequest") + proto.RegisterType((*EchoResponse)(nil), "service.EchoResponse") +} + +func init() { proto.RegisterFile("echo.proto", fileDescriptor1) } + +var fileDescriptor1 = []byte{ + // 134 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4a, 0x4d, 0xce, 0xc8, + 0xd7, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x2f, 0x4e, 0x2d, 0x2a, 0xcb, 0x4c, 0x4e, 0x55, + 0x92, 0xe7, 0xe2, 0x76, 0x4d, 0xce, 0xc8, 0x0f, 0x4a, 0x2d, 0x2c, 0x4d, 0x2d, 0x2e, 0x11, 0x12, + 0xe0, 0x62, 0xce, 0x2d, 0x4e, 0x97, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x02, 0x31, 0x95, 0x14, + 0xb8, 0x78, 0x20, 0x0a, 0x8a, 0x0b, 0xf2, 0xf3, 0x8a, 0x53, 0x31, 0x55, 0x18, 0xd5, 0x40, 0x8c, + 0x08, 0x86, 0x98, 0x28, 0x64, 0xcc, 0xc5, 0x02, 0xe2, 0x0a, 0x89, 0xe8, 0x41, 0xed, 0xd0, 0x43, + 0xb2, 0x40, 0x4a, 0x14, 0x4d, 0x14, 0x6a, 0xaa, 0x05, 0x17, 0x27, 0x88, 0x1f, 0x52, 0x0e, 0x32, + 0x81, 0x14, 0x9d, 0x49, 0x6c, 0x60, 0x0f, 0x19, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc1, + 0xd4, 0xbd, 0xde, 0x00, 0x00, 0x00, +} diff --git a/core/protorpc/examples/service.pb/echo.pb.protorpc.go b/core/protorpc/examples/service.pb/echo.pb.protorpc.go new file mode 100644 index 0000000..289d61b --- /dev/null +++ b/core/protorpc/examples/service.pb/echo.pb.protorpc.go @@ -0,0 +1,211 @@ +// Code generated by protoc-gen-protorpc. DO NOT EDIT. +// +// plugin: https://github.com/chai2010/protorpc/tree/master/protoc-gen-plugin +// plugin: https://github.com/chai2010/protorpc/tree/master/protoc-gen-protorpc +// +// source: echo.proto + +package service + +import ( + "fmt" + "io" + "log" + "net" + "net/rpc" + "time" + + "github.com/chai2010/protorpc" + "github.com/golang/protobuf/proto" +) + +var ( + _ = fmt.Sprint + _ = io.Reader(nil) + _ = log.Print + _ = net.Addr(nil) + _ = rpc.Call{} + _ = time.Second + + _ = proto.String + _ = protorpc.Dial +) + +type EchoService interface { + Echo(in *EchoRequest, out *EchoResponse) error + EchoTwice(in *EchoRequest, out *EchoResponse) error +} + +// AcceptEchoServiceClient accepts connections on the listener and serves requests +// for each incoming connection. Accept blocks; the caller typically +// invokes it in a go statement. +func AcceptEchoServiceClient(lis net.Listener, x EchoService) { + srv := rpc.NewServer() + if err := srv.RegisterName("EchoService", x); err != nil { + log.Fatal(err) + } + + for { + conn, err := lis.Accept() + if err != nil { + log.Fatalf("lis.Accept(): %v\n", err) + } + go srv.ServeCodec(protorpc.NewServerCodec(conn)) + } +} + +// RegisterEchoService publish the given EchoService implementation on the server. +func RegisterEchoService(srv *rpc.Server, x EchoService) error { + if err := srv.RegisterName("EchoService", x); err != nil { + return err + } + return nil +} + +// NewEchoServiceServer returns a new EchoService Server. +func NewEchoServiceServer(x EchoService) *rpc.Server { + srv := rpc.NewServer() + if err := srv.RegisterName("EchoService", x); err != nil { + log.Fatal(err) + } + return srv +} + +// ListenAndServeEchoService listen announces on the local network address laddr +// and serves the given EchoService implementation. +func ListenAndServeEchoService(network, addr string, x EchoService) error { + lis, err := net.Listen(network, addr) + if err != nil { + return err + } + defer lis.Close() + + srv := rpc.NewServer() + if err := srv.RegisterName("EchoService", x); err != nil { + return err + } + + for { + conn, err := lis.Accept() + if err != nil { + log.Fatalf("lis.Accept(): %v\n", err) + } + go srv.ServeCodec(protorpc.NewServerCodec(conn)) + } +} + +// ServeEchoService serves the given EchoService implementation. +func ServeEchoService(conn io.ReadWriteCloser, x EchoService) { + srv := rpc.NewServer() + if err := srv.RegisterName("EchoService", x); err != nil { + log.Fatal(err) + } + srv.ServeCodec(protorpc.NewServerCodec(conn)) +} + +type EchoServiceClient struct { + *rpc.Client +} + +// NewEchoServiceClient returns a EchoService stub to handle +// requests to the set of EchoService at the other end of the connection. +func NewEchoServiceClient(conn io.ReadWriteCloser) *EchoServiceClient { + c := rpc.NewClientWithCodec(protorpc.NewClientCodec(conn)) + return &EchoServiceClient{c} +} + +func (c *EchoServiceClient) Echo(in *EchoRequest) (out *EchoResponse, err error) { + if in == nil { + in = new(EchoRequest) + } + + type Validator interface { + Validate() error + } + if x, ok := proto.Message(in).(Validator); ok { + if err := x.Validate(); err != nil { + return nil, err + } + } + + out = new(EchoResponse) + if err = c.Call("EchoService.Echo", in, out); err != nil { + return nil, err + } + + if x, ok := proto.Message(out).(Validator); ok { + if err := x.Validate(); err != nil { + return out, err + } + } + + return out, nil +} + +func (c *EchoServiceClient) AsyncEcho(in *EchoRequest, out *EchoResponse, done chan *rpc.Call) *rpc.Call { + if in == nil { + in = new(EchoRequest) + } + return c.Go( + "EchoService.Echo", + in, out, + done, + ) +} + +func (c *EchoServiceClient) EchoTwice(in *EchoRequest) (out *EchoResponse, err error) { + if in == nil { + in = new(EchoRequest) + } + + type Validator interface { + Validate() error + } + if x, ok := proto.Message(in).(Validator); ok { + if err := x.Validate(); err != nil { + return nil, err + } + } + + out = new(EchoResponse) + if err = c.Call("EchoService.EchoTwice", in, out); err != nil { + return nil, err + } + + if x, ok := proto.Message(out).(Validator); ok { + if err := x.Validate(); err != nil { + return out, err + } + } + + return out, nil +} + +func (c *EchoServiceClient) AsyncEchoTwice(in *EchoRequest, out *EchoResponse, done chan *rpc.Call) *rpc.Call { + if in == nil { + in = new(EchoRequest) + } + return c.Go( + "EchoService.EchoTwice", + in, out, + done, + ) +} + +// DialEchoService connects to an EchoService at the specified network address. +func DialEchoService(network, addr string) (*EchoServiceClient, error) { + c, err := protorpc.Dial(network, addr) + if err != nil { + return nil, err + } + return &EchoServiceClient{c}, nil +} + +// DialEchoServiceTimeout connects to an EchoService at the specified network address. +func DialEchoServiceTimeout(network, addr string, timeout time.Duration) (*EchoServiceClient, error) { + c, err := protorpc.DialTimeout(network, addr, timeout) + if err != nil { + return nil, err + } + return &EchoServiceClient{c}, nil +} diff --git a/core/protorpc/examples/service.pb/echo.proto b/core/protorpc/examples/service.pb/echo.proto new file mode 100644 index 0000000..60a5f16 --- /dev/null +++ b/core/protorpc/examples/service.pb/echo.proto @@ -0,0 +1,20 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +syntax = "proto3"; + +package service; + +message EchoRequest { + string msg = 1; +} + +message EchoResponse { + string msg = 1; +} + +service EchoService { + rpc Echo (EchoRequest) returns (EchoResponse); + rpc EchoTwice (EchoRequest) returns (EchoResponse); +} diff --git a/core/protorpc/examples/service.pb/echo_test.go b/core/protorpc/examples/service.pb/echo_test.go new file mode 100644 index 0000000..578c7ab --- /dev/null +++ b/core/protorpc/examples/service.pb/echo_test.go @@ -0,0 +1,698 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package service + +import ( + "fmt" + "log" + "net/rpc" + "sync" + "testing" + "unicode/utf8" +) + +var ( + echoHost = "127.0.0.1" + echoPort = 2015 + + echoRequest = "Hello, new gopher!" + echoResponse = echoRequest + echoRequest + echoMassiveRequest = makeMassive("Hello, 世界.") + echoMassiveResponse = echoMassiveRequest + echoMassiveRequest + + onceEcho sync.Once +) + +func makeMassive(args string) string { + runeLen := utf8.RuneCountInString(args) + runeBuf := make([]rune, runeLen*1024*100) + for i := 0; i < 1024*100; i++ { + offset := i * runeLen + j := 0 + for _, r := range args { + runeBuf[offset+j] = r + j++ + } + } + return string(runeBuf) +} + +func setupEchoServer() { + var wg sync.WaitGroup + wg.Add(1) + defer wg.Wait() + + go func() { + wg.Done() + + addr := fmt.Sprintf("127.0.0.1:%d", echoPort) + err := ListenAndServeEchoService("tcp", addr, new(Echo)) + if err != nil { + log.Fatalf("ListenAndServeEchoService: %v", err) + } + }() +} + +func TestEchoService(t *testing.T) { + onceEcho.Do(setupEchoServer) + + addr := fmt.Sprintf("%s:%d", echoHost, echoPort) + c, err := DialEchoService("tcp", addr) + if err != nil { + t.Fatalf( + `net.Dial("tcp", "%s:%d"): %v`, + echoHost, echoPort, + err, + ) + } + defer c.Close() + + testEchoService(t, c.Client) +} + +func testEchoService(t *testing.T, client *rpc.Client) { + var args EchoRequest + var reply EchoResponse + var err error + + // EchoService.EchoTwice + args.Msg = echoRequest + err = client.Call("EchoService.EchoTwice", &args, &reply) + if err != nil { + t.Fatalf(`EchoService.EchoTwice: %v`, err) + } + if reply.Msg != echoResponse { + t.Fatalf( + `EchoService.EchoTwice: expected = "%s", got = "%s"`, + echoResponse, reply.Msg, + ) + } + + // EchoService.EchoTwice (Massive) + args.Msg = echoMassiveRequest + err = client.Call("EchoService.EchoTwice", &args, &reply) + if err != nil { + t.Fatalf(`EchoService.EchoTwice: %v`, err) + } + if reply.Msg != echoMassiveResponse { + got := reply.Msg + if len(got) > 8 { + got = got[:8] + "..." + } + t.Fatalf(`EchoService.EchoTwice: len = %d, got = %v`, + len(reply.Msg), got, + ) + } +} + +func TestClientSyncEcho(t *testing.T) { + onceEcho.Do(setupEchoServer) + + addr := fmt.Sprintf("%s:%d", echoHost, echoPort) + echoClient, err := DialEchoService("tcp", addr) + if err != nil { + t.Fatalf( + `net.Dial("tcp", "%s:%d"): %v`, + echoHost, echoPort, + err, + ) + } + defer echoClient.Close() + + var args EchoRequest + var reply *EchoResponse + + // EchoService.EchoTwice + args.Msg = "abc" + reply, err = echoClient.EchoTwice(&args) + if err != nil { + t.Fatalf(`EchoService.EchoTwice: %v`, err) + } + if reply.Msg != args.Msg+args.Msg { + t.Fatalf( + `EchoService.EchoTwice: expected = "%s", got = "%s"`, + args.Msg+args.Msg, reply.Msg, + ) + } + + // EchoService.EchoTwice + args.Msg = "你好, 世界" + reply, err = echoClient.EchoTwice(&args) + if err != nil { + t.Fatalf(`EchoService.EchoTwice: %v`, err) + } + if reply.Msg != args.Msg+args.Msg { + t.Fatalf( + `EchoService.EchoTwice: expected = "%s", got = "%s"`, + args.Msg+args.Msg, reply.Msg, + ) + } +} + +func TestClientSyncMassive(t *testing.T) { + onceEcho.Do(setupEchoServer) + + addr := fmt.Sprintf("%s:%d", echoHost, echoPort) + echoClient, err := DialEchoService("tcp", addr) + if err != nil { + t.Fatalf( + `net.Dial("tcp", "%s:%d"): %v`, + echoHost, echoPort, + err, + ) + } + defer echoClient.Close() + + var args EchoRequest + var reply *EchoResponse + + // EchoService.EchoTwice + args.Msg = echoMassiveRequest + "abc" + reply, err = echoClient.EchoTwice(&args) + if err != nil { + t.Fatalf(`EchoService.EchoTwice: %v`, err) + } + if reply.Msg != args.Msg+args.Msg { + got := reply.Msg + if len(got) > 8 { + got = got[:8] + "..." + } + t.Fatalf(`EchoService.EchoTwice: len = %d, got = %v`, + len(reply.Msg), got, + ) + } + + // EchoService.EchoTwice + args.Msg = echoMassiveRequest + "你好, 世界" + reply, err = echoClient.EchoTwice(&args) + if err != nil { + t.Fatalf(`EchoService.EchoTwice: %v`, err) + } + if reply.Msg != args.Msg+args.Msg { + got := reply.Msg + if len(got) > 8 { + got = got[:8] + "..." + } + t.Fatalf(`EchoService.EchoTwice: len = %d, got = %v`, + len(reply.Msg), got, + ) + } +} + +func TestClientAsyncEcho(t *testing.T) { + onceEcho.Do(setupEchoServer) + + addr := fmt.Sprintf("%s:%d", echoHost, echoPort) + client, err := DialEchoService("tcp", addr) + if err != nil { + t.Fatalf( + `net.Dial("tcp", "%s:%d"): %v`, + echoHost, echoPort, + err, + ) + } + defer client.Close() + + var args EchoRequest + var reply EchoResponse + + // EchoService.EchoTwice + args.Msg = echoRequest + call := client.Go("EchoService.EchoTwice", &args, &reply, nil) + + call = <-call.Done + if call.Error != nil { + t.Fatalf(`EchoService.EchoTwice: %v`, call.Error) + } + if call.Reply.(*EchoResponse).Msg != echoResponse { + t.Fatalf( + `EchoService.EchoTwice: expected = "%s", got = "%s"`, + echoResponse, call.Reply.(*EchoResponse).Msg, + ) + } +} + +func TestClientAsyncEchoBatches(t *testing.T) { + onceEcho.Do(setupEchoServer) + + addr := fmt.Sprintf("%s:%d", echoHost, echoPort) + client, err := DialEchoService("tcp", addr) + if err != nil { + t.Fatalf( + `net.Dial("tcp", "%s:%d"): %v`, + echoHost, echoPort, + err, + ) + } + defer client.Close() + + var args1 EchoRequest + var reply1 EchoResponse + var args2 EchoRequest + var reply2 EchoResponse + var args3 EchoRequest + var reply3 EchoResponse + + // EchoService.EchoTwice + args1.Msg = "abc" + call1 := client.Go("EchoService.EchoTwice", &args1, &reply1, nil) + args2.Msg = "你好, 世界" + call2 := client.Go("EchoService.EchoTwice", &args2, &reply2, nil) + args3.Msg = "Hello, 世界" + call3 := client.Go("EchoService.EchoTwice", &args3, &reply3, nil) + + call1 = <-call1.Done + call2 = <-call2.Done + call3 = <-call3.Done + + // call1 + if call1.Error != nil { + t.Fatalf(`EchoService.EchoTwice: %v`, call1.Error) + } + if call1.Reply.(*EchoResponse).Msg != args1.Msg+args1.Msg { + t.Fatalf( + `EchoService.EchoTwice: expected = "%s", got = "%s"`, + args1.Msg+args1.Msg, + call1.Reply.(*EchoResponse).Msg, + ) + } + + // call2 + if call2.Error != nil { + t.Fatalf(`EchoService.EchoTwice: %v`, call2.Error) + } + if call2.Reply.(*EchoResponse).Msg != args2.Msg+args2.Msg { + t.Fatalf( + `EchoService.EchoTwice: expected = "%s", got = "%s"`, + args2.Msg+args2.Msg, + call2.Reply.(*EchoResponse).Msg, + ) + } + + // call3 + if call3.Error != nil { + t.Fatalf(`EchoService.EchoTwice: %v`, call3.Error) + } + if call3.Reply.(*EchoResponse).Msg != args3.Msg+args3.Msg { + t.Fatalf( + `EchoService.EchoTwice: expected = "%s", got = "%s"`, + args3.Msg+args3.Msg, + call3.Reply.(*EchoResponse).Msg, + ) + } +} + +func TestClientAsyncMassive(t *testing.T) { + onceEcho.Do(setupEchoServer) + + addr := fmt.Sprintf("%s:%d", echoHost, echoPort) + client, err := DialEchoService("tcp", addr) + if err != nil { + t.Fatalf( + `net.Dial("tcp", "%s:%d"): %v`, + echoHost, echoPort, + err, + ) + } + defer client.Close() + + var args EchoRequest + var reply EchoResponse + + // EchoService.EchoTwice + args.Msg = echoMassiveRequest + call := client.Go("EchoService.EchoTwice", &args, &reply, nil) + + call = <-call.Done + if call.Error != nil { + t.Fatalf(`EchoService.EchoTwice: %v`, call.Error) + } + if call.Reply.(*EchoResponse).Msg != echoMassiveResponse { + got := call.Reply.(*EchoResponse).Msg + if len(got) > 8 { + got = got[:8] + "..." + } + t.Fatalf(`EchoService.EchoTwice: len = %d, got = %v`, + len(call.Reply.(*EchoResponse).Msg), got, + ) + } +} + +func TestClientAsyncMassiveBatches(t *testing.T) { + onceEcho.Do(setupEchoServer) + + addr := fmt.Sprintf("%s:%d", echoHost, echoPort) + client, err := DialEchoService("tcp", addr) + if err != nil { + t.Fatalf( + `net.Dial("tcp", "%s:%d"): %v`, + echoHost, echoPort, + err, + ) + } + defer client.Close() + + var args1 EchoRequest + var reply1 EchoResponse + var args2 EchoRequest + var reply2 EchoResponse + var args3 EchoRequest + var reply3 EchoResponse + + // EchoService.EchoTwice + args1.Msg = echoMassiveRequest + "abc" + call1 := client.Go("EchoService.EchoTwice", &args1, &reply1, nil) + args2.Msg = echoMassiveRequest + "你好, 世界" + call2 := client.Go("EchoService.EchoTwice", &args2, &reply2, nil) + args3.Msg = echoMassiveRequest + "Hello, 世界" + call3 := client.Go("EchoService.EchoTwice", &args3, &reply3, nil) + + call1 = <-call1.Done + call2 = <-call2.Done + call3 = <-call3.Done + + // call1 + if call1.Error != nil { + t.Fatalf(`EchoService.EchoTwice: %v`, call1.Error) + } + if call1.Reply.(*EchoResponse).Msg != args1.Msg+args1.Msg { + got := call1.Reply.(*EchoResponse).Msg + if len(got) > 8 { + got = got[:8] + "..." + } + t.Fatalf(`EchoService.EchoTwice: len = %d, got = %v`, + len(call1.Reply.(*EchoResponse).Msg), got, + ) + } + + // call2 + if call2.Error != nil { + t.Fatalf(`EchoService.EchoTwice: %v`, call2.Error) + } + if call2.Reply.(*EchoResponse).Msg != args2.Msg+args2.Msg { + got := call2.Reply.(*EchoResponse).Msg + if len(got) > 8 { + got = got[:8] + "..." + } + t.Fatalf(`EchoService.EchoTwice: len = %d, got = %v`, + len(call2.Reply.(*EchoResponse).Msg), got, + ) + } + + // call3 + if call3.Error != nil { + t.Fatalf(`EchoService.EchoTwice: %v`, call3.Error) + } + if call3.Reply.(*EchoResponse).Msg != args3.Msg+args3.Msg { + got := call3.Reply.(*EchoResponse).Msg + if len(got) > 8 { + got = got[:8] + "..." + } + t.Fatalf(`EchoService.EchoTwice: len = %d, got = %v`, + len(call3.Reply.(*EchoResponse).Msg), got, + ) + } +} + +func BenchmarkSyncEcho(b *testing.B) { + onceEcho.Do(setupEchoServer) + + addr := fmt.Sprintf("%s:%d", echoHost, echoPort) + echoClient, err := DialEchoService("tcp", addr) + if err != nil { + b.Fatalf( + `net.Dial("tcp", "%s:%d"): %v`, + echoHost, echoPort, + err, + ) + } + defer echoClient.Close() + + b.ResetTimer() + for i := 0; i < b.N; i++ { + var args EchoRequest + var reply *EchoResponse + + // EchoService.EchoTwice + args.Msg = "abc" + reply, err = echoClient.EchoTwice(&args) + if err != nil { + b.Fatalf(`EchoService.EchoTwice: %v`, err) + } + if reply.Msg != args.Msg+args.Msg { + b.Fatalf( + `EchoService.EchoTwice: expected = "%s", got = "%s"`, + args.Msg+args.Msg, reply.Msg, + ) + } + + // EchoService.EchoTwice + args.Msg = "你好, 世界" + reply, err = echoClient.EchoTwice(&args) + if err != nil { + b.Fatalf(`EchoService.EchoTwice: %v`, err) + } + if reply.Msg != args.Msg+args.Msg { + b.Fatalf( + `EchoService.EchoTwice: expected = "%s", got = "%s"`, + args.Msg+args.Msg, reply.Msg, + ) + } + + // EchoService.EchoTwice + args.Msg = "Hello, 世界" + reply, err = echoClient.EchoTwice(&args) + if err != nil { + b.Fatalf(`EchoService.EchoTwice: %v`, err) + } + if reply.Msg != args.Msg+args.Msg { + b.Fatalf( + `EchoService.EchoTwice: expected = "%s", got = "%s"`, + args.Msg+args.Msg, reply.Msg, + ) + } + } +} + +func BenchmarkSyncMassive(b *testing.B) { + onceEcho.Do(setupEchoServer) + + addr := fmt.Sprintf("%s:%d", echoHost, echoPort) + echoClient, err := DialEchoService("tcp", addr) + if err != nil { + b.Fatalf( + `net.Dial("tcp", "%s:%d"): %v`, + echoHost, echoPort, + err, + ) + } + defer echoClient.Close() + + b.ResetTimer() + for i := 0; i < b.N; i++ { + var args EchoRequest + var reply *EchoResponse + + // EchoService.EchoTwice + args.Msg = echoMassiveRequest + "abc" + reply, err = echoClient.EchoTwice(&args) + if err != nil { + b.Fatalf(`EchoService.EchoTwice: %v`, err) + } + if reply.Msg != args.Msg+args.Msg { + got := reply.Msg + if len(got) > 8 { + got = got[:8] + "..." + } + b.Fatalf(`EchoService.EchoTwice: len = %d, got = %v`, + len(reply.Msg), got, + ) + } + + // EchoService.EchoTwice + args.Msg = echoMassiveRequest + "你好, 世界" + reply, err = echoClient.EchoTwice(&args) + if err != nil { + b.Fatalf(`EchoService.EchoTwice: %v`, err) + } + if reply.Msg != args.Msg+args.Msg { + got := reply.Msg + if len(got) > 8 { + got = got[:8] + "..." + } + b.Fatalf(`EchoService.EchoTwice: len = %d, got = %v`, + len(reply.Msg), got, + ) + } + + // EchoService.EchoTwice + args.Msg = echoMassiveRequest + "Hello, 世界" + reply, err = echoClient.EchoTwice(&args) + if err != nil { + b.Fatalf(`EchoService.EchoTwice: %v`, err) + } + if reply.Msg != args.Msg+args.Msg { + got := reply.Msg + if len(got) > 8 { + got = got[:8] + "..." + } + b.Fatalf(`EchoService.EchoTwice: len = %d, got = %v`, + len(reply.Msg), got, + ) + } + } +} + +func BenchmarkAsyncEcho(b *testing.B) { + onceEcho.Do(setupEchoServer) + + addr := fmt.Sprintf("%s:%d", echoHost, echoPort) + client, err := DialEchoService("tcp", addr) + if err != nil { + b.Fatalf( + `net.Dial("tcp", "%s:%d"): %v`, + echoHost, echoPort, + err, + ) + } + defer client.Close() + + b.ResetTimer() + for i := 0; i < b.N; i++ { + var args1 EchoRequest + var reply1 EchoResponse + var args2 EchoRequest + var reply2 EchoResponse + var args3 EchoRequest + var reply3 EchoResponse + + // EchoService.EchoTwice + args1.Msg = "abc" + call1 := client.Go("EchoService.EchoTwice", &args1, &reply1, nil) + args2.Msg = "你好, 世界" + call2 := client.Go("EchoService.EchoTwice", &args2, &reply2, nil) + args3.Msg = "Hello, 世界" + call3 := client.Go("EchoService.EchoTwice", &args3, &reply3, nil) + + call1 = <-call1.Done + call2 = <-call2.Done + call3 = <-call3.Done + + // call1 + if call1.Error != nil { + b.Fatalf(`EchoService.EchoTwice: %v`, call1.Error) + } + if call1.Reply.(*EchoResponse).Msg != args1.Msg+args1.Msg { + b.Fatalf( + `EchoService.EchoTwice: expected = "%s", got = "%s"`, + args1.Msg+args1.Msg, + call1.Reply.(*EchoResponse).Msg, + ) + } + + // call2 + if call2.Error != nil { + b.Fatalf(`EchoService.EchoTwice: %v`, call2.Error) + } + if call2.Reply.(*EchoResponse).Msg != args2.Msg+args2.Msg { + b.Fatalf( + `EchoService.EchoTwice: expected = "%s", got = "%s"`, + args2.Msg+args2.Msg, + call2.Reply.(*EchoResponse).Msg, + ) + } + + // call3 + if call3.Error != nil { + b.Fatalf(`EchoService.EchoTwice: %v`, call3.Error) + } + if call3.Reply.(*EchoResponse).Msg != args3.Msg+args3.Msg { + b.Fatalf( + `EchoService.EchoTwice: expected = "%s", got = "%s"`, + args3.Msg+args3.Msg, + call3.Reply.(*EchoResponse).Msg, + ) + } + } +} + +func BenchmarkAsyncMassive(b *testing.B) { + onceEcho.Do(setupEchoServer) + + addr := fmt.Sprintf("%s:%d", echoHost, echoPort) + client, err := DialEchoService("tcp", addr) + if err != nil { + b.Fatalf( + `net.Dial("tcp", "%s:%d"): %v`, + echoHost, echoPort, + err, + ) + } + defer client.Close() + + b.ResetTimer() + for i := 0; i < b.N; i++ { + var args1 EchoRequest + var reply1 EchoResponse + var args2 EchoRequest + var reply2 EchoResponse + var args3 EchoRequest + var reply3 EchoResponse + + // EchoService.EchoTwice + args1.Msg = echoMassiveRequest + "abc" + call1 := client.Go("EchoService.EchoTwice", &args1, &reply1, nil) + args2.Msg = echoMassiveRequest + "你好, 世界" + call2 := client.Go("EchoService.EchoTwice", &args2, &reply2, nil) + args3.Msg = echoMassiveRequest + "Hello, 世界" + call3 := client.Go("EchoService.EchoTwice", &args3, &reply3, nil) + + call1 = <-call1.Done + call2 = <-call2.Done + call3 = <-call3.Done + + // call1 + if call1.Error != nil { + b.Fatalf(`EchoService.EchoTwice: %v`, call1.Error) + } + if call1.Reply.(*EchoResponse).Msg != args1.Msg+args1.Msg { + got := call1.Reply.(*EchoResponse).Msg + if len(got) > 8 { + got = got[:8] + "..." + } + b.Fatalf(`EchoService.EchoTwice: len = %d, got = %v`, + len(call1.Reply.(*EchoResponse).Msg), got, + ) + } + + // call2 + if call2.Error != nil { + b.Fatalf(`EchoService.EchoTwice: %v`, call2.Error) + } + if call2.Reply.(*EchoResponse).Msg != args2.Msg+args2.Msg { + got := call2.Reply.(*EchoResponse).Msg + if len(got) > 8 { + got = got[:8] + "..." + } + b.Fatalf(`EchoService.EchoTwice: len = %d, got = %v`, + len(call2.Reply.(*EchoResponse).Msg), got, + ) + } + + // call3 + if call3.Error != nil { + b.Fatalf(`EchoService.EchoTwice: %v`, call3.Error) + } + if call3.Reply.(*EchoResponse).Msg != args3.Msg+args3.Msg { + got := call3.Reply.(*EchoResponse).Msg + if len(got) > 8 { + got = got[:8] + "..." + } + b.Fatalf(`EchoService.EchoTwice: len = %d, got = %v`, + len(call3.Reply.(*EchoResponse).Msg), got, + ) + } + } +} diff --git a/core/protorpc/examples/service.pb/proto.go b/core/protorpc/examples/service.pb/proto.go new file mode 100644 index 0000000..92f2491 --- /dev/null +++ b/core/protorpc/examples/service.pb/proto.go @@ -0,0 +1,8 @@ +// Copyright 2014 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:generate protoc --go_out=. arith.proto echo.proto +//go:generate protoc --protorpc_out=. arith.proto echo.proto + +package service diff --git a/core/protorpc/examples/stdrpc.pb/Makefile b/core/protorpc/examples/stdrpc.pb/Makefile new file mode 100644 index 0000000..cdd2179 --- /dev/null +++ b/core/protorpc/examples/stdrpc.pb/Makefile @@ -0,0 +1,13 @@ +# Copyright 2013 . All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +PROTO_FILES=$(sort $(wildcard ./*.proto)) + +default: $(PROTO_FILES) Makefile + go install github.com/golang/protobuf/protoc-gen-go + go install github.com/chai2010/protorpc/protoc-gen-stdrpc + protoc --stdrpc_out=. ${PROTO_FILES} + go test + +clean: diff --git a/core/protorpc/examples/stdrpc.pb/arith.pb.go b/core/protorpc/examples/stdrpc.pb/arith.pb.go new file mode 100644 index 0000000..57be423 --- /dev/null +++ b/core/protorpc/examples/stdrpc.pb/arith.pb.go @@ -0,0 +1,401 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: arith.proto + +/* +Package service is a generated protocol buffer package. + +It is generated from these files: + arith.proto + echo.proto + +It has these top-level messages: + ArithRequest + ArithResponse + EchoRequest + EchoResponse +*/ +package service + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +import "bufio" +import "crypto/tls" +import "errors" +import "io" +import "log" +import "net" +import "net/http" +import "net/rpc" +import "time" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +type ArithRequest struct { + A int32 `protobuf:"varint,1,opt,name=a" json:"a,omitempty"` + B int32 `protobuf:"varint,2,opt,name=b" json:"b,omitempty"` +} + +func (m *ArithRequest) Reset() { *m = ArithRequest{} } +func (m *ArithRequest) String() string { return proto.CompactTextString(m) } +func (*ArithRequest) ProtoMessage() {} +func (*ArithRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +func (m *ArithRequest) GetA() int32 { + if m != nil { + return m.A + } + return 0 +} + +func (m *ArithRequest) GetB() int32 { + if m != nil { + return m.B + } + return 0 +} + +type ArithResponse struct { + C int32 `protobuf:"varint,1,opt,name=c" json:"c,omitempty"` +} + +func (m *ArithResponse) Reset() { *m = ArithResponse{} } +func (m *ArithResponse) String() string { return proto.CompactTextString(m) } +func (*ArithResponse) ProtoMessage() {} +func (*ArithResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +func (m *ArithResponse) GetC() int32 { + if m != nil { + return m.C + } + return 0 +} + +func init() { + proto.RegisterType((*ArithRequest)(nil), "service.ArithRequest") + proto.RegisterType((*ArithResponse)(nil), "service.ArithResponse") +} + +type ArithService interface { + Add(in *ArithRequest, out *ArithResponse) error + Mul(in *ArithRequest, out *ArithResponse) error + Div(in *ArithRequest, out *ArithResponse) error + Error(in *ArithRequest, out *ArithResponse) error +} + +// AcceptArithServiceClient accepts connections on the listener and serves requests +// for each incoming connection. Accept blocks; the caller typically +// invokes it in a go statement. +func AcceptArithServiceClient(lis net.Listener, x ArithService) { + srv := rpc.NewServer() + if err := srv.RegisterName("service.ArithService", x); err != nil { + log.Fatal(err) + } + + for { + conn, err := lis.Accept() + if err != nil { + log.Fatalf("lis.Accept(): %v\n", err) + } + go srv.ServeConn(conn) + } +} + +// RegisterArithService publish the given ArithService implementation on the server. +func RegisterArithService(srv *rpc.Server, x ArithService) error { + if err := srv.RegisterName("service.ArithService", x); err != nil { + return err + } + return nil +} + +// NewArithServiceServer returns a new ArithService Server. +func NewArithServiceServer(x ArithService) *rpc.Server { + srv := rpc.NewServer() + if err := srv.RegisterName("service.ArithService", x); err != nil { + log.Fatal(err) + } + return srv +} + +// ListenAndServeArithService listen announces on the local network address laddr +// and serves the given ArithService implementation. +func ListenAndServeArithService(network, addr string, x ArithService) error { + lis, err := net.Listen(network, addr) + if err != nil { + return err + } + defer lis.Close() + + srv := rpc.NewServer() + if err := srv.RegisterName("service.ArithService", x); err != nil { + return err + } + + for { + conn, err := lis.Accept() + if err != nil { + log.Fatalf("lis.Accept(): %v\n", err) + } + go srv.ServeConn(conn) + } +} + +// ServeArithService serves the given ArithService implementation. +func ServeArithService(conn io.ReadWriteCloser, x ArithService) { + srv := rpc.NewServer() + if err := srv.RegisterName("service.ArithService", x); err != nil { + log.Fatal(err) + } + srv.ServeConn(conn) +} + +type ArithServiceClient struct { + *rpc.Client +} + +// NewArithServiceClient returns a ArithService stub to handle +// requests to the set of ArithService at the other end of the connection. +func NewArithServiceClient(conn io.ReadWriteCloser) *ArithServiceClient { + c := rpc.NewClient(conn) + return &ArithServiceClient{c} +} + +func (c *ArithServiceClient) Add(in *ArithRequest) (out *ArithResponse, err error) { + if in == nil { + in = new(ArithRequest) + } + type Validator interface { + Validate() error + } + if x, ok := proto.Message(in).(Validator); ok { + if err := x.Validate(); err != nil { + return nil, err + } + } + out = new(ArithResponse) + if err = c.Call("service.ArithService.Add", in, out); err != nil { + return nil, err + } + if x, ok := proto.Message(out).(Validator); ok { + if err := x.Validate(); err != nil { + return out, err + } + } + return out, nil +} + +func (c *ArithServiceClient) AsyncAdd(in *ArithRequest, out *ArithResponse, done chan *rpc.Call) *rpc.Call { + if in == nil { + in = new(ArithRequest) + } + return c.Go( + "service.ArithService.Add", + in, out, + done, + ) +} + +func (c *ArithServiceClient) Mul(in *ArithRequest) (out *ArithResponse, err error) { + if in == nil { + in = new(ArithRequest) + } + type Validator interface { + Validate() error + } + if x, ok := proto.Message(in).(Validator); ok { + if err := x.Validate(); err != nil { + return nil, err + } + } + out = new(ArithResponse) + if err = c.Call("service.ArithService.Mul", in, out); err != nil { + return nil, err + } + if x, ok := proto.Message(out).(Validator); ok { + if err := x.Validate(); err != nil { + return out, err + } + } + return out, nil +} + +func (c *ArithServiceClient) AsyncMul(in *ArithRequest, out *ArithResponse, done chan *rpc.Call) *rpc.Call { + if in == nil { + in = new(ArithRequest) + } + return c.Go( + "service.ArithService.Mul", + in, out, + done, + ) +} + +func (c *ArithServiceClient) Div(in *ArithRequest) (out *ArithResponse, err error) { + if in == nil { + in = new(ArithRequest) + } + type Validator interface { + Validate() error + } + if x, ok := proto.Message(in).(Validator); ok { + if err := x.Validate(); err != nil { + return nil, err + } + } + out = new(ArithResponse) + if err = c.Call("service.ArithService.Div", in, out); err != nil { + return nil, err + } + if x, ok := proto.Message(out).(Validator); ok { + if err := x.Validate(); err != nil { + return out, err + } + } + return out, nil +} + +func (c *ArithServiceClient) AsyncDiv(in *ArithRequest, out *ArithResponse, done chan *rpc.Call) *rpc.Call { + if in == nil { + in = new(ArithRequest) + } + return c.Go( + "service.ArithService.Div", + in, out, + done, + ) +} + +func (c *ArithServiceClient) Error(in *ArithRequest) (out *ArithResponse, err error) { + if in == nil { + in = new(ArithRequest) + } + type Validator interface { + Validate() error + } + if x, ok := proto.Message(in).(Validator); ok { + if err := x.Validate(); err != nil { + return nil, err + } + } + out = new(ArithResponse) + if err = c.Call("service.ArithService.Error", in, out); err != nil { + return nil, err + } + if x, ok := proto.Message(out).(Validator); ok { + if err := x.Validate(); err != nil { + return out, err + } + } + return out, nil +} + +func (c *ArithServiceClient) AsyncError(in *ArithRequest, out *ArithResponse, done chan *rpc.Call) *rpc.Call { + if in == nil { + in = new(ArithRequest) + } + return c.Go( + "service.ArithService.Error", + in, out, + done, + ) +} + +// DialArithService connects to an ArithService at the specified network address. +func DialArithService(network, addr string) (*ArithServiceClient, error) { + c, err := rpc.Dial(network, addr) + if err != nil { + return nil, err + } + return &ArithServiceClient{c}, nil +} + +// DialArithServiceTimeout connects to an ArithService at the specified network address. +func DialArithServiceTimeout(network, addr string, timeout time.Duration) (*ArithServiceClient, error) { + conn, err := net.DialTimeout(network, addr, timeout) + if err != nil { + return nil, err + } + return &ArithServiceClient{rpc.NewClient(conn)}, nil +} + +// DialArithServiceHTTP connects to an HTTP RPC server at the specified network address +// listening on the default HTTP RPC path. +func DialArithServiceHTTP(network, address string) (*ArithServiceClient, error) { + return DialArithServiceHTTPPath(network, address, rpc.DefaultRPCPath) +} + +// DialArithServiceHTTPPath connects to an HTTP RPC server +// at the specified network address and path. +func DialArithServiceHTTPPath(network, address, path string) (*ArithServiceClient, error) { + conn, err := net.Dial(network, address) + if err != nil { + return nil, err + } + return dialArithServicePath(network, address, path, conn) +} + +// DialArithServiceHTTPS connects to an HTTPS RPC server at the specified network address +// listening on the default HTTP RPC path. +func DialArithServiceHTTPS(network, address string, tlsConfig *tls.Config) (*ArithServiceClient, error) { + return DialArithServiceHTTPSPath(network, address, rpc.DefaultRPCPath, tlsConfig) +} + +// DialArithServiceHTTPSPath connects to an HTTPS RPC server +// at the specified network address and path. +func DialArithServiceHTTPSPath(network, address, path string, tlsConfig *tls.Config) (*ArithServiceClient, error) { + conn, err := tls.Dial(network, address, tlsConfig) + if err != nil { + return nil, err + } + return dialArithServicePath(network, address, path, conn) +} + +func dialArithServicePath(network, address, path string, conn net.Conn) (*ArithServiceClient, error) { + const net_rpc_connected = "200 Connected to Go RPC" + + io.WriteString(conn, "CONNECT "+path+" HTTP/1.0\n\n") + + // Require successful HTTP response + // before switching to RPC protocol. + resp, err := http.ReadResponse(bufio.NewReader(conn), &http.Request{Method: "CONNECT"}) + if err == nil && resp.Status == net_rpc_connected { + return &ArithServiceClient{rpc.NewClient(conn)}, nil + } + if err == nil { + err = errors.New("unexpected HTTP response: " + resp.Status) + } + conn.Close() + return nil, &net.OpError{ + Op: "dial-http", + Net: network + " " + address, + Addr: nil, + Err: err, + } +} + +func init() { proto.RegisterFile("arith.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 159 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4e, 0x2c, 0xca, 0x2c, + 0xc9, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x2f, 0x4e, 0x2d, 0x2a, 0xcb, 0x4c, 0x4e, + 0x55, 0xd2, 0xe2, 0xe2, 0x71, 0x04, 0x89, 0x07, 0xa5, 0x16, 0x96, 0xa6, 0x16, 0x97, 0x08, 0xf1, + 0x70, 0x31, 0x26, 0x4a, 0x30, 0x2a, 0x30, 0x6a, 0xb0, 0x06, 0x31, 0x26, 0x82, 0x78, 0x49, 0x12, + 0x4c, 0x10, 0x5e, 0x92, 0x92, 0x2c, 0x17, 0x2f, 0x54, 0x6d, 0x71, 0x41, 0x7e, 0x5e, 0x71, 0x2a, + 0x48, 0x3a, 0x19, 0xa6, 0x38, 0xd9, 0xe8, 0x05, 0x23, 0xd4, 0xac, 0x60, 0x88, 0xd9, 0x42, 0x26, + 0x5c, 0xcc, 0x89, 0x29, 0x29, 0x42, 0xa2, 0x7a, 0x50, 0xcb, 0xf4, 0x90, 0x6d, 0x92, 0x12, 0x43, + 0x17, 0x86, 0x1a, 0x6a, 0xc2, 0xc5, 0x9c, 0x5b, 0x9a, 0x43, 0x86, 0xae, 0x94, 0xcc, 0x32, 0x52, + 0x75, 0x99, 0x71, 0xb1, 0xa6, 0x16, 0x15, 0xe5, 0x17, 0x91, 0xa8, 0x2f, 0x89, 0x0d, 0x1c, 0x8a, + 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa2, 0x62, 0xfd, 0xbd, 0x54, 0x01, 0x00, 0x00, +} diff --git a/core/protorpc/examples/stdrpc.pb/arith.proto b/core/protorpc/examples/stdrpc.pb/arith.proto new file mode 100644 index 0000000..7c92e4f --- /dev/null +++ b/core/protorpc/examples/stdrpc.pb/arith.proto @@ -0,0 +1,23 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +syntax = "proto3"; + +package service; + +message ArithRequest { + int32 a = 1; + int32 b = 2; +} + +message ArithResponse { + int32 c = 1; +} + +service ArithService { + rpc add (ArithRequest) returns (ArithResponse); + rpc mul (ArithRequest) returns (ArithResponse); + rpc div (ArithRequest) returns (ArithResponse); + rpc error (ArithRequest) returns (ArithResponse); +} diff --git a/core/protorpc/examples/stdrpc.pb/echo.pb.go b/core/protorpc/examples/stdrpc.pb/echo.pb.go new file mode 100644 index 0000000..9e2725d --- /dev/null +++ b/core/protorpc/examples/stdrpc.pb/echo.pb.go @@ -0,0 +1,301 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: echo.proto + +package service + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +import "bufio" +import "crypto/tls" +import "errors" +import "io" +import "log" +import "net" +import "net/http" +import "net/rpc" +import "time" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +type EchoRequest struct { + Msg string `protobuf:"bytes,1,opt,name=msg" json:"msg,omitempty"` +} + +func (m *EchoRequest) Reset() { *m = EchoRequest{} } +func (m *EchoRequest) String() string { return proto.CompactTextString(m) } +func (*EchoRequest) ProtoMessage() {} +func (*EchoRequest) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} } + +func (m *EchoRequest) GetMsg() string { + if m != nil { + return m.Msg + } + return "" +} + +type EchoResponse struct { + Msg string `protobuf:"bytes,1,opt,name=msg" json:"msg,omitempty"` +} + +func (m *EchoResponse) Reset() { *m = EchoResponse{} } +func (m *EchoResponse) String() string { return proto.CompactTextString(m) } +func (*EchoResponse) ProtoMessage() {} +func (*EchoResponse) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{1} } + +func (m *EchoResponse) GetMsg() string { + if m != nil { + return m.Msg + } + return "" +} + +func init() { + proto.RegisterType((*EchoRequest)(nil), "service.EchoRequest") + proto.RegisterType((*EchoResponse)(nil), "service.EchoResponse") +} + +type EchoService interface { + Echo(in *EchoRequest, out *EchoResponse) error + EchoTwice(in *EchoRequest, out *EchoResponse) error +} + +// AcceptEchoServiceClient accepts connections on the listener and serves requests +// for each incoming connection. Accept blocks; the caller typically +// invokes it in a go statement. +func AcceptEchoServiceClient(lis net.Listener, x EchoService) { + srv := rpc.NewServer() + if err := srv.RegisterName("service.EchoService", x); err != nil { + log.Fatal(err) + } + + for { + conn, err := lis.Accept() + if err != nil { + log.Fatalf("lis.Accept(): %v\n", err) + } + go srv.ServeConn(conn) + } +} + +// RegisterEchoService publish the given EchoService implementation on the server. +func RegisterEchoService(srv *rpc.Server, x EchoService) error { + if err := srv.RegisterName("service.EchoService", x); err != nil { + return err + } + return nil +} + +// NewEchoServiceServer returns a new EchoService Server. +func NewEchoServiceServer(x EchoService) *rpc.Server { + srv := rpc.NewServer() + if err := srv.RegisterName("service.EchoService", x); err != nil { + log.Fatal(err) + } + return srv +} + +// ListenAndServeEchoService listen announces on the local network address laddr +// and serves the given EchoService implementation. +func ListenAndServeEchoService(network, addr string, x EchoService) error { + lis, err := net.Listen(network, addr) + if err != nil { + return err + } + defer lis.Close() + + srv := rpc.NewServer() + if err := srv.RegisterName("service.EchoService", x); err != nil { + return err + } + + for { + conn, err := lis.Accept() + if err != nil { + log.Fatalf("lis.Accept(): %v\n", err) + } + go srv.ServeConn(conn) + } +} + +// ServeEchoService serves the given EchoService implementation. +func ServeEchoService(conn io.ReadWriteCloser, x EchoService) { + srv := rpc.NewServer() + if err := srv.RegisterName("service.EchoService", x); err != nil { + log.Fatal(err) + } + srv.ServeConn(conn) +} + +type EchoServiceClient struct { + *rpc.Client +} + +// NewEchoServiceClient returns a EchoService stub to handle +// requests to the set of EchoService at the other end of the connection. +func NewEchoServiceClient(conn io.ReadWriteCloser) *EchoServiceClient { + c := rpc.NewClient(conn) + return &EchoServiceClient{c} +} + +func (c *EchoServiceClient) Echo(in *EchoRequest) (out *EchoResponse, err error) { + if in == nil { + in = new(EchoRequest) + } + type Validator interface { + Validate() error + } + if x, ok := proto.Message(in).(Validator); ok { + if err := x.Validate(); err != nil { + return nil, err + } + } + out = new(EchoResponse) + if err = c.Call("service.EchoService.Echo", in, out); err != nil { + return nil, err + } + if x, ok := proto.Message(out).(Validator); ok { + if err := x.Validate(); err != nil { + return out, err + } + } + return out, nil +} + +func (c *EchoServiceClient) AsyncEcho(in *EchoRequest, out *EchoResponse, done chan *rpc.Call) *rpc.Call { + if in == nil { + in = new(EchoRequest) + } + return c.Go( + "service.EchoService.Echo", + in, out, + done, + ) +} + +func (c *EchoServiceClient) EchoTwice(in *EchoRequest) (out *EchoResponse, err error) { + if in == nil { + in = new(EchoRequest) + } + type Validator interface { + Validate() error + } + if x, ok := proto.Message(in).(Validator); ok { + if err := x.Validate(); err != nil { + return nil, err + } + } + out = new(EchoResponse) + if err = c.Call("service.EchoService.EchoTwice", in, out); err != nil { + return nil, err + } + if x, ok := proto.Message(out).(Validator); ok { + if err := x.Validate(); err != nil { + return out, err + } + } + return out, nil +} + +func (c *EchoServiceClient) AsyncEchoTwice(in *EchoRequest, out *EchoResponse, done chan *rpc.Call) *rpc.Call { + if in == nil { + in = new(EchoRequest) + } + return c.Go( + "service.EchoService.EchoTwice", + in, out, + done, + ) +} + +// DialEchoService connects to an EchoService at the specified network address. +func DialEchoService(network, addr string) (*EchoServiceClient, error) { + c, err := rpc.Dial(network, addr) + if err != nil { + return nil, err + } + return &EchoServiceClient{c}, nil +} + +// DialEchoServiceTimeout connects to an EchoService at the specified network address. +func DialEchoServiceTimeout(network, addr string, timeout time.Duration) (*EchoServiceClient, error) { + conn, err := net.DialTimeout(network, addr, timeout) + if err != nil { + return nil, err + } + return &EchoServiceClient{rpc.NewClient(conn)}, nil +} + +// DialEchoServiceHTTP connects to an HTTP RPC server at the specified network address +// listening on the default HTTP RPC path. +func DialEchoServiceHTTP(network, address string) (*EchoServiceClient, error) { + return DialEchoServiceHTTPPath(network, address, rpc.DefaultRPCPath) +} + +// DialEchoServiceHTTPPath connects to an HTTP RPC server +// at the specified network address and path. +func DialEchoServiceHTTPPath(network, address, path string) (*EchoServiceClient, error) { + conn, err := net.Dial(network, address) + if err != nil { + return nil, err + } + return dialEchoServicePath(network, address, path, conn) +} + +// DialEchoServiceHTTPS connects to an HTTPS RPC server at the specified network address +// listening on the default HTTP RPC path. +func DialEchoServiceHTTPS(network, address string, tlsConfig *tls.Config) (*EchoServiceClient, error) { + return DialEchoServiceHTTPSPath(network, address, rpc.DefaultRPCPath, tlsConfig) +} + +// DialEchoServiceHTTPSPath connects to an HTTPS RPC server +// at the specified network address and path. +func DialEchoServiceHTTPSPath(network, address, path string, tlsConfig *tls.Config) (*EchoServiceClient, error) { + conn, err := tls.Dial(network, address, tlsConfig) + if err != nil { + return nil, err + } + return dialEchoServicePath(network, address, path, conn) +} + +func dialEchoServicePath(network, address, path string, conn net.Conn) (*EchoServiceClient, error) { + const net_rpc_connected = "200 Connected to Go RPC" + + io.WriteString(conn, "CONNECT "+path+" HTTP/1.0\n\n") + + // Require successful HTTP response + // before switching to RPC protocol. + resp, err := http.ReadResponse(bufio.NewReader(conn), &http.Request{Method: "CONNECT"}) + if err == nil && resp.Status == net_rpc_connected { + return &EchoServiceClient{rpc.NewClient(conn)}, nil + } + if err == nil { + err = errors.New("unexpected HTTP response: " + resp.Status) + } + conn.Close() + return nil, &net.OpError{ + Op: "dial-http", + Net: network + " " + address, + Addr: nil, + Err: err, + } +} + +func init() { proto.RegisterFile("echo.proto", fileDescriptor1) } + +var fileDescriptor1 = []byte{ + // 134 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4a, 0x4d, 0xce, 0xc8, + 0xd7, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x2f, 0x4e, 0x2d, 0x2a, 0xcb, 0x4c, 0x4e, 0x55, + 0x92, 0xe7, 0xe2, 0x76, 0x4d, 0xce, 0xc8, 0x0f, 0x4a, 0x2d, 0x2c, 0x4d, 0x2d, 0x2e, 0x11, 0x12, + 0xe0, 0x62, 0xce, 0x2d, 0x4e, 0x97, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x02, 0x31, 0x95, 0x14, + 0xb8, 0x78, 0x20, 0x0a, 0x8a, 0x0b, 0xf2, 0xf3, 0x8a, 0x53, 0x31, 0x55, 0x18, 0xd5, 0x40, 0x8c, + 0x08, 0x86, 0x98, 0x28, 0x64, 0xcc, 0xc5, 0x02, 0xe2, 0x0a, 0x89, 0xe8, 0x41, 0xed, 0xd0, 0x43, + 0xb2, 0x40, 0x4a, 0x14, 0x4d, 0x14, 0x6a, 0xaa, 0x05, 0x17, 0x27, 0x88, 0x1f, 0x52, 0x0e, 0x32, + 0x81, 0x14, 0x9d, 0x49, 0x6c, 0x60, 0x0f, 0x19, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc1, + 0xd4, 0xbd, 0xde, 0x00, 0x00, 0x00, +} diff --git a/core/protorpc/examples/stdrpc.pb/echo.proto b/core/protorpc/examples/stdrpc.pb/echo.proto new file mode 100644 index 0000000..60a5f16 --- /dev/null +++ b/core/protorpc/examples/stdrpc.pb/echo.proto @@ -0,0 +1,20 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +syntax = "proto3"; + +package service; + +message EchoRequest { + string msg = 1; +} + +message EchoResponse { + string msg = 1; +} + +service EchoService { + rpc Echo (EchoRequest) returns (EchoResponse); + rpc EchoTwice (EchoRequest) returns (EchoResponse); +} diff --git a/core/protorpc/go.mod b/core/protorpc/go.mod new file mode 100644 index 0000000..833ca05 --- /dev/null +++ b/core/protorpc/go.mod @@ -0,0 +1,11 @@ +// Copyright 2021 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +module github.com/chai2010/protorpc + +go 1.23 + +require github.com/golang/protobuf v1.5.4 + +require google.golang.org/protobuf v1.36.6 // indirect diff --git a/core/protorpc/hello.go b/core/protorpc/hello.go new file mode 100644 index 0000000..f54aae0 --- /dev/null +++ b/core/protorpc/hello.go @@ -0,0 +1,62 @@ +// Copyright 2014 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ingore + +package main + +import ( + "fmt" + "log" + + "github.com/chai2010/protorpc" + service "github.com/chai2010/protorpc/examples/service.pb" +) + +type Echo int + +func (t *Echo) Echo(args *service.EchoRequest, reply *service.EchoResponse) error { + reply.Msg = args.Msg + return nil +} + +func (t *Echo) EchoTwice(args *service.EchoRequest, reply *service.EchoResponse) error { + reply.Msg = args.Msg + args.Msg + return nil +} + +func init() { + go service.ListenAndServeEchoService("tcp", `127.0.0.1:9527`, new(Echo)) +} + +func main() { + echoClient, err := service.DialEchoService("tcp", `127.0.0.1:9527`) + if err != nil { + log.Fatalf("service.DialEchoService: %v", err) + } + defer echoClient.Close() + + args := &service.EchoRequest{Msg: "你好, 世界!"} + reply, err := echoClient.EchoTwice(args) + if err != nil { + log.Fatalf("echoClient.EchoTwice: %v", err) + } + fmt.Println(reply.Msg) + + // or use normal client + client, err := protorpc.Dial("tcp", `127.0.0.1:9527`) + if err != nil { + log.Fatalf("protorpc.Dial: %v", err) + } + defer client.Close() + + echoClient1 := &service.EchoServiceClient{client} + echoClient2 := &service.EchoServiceClient{client} + reply, err = echoClient1.EchoTwice(args) + reply, err = echoClient2.EchoTwice(args) + _, _ = reply, err + + // Output: + // 你好, 世界!你好, 世界! +} diff --git a/core/protorpc/hello2.go b/core/protorpc/hello2.go new file mode 100644 index 0000000..c90cb48 --- /dev/null +++ b/core/protorpc/hello2.go @@ -0,0 +1,65 @@ +// Copyright 2014 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build ingore + +package main + +import ( + "fmt" + "log" + "net/rpc" + "time" + + stdrpc "github.com/chai2010/protorpc/examples/stdrpc.pb" +) + +type Echo int + +func (t *Echo) Echo(args *stdrpc.EchoRequest, reply *stdrpc.EchoResponse) error { + reply.Msg = args.Msg + return nil +} + +func (t *Echo) EchoTwice(args *stdrpc.EchoRequest, reply *stdrpc.EchoResponse) error { + reply.Msg = args.Msg + args.Msg + return nil +} + +func init() { + go stdrpc.ListenAndServeEchoService("tcp", `127.0.0.1:9527`, new(Echo)) +} + +func main() { + time.Sleep(time.Second) + + echoClient, err := stdrpc.DialEchoService("tcp", `127.0.0.1:9527`) + if err != nil { + log.Fatalf("stdrpc.DialEchoService: %v", err) + } + defer echoClient.Close() + + args := &stdrpc.EchoRequest{Msg: "你好, 世界!"} + reply, err := echoClient.EchoTwice(args) + if err != nil { + log.Fatalf("echoClient.EchoTwice: %v", err) + } + fmt.Println(reply.Msg) + + // or use normal client + client, err := rpc.Dial("tcp", `127.0.0.1:9527`) + if err != nil { + log.Fatalf("rpc.Dial: %v", err) + } + defer client.Close() + + echoClient1 := &stdrpc.EchoServiceClient{client} + echoClient2 := &stdrpc.EchoServiceClient{client} + reply, err = echoClient1.EchoTwice(args) + reply, err = echoClient2.EchoTwice(args) + _, _ = reply, err + + // Output: + // 你好, 世界!你好, 世界! +} diff --git a/core/protorpc/protoc-gen-plugin/generator.go b/core/protorpc/protoc-gen-plugin/generator.go new file mode 100644 index 0000000..5478105 --- /dev/null +++ b/core/protorpc/protoc-gen-plugin/generator.go @@ -0,0 +1,52 @@ +// Copyright 2017 . All rights reserved. +// Use of this source code is governed by a Apache +// license that can be found in the LICENSE file. + +package plugin + +import ( + "github.com/golang/protobuf/protoc-gen-go/descriptor" + "github.com/golang/protobuf/protoc-gen-go/generator" +) + +var pkgCodeGeneratorList []CodeGenerator + +type CodeGenerator interface { + Name() string + FileNameExt() string + + HeaderCode(g *generator.Generator, file *generator.FileDescriptor) string + ServiceCode(g *generator.Generator, file *generator.FileDescriptor, svc *descriptor.ServiceDescriptorProto) string + MessageCode(g *generator.Generator, file *generator.FileDescriptor, msg *descriptor.DescriptorProto) string +} + +func RegisterCodeGenerator(g CodeGenerator) { + pkgCodeGeneratorList = append(pkgCodeGeneratorList, g) +} + +func getAllCodeGenerator() []CodeGenerator { + return pkgCodeGeneratorList +} + +func getAllServiceGeneratorNames() (names []string) { + for _, g := range pkgCodeGeneratorList { + names = append(names, g.Name()) + } + return +} + +func getFirstServiceGeneratorName() string { + if len(pkgCodeGeneratorList) > 0 { + return pkgCodeGeneratorList[0].Name() + } + return "" +} + +func getCodeGenerator(name string) CodeGenerator { + for _, g := range pkgCodeGeneratorList { + if g.Name() == name { + return g + } + } + return nil +} diff --git a/core/protorpc/protoc-gen-plugin/main.go b/core/protorpc/protoc-gen-plugin/main.go new file mode 100644 index 0000000..97d3d7e --- /dev/null +++ b/core/protorpc/protoc-gen-plugin/main.go @@ -0,0 +1,115 @@ +// Copyright 2017 . All rights reserved. +// Use of this source code is governed by a Apache +// license that can be found in the LICENSE file. + +package plugin + +import ( + "io/ioutil" + "log" + "os" + "strings" + + "github.com/golang/protobuf/proto" + "github.com/golang/protobuf/protoc-gen-go/generator" +) + +func Main() { + mainPlugin := new(mainPlugin) + generator.RegisterPlugin(mainPlugin) + + // Begin by allocating a generator. The request and response structures are stored there + // so we can do error handling easily - the response structure contains the field to + // report failure. + g := generator.New() + if len(getAllCodeGenerator()) == 0 { + g.Fail("no code generator plugin") + } + + pkgReadRequetFromStdin(g) + pkgGenerateAllFiles(g, mainPlugin) + pkgWriteResponseToStdout(g) +} + +func pkgGenerateAllFiles(g *generator.Generator, plugin *mainPlugin) { + // set default plugins + // protoc --xxx_out=. x.proto + plugin.InitService(pkgGetUserPlugin(g)) + + // parse command line parameters + g.CommandLineParameters("plugins=" + plugin.Name()) + + // Create a wrapped version of the Descriptors and EnumDescriptors that + // point to the file that defines them. + g.WrapTypes() + + g.SetPackageNames() + g.BuildTypeNameMap() + + g.GenerateAllFiles() + + // skip non *.pb.xxx.go + respFileList := g.Response.File[:0] + for _, file := range g.Response.File { + fileName := file.GetName() + extName := plugin.FileNameExt() + + if strings.HasSuffix(fileName, extName) { + respFileList = append(respFileList, file) + } + } + g.Response.File = respFileList +} + +func pkgReadRequetFromStdin(g *generator.Generator) { + data, err := ioutil.ReadAll(os.Stdin) + if err != nil { + g.Error(err, "reading input") + } + + if err := proto.Unmarshal(data, g.Request); err != nil { + g.Error(err, "parsing input proto") + } + + if len(g.Request.FileToGenerate) == 0 { + g.Fail("no files to generate") + } +} + +func pkgWriteResponseToStdout(g *generator.Generator) { + data, err := proto.Marshal(g.Response) + if err != nil { + g.Error(err, "failed to marshal output proto") + } + _, err = os.Stdout.Write(data) + if err != nil { + g.Error(err, "failed to write output proto") + } +} + +func pkgGetUserPlugin(g *generator.Generator) CodeGenerator { + args := g.Request.GetParameter() + userPluginName := pkgGetParameterValue(args, "plugin") + if userPluginName == "" { + userPluginName = getFirstServiceGeneratorName() + } + + userPlugin := getCodeGenerator(userPluginName) + if userPlugin == nil { + log.Print("protoc-gen-plugin: registor plugins:", getAllServiceGeneratorNames()) + g.Fail("invalid plugin option:", userPluginName) + } + + return userPlugin +} + +func pkgGetParameterValue(parameter, key string) string { + for _, p := range strings.Split(parameter, ",") { + if i := strings.Index(p, "="); i > 0 { + if p[0:i] == key { + return p[i+1:] + } + } + } + return "" +} diff --git a/core/protorpc/protoc-gen-plugin/main_plugin.go b/core/protorpc/protoc-gen-plugin/main_plugin.go new file mode 100644 index 0000000..829158f --- /dev/null +++ b/core/protorpc/protoc-gen-plugin/main_plugin.go @@ -0,0 +1,119 @@ +// Copyright 2017 . All rights reserved. +// Use of this source code is governed by a Apache +// license that can be found in the LICENSE file. + +package plugin + +import ( + "bytes" + "fmt" + "go/format" + "path" + "strings" + + "github.com/golang/protobuf/proto" + "github.com/golang/protobuf/protoc-gen-go/generator" + plugin "github.com/golang/protobuf/protoc-gen-go/plugin" +) + +// mainPlugin produce the Service interface. +type mainPlugin struct { + *generator.Generator + CodeGenerator +} + +// Name returns the name of the plugin. +func (p *mainPlugin) Name() string { return "main-plugin" } + +// Init is called once after data structures are built but before +// code generation begins. +func (p *mainPlugin) Init(g *generator.Generator) { + p.Generator = g +} + +func (p *mainPlugin) InitService(g CodeGenerator) { + p.CodeGenerator = g +} + +// Generate produces the code generated by the plugin for this file. +func (p *mainPlugin) GenerateImports(file *generator.FileDescriptor) { + // skip +} + +// Generate generates the Service interface. +// rpc service can't handle other proto message!!! +func (p *mainPlugin) Generate(file *generator.FileDescriptor) { + if !p.isFileNeedGenerate(file) { + return + } + + var buf bytes.Buffer + fmt.Fprintln(&buf, p.HeaderCode(p.Generator, file)) + + for _, msg := range file.MessageType { + fmt.Fprintln(&buf, p.MessageCode(p.Generator, file, msg)) + } + + for _, svc := range file.Service { + fmt.Fprintln(&buf, p.ServiceCode(p.Generator, file, svc)) + } + + fileContent := buf.String() + if code, err := format.Source(buf.Bytes()); err == nil { + fileContent = string(code) + } + + p.Generator.Response.File = append(p.Generator.Response.File, &plugin.CodeGeneratorResponse_File{ + Name: proto.String(p.goFileName(file)), + Content: proto.String(fileContent), + }) +} + +func (p *mainPlugin) isFileNeedGenerate(file *generator.FileDescriptor) bool { + for _, v := range p.Generator.Request.FileToGenerate { + if v == file.GetName() { + return true + } + } + return false +} + +func (p *mainPlugin) goFileName(file *generator.FileDescriptor) string { + name := *file.Name + if ext := path.Ext(name); ext == ".proto" || ext == ".protodevel" { + name = name[:len(name)-len(ext)] + } + name += p.FileNameExt() + + // Does the file have a "go_package" option? + // If it does, it may override the filename. + if impPath, _, ok := p.goPackageOption(file); ok && impPath != "" { + // Replace the existing dirname with the declared import path. + _, name = path.Split(name) + name = path.Join(impPath, name) + return name + } + + return name +} + +func (p *mainPlugin) goPackageOption(file *generator.FileDescriptor) (impPath, pkg string, ok bool) { + pkg = file.GetOptions().GetGoPackage() + if pkg == "" { + return + } + ok = true + // The presence of a slash implies there's an import path. + slash := strings.LastIndex(pkg, "/") + if slash < 0 { + return + } + impPath, pkg = pkg, pkg[slash+1:] + // A semicolon-delimited suffix overrides the package name. + sc := strings.IndexByte(impPath, ';') + if sc < 0 { + return + } + impPath, pkg = impPath[:sc], impPath[sc+1:] + return +} diff --git a/core/protorpc/protoc-gen-protorpc/env.go b/core/protorpc/protoc-gen-protorpc/env.go new file mode 100644 index 0000000..2362326 --- /dev/null +++ b/core/protorpc/protoc-gen-protorpc/env.go @@ -0,0 +1,7 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +const ENV_PROTOC_GEN_PROTORPC_FLAG_PREFIX = "ENV_PROTOC_GEN_PROTORPC_FLAG_PREFIX" diff --git a/core/protorpc/protoc-gen-protorpc/main.go b/core/protorpc/protoc-gen-protorpc/main.go new file mode 100644 index 0000000..ab15ff4 --- /dev/null +++ b/core/protorpc/protoc-gen-protorpc/main.go @@ -0,0 +1,381 @@ +// Copyright 2018 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "bytes" + "log" + "os" + "text/template" + + plugin "github.com/chai2010/protorpc/protoc-gen-plugin" + "github.com/golang/protobuf/protoc-gen-go/descriptor" + "github.com/golang/protobuf/protoc-gen-go/generator" +) + +var flagPrefix = os.Getenv(ENV_PROTOC_GEN_PROTORPC_FLAG_PREFIX) + +func main() { + plugin.Main() +} + +func init() { + plugin.RegisterCodeGenerator(new(protorpcPlugin)) +} + +type protorpcPlugin struct{} + +func (p *protorpcPlugin) Name() string { return "protorpc-go" } +func (p *protorpcPlugin) FileNameExt() string { return ".pb.protorpc.go" } + +func (p *protorpcPlugin) HeaderCode(g *generator.Generator, file *generator.FileDescriptor) string { + const tmpl = ` +{{- $G := .G -}} +{{- $File := .File -}} + +// Code generated by protoc-gen-protorpc. DO NOT EDIT. +// +// plugin: https://github.com/chai2010/protorpc/tree/master/protoc-gen-plugin +// plugin: https://github.com/chai2010/protorpc/tree/master/protoc-gen-protorpc +// +// source: {{$File.GetName}} + +package {{$File.PackageName}} + +import ( + "fmt" + "io" + "log" + "net" + "net/rpc" + "time" + + "github.com/chai2010/protorpc" + "github.com/golang/protobuf/proto" +) + +var ( + _ = fmt.Sprint + _ = io.Reader(nil) + _ = log.Print + _ = net.Addr(nil) + _ = rpc.Call{} + _ = time.Second + + _ = proto.String + _ = protorpc.Dial +) +` + var buf bytes.Buffer + t := template.Must(template.New("").Parse(tmpl)) + err := t.Execute(&buf, + struct { + G *generator.Generator + File *generator.FileDescriptor + Prefix string + }{ + G: g, + File: file, + Prefix: flagPrefix, + }, + ) + if err != nil { + log.Fatal(err) + } + + return buf.String() +} + +func (p *protorpcPlugin) ServiceCode(g *generator.Generator, file *generator.FileDescriptor, svc *descriptor.ServiceDescriptorProto) string { + var code string + code += p.genServiceInterface(g, file, svc) + code += p.genServiceServer(g, file, svc) + code += p.genServiceClient(g, file, svc) + return code +} + +func (p *protorpcPlugin) MessageCode(g *generator.Generator, file *generator.FileDescriptor, msg *descriptor.DescriptorProto) string { + return "" +} + +func (p *protorpcPlugin) genServiceInterface( + g *generator.Generator, + file *generator.FileDescriptor, + svc *descriptor.ServiceDescriptorProto, +) string { + const serviceInterfaceTmpl = ` +type {{.Prefix}}{{.ServiceName}} interface { + {{.CallMethodList}} +} +` + const callMethodTmpl = ` +{{.MethodName}}(in *{{.ArgsType}}, out *{{.ReplyType}}) error` + + // gen call method list + var callMethodList string + for _, m := range svc.Method { + out := bytes.NewBuffer([]byte{}) + t := template.Must(template.New("").Parse(callMethodTmpl)) + t.Execute(out, &struct { + Prefix string + ServiceName string + MethodName string + ArgsType string + ReplyType string + }{ + Prefix: flagPrefix, + ServiceName: generator.CamelCase(svc.GetName()), + MethodName: generator.CamelCase(m.GetName()), + ArgsType: g.TypeName(g.ObjectNamed(m.GetInputType())), + ReplyType: g.TypeName(g.ObjectNamed(m.GetOutputType())), + }) + callMethodList += out.String() + + g.RecordTypeUse(m.GetInputType()) + g.RecordTypeUse(m.GetOutputType()) + } + + // gen all interface code + { + out := bytes.NewBuffer([]byte{}) + t := template.Must(template.New("").Parse(serviceInterfaceTmpl)) + t.Execute(out, &struct { + Prefix string + ServiceName string + CallMethodList string + }{ + Prefix: flagPrefix, + ServiceName: generator.CamelCase(svc.GetName()), + CallMethodList: callMethodList, + }) + + return out.String() + } +} + +func (p *protorpcPlugin) genServiceServer( + g *generator.Generator, + file *generator.FileDescriptor, + svc *descriptor.ServiceDescriptorProto, +) string { + const serviceHelperFunTmpl = ` +// {{.Prefix}}Accept{{.ServiceName}}Client accepts connections on the listener and serves requests +// for each incoming connection. Accept blocks; the caller typically +// invokes it in a go statement. +func {{.Prefix}}Accept{{.ServiceName}}Client(lis net.Listener, x {{.Prefix}}{{.ServiceName}}) { + srv := rpc.NewServer() + if err := srv.RegisterName("{{.ServiceRegisterName}}", x); err != nil { + log.Fatal(err) + } + + for { + conn, err := lis.Accept() + if err != nil { + log.Fatalf("lis.Accept(): %v\n", err) + } + go srv.ServeCodec(protorpc.NewServerCodec(conn)) + } +} + +// {{.Prefix}}Register{{.ServiceName}} publish the given {{.Prefix}}{{.ServiceName}} implementation on the server. +func {{.Prefix}}Register{{.ServiceName}}(srv *rpc.Server, x {{.Prefix}}{{.ServiceName}}) error { + if err := srv.RegisterName("{{.ServiceRegisterName}}", x); err != nil { + return err + } + return nil +} + +// {{.Prefix}}New{{.ServiceName}}Server returns a new {{.Prefix}}{{.ServiceName}} Server. +func {{.Prefix}}New{{.ServiceName}}Server(x {{.Prefix}}{{.ServiceName}}) *rpc.Server { + srv := rpc.NewServer() + if err := srv.RegisterName("{{.ServiceRegisterName}}", x); err != nil { + log.Fatal(err) + } + return srv +} + +// {{.Prefix}}ListenAndServe{{.ServiceName}} listen announces on the local network address laddr +// and serves the given {{.ServiceName}} implementation. +func {{.Prefix}}ListenAndServe{{.ServiceName}}(network, addr string, x {{.Prefix}}{{.ServiceName}}) error { + lis, err := net.Listen(network, addr) + if err != nil { + return err + } + defer lis.Close() + + srv := rpc.NewServer() + if err := srv.RegisterName("{{.ServiceRegisterName}}", x); err != nil { + return err + } + + for { + conn, err := lis.Accept() + if err != nil { + log.Fatalf("lis.Accept(): %v\n", err) + } + go srv.ServeCodec(protorpc.NewServerCodec(conn)) + } +} + +// {{.Prefix}}Serve{{.ServiceName}} serves the given {{.Prefix}}{{.ServiceName}} implementation. +func {{.Prefix}}Serve{{.ServiceName}}(conn io.ReadWriteCloser, x {{.Prefix}}{{.ServiceName}}) { + srv := rpc.NewServer() + if err := srv.RegisterName("{{.ServiceRegisterName}}", x); err != nil { + log.Fatal(err) + } + srv.ServeCodec(protorpc.NewServerCodec(conn)) +} +` + { + out := bytes.NewBuffer([]byte{}) + t := template.Must(template.New("").Parse(serviceHelperFunTmpl)) + t.Execute(out, &struct { + Prefix string + PackageName string + ServiceName string + ServiceRegisterName string + }{ + Prefix: flagPrefix, + PackageName: file.GetPackage(), + ServiceName: generator.CamelCase(svc.GetName()), + ServiceRegisterName: p.makeServiceRegisterName( + file, file.GetPackage(), generator.CamelCase(svc.GetName()), + ), + }) + + return out.String() + } +} + +func (p *protorpcPlugin) genServiceClient( + g *generator.Generator, + file *generator.FileDescriptor, + svc *descriptor.ServiceDescriptorProto, +) string { + const clientHelperFuncTmpl = ` +type {{.Prefix}}{{.ServiceName}}Client struct { + *rpc.Client +} + +// {{.Prefix}}New{{.ServiceName}}Client returns a {{.Prefix}}{{.ServiceName}} stub to handle +// requests to the set of {{.Prefix}}{{.ServiceName}} at the other end of the connection. +func {{.Prefix}}New{{.ServiceName}}Client(conn io.ReadWriteCloser) (*{{.Prefix}}{{.ServiceName}}Client) { + c := rpc.NewClientWithCodec(protorpc.NewClientCodec(conn)) + return &{{.Prefix}}{{.ServiceName}}Client{c} +} + +{{.MethodList}} + +// {{.Prefix}}Dial{{.ServiceName}} connects to an {{.Prefix}}{{.ServiceName}} at the specified network address. +func {{.Prefix}}Dial{{.ServiceName}}(network, addr string) (*{{.Prefix}}{{.ServiceName}}Client, error) { + c, err := protorpc.Dial(network, addr) + if err != nil { + return nil, err + } + return &{{.Prefix}}{{.ServiceName}}Client{c}, nil +} + +// {{.Prefix}}Dial{{.ServiceName}}Timeout connects to an {{.Prefix}}{{.ServiceName}} at the specified network address. +func {{.Prefix}}Dial{{.ServiceName}}Timeout(network, addr string, timeout time.Duration) (*{{.Prefix}}{{.ServiceName}}Client, error) { + c, err := protorpc.DialTimeout(network, addr, timeout) + if err != nil { + return nil, err + } + return &{{.Prefix}}{{.ServiceName}}Client{c}, nil +} +` + const clientMethodTmpl = ` +func (c *{{.Prefix}}{{.ServiceName}}Client) {{.MethodName}}(in *{{.ArgsType}}) (out *{{.ReplyType}}, err error) { + if in == nil { + in = new({{.ArgsType}}) + } + + type Validator interface { + Validate() error + } + if x, ok := proto.Message(in).(Validator); ok { + if err := x.Validate(); err != nil { + return nil, err + } + } + + out = new({{.ReplyType}}) + if err = c.Call("{{.ServiceRegisterName}}.{{.MethodName}}", in, out); err != nil { + return nil, err + } + + if x, ok := proto.Message(out).(Validator); ok { + if err := x.Validate(); err != nil { + return out, err + } + } + + return out, nil +} + +func (c *{{.Prefix}}{{.ServiceName}}Client) Async{{.MethodName}}(in *{{.ArgsType}}, out *{{.ReplyType}}, done chan *rpc.Call) *rpc.Call { + if in == nil { + in = new({{.ArgsType}}) + } + return c.Go( + "{{.ServiceRegisterName}}.{{.MethodName}}", + in, out, + done, + ) +} +` + + // gen client method list + var methodList string + for _, m := range svc.Method { + out := bytes.NewBuffer([]byte{}) + t := template.Must(template.New("").Parse(clientMethodTmpl)) + t.Execute(out, &struct { + Prefix string + ServiceName string + ServiceRegisterName string + MethodName string + ArgsType string + ReplyType string + }{ + Prefix: flagPrefix, + ServiceName: generator.CamelCase(svc.GetName()), + ServiceRegisterName: p.makeServiceRegisterName( + file, file.GetPackage(), generator.CamelCase(svc.GetName()), + ), + MethodName: generator.CamelCase(m.GetName()), + ArgsType: g.TypeName(g.ObjectNamed(m.GetInputType())), + ReplyType: g.TypeName(g.ObjectNamed(m.GetOutputType())), + }) + methodList += out.String() + } + + // gen all client code + { + out := bytes.NewBuffer([]byte{}) + t := template.Must(template.New("").Parse(clientHelperFuncTmpl)) + t.Execute(out, &struct { + Prefix string + PackageName string + ServiceName string + MethodList string + }{ + Prefix: flagPrefix, + PackageName: file.GetPackage(), + ServiceName: generator.CamelCase(svc.GetName()), + MethodList: methodList, + }) + + return out.String() + } +} + +func (p *protorpcPlugin) makeServiceRegisterName( + file *generator.FileDescriptor, + packageName, serviceName string, +) string { + // return packageName + "." + serviceName + return serviceName +} diff --git a/core/protorpc/protoc-gen-stdrpc/_main-ignore.go b/core/protorpc/protoc-gen-stdrpc/_main-ignore.go new file mode 100644 index 0000000..a16035e --- /dev/null +++ b/core/protorpc/protoc-gen-stdrpc/_main-ignore.go @@ -0,0 +1,342 @@ +// Copyright 2018 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "bytes" + "log" + "text/template" + + plugin "github.com/chai2010/protorpc/protoc-gen-plugin" + "github.com/golang/protobuf/protoc-gen-go/descriptor" + "github.com/golang/protobuf/protoc-gen-go/generator" +) + +func main() { + plugin.Main() +} + +func init() { + plugin.RegisterCodeGenerator(new(protorpcPlugin)) +} + +type protorpcPlugin struct{} + +func (p *protorpcPlugin) Name() string { return "stdrpc-go" } +func (p *protorpcPlugin) FileNameExt() string { return ".pb.stdrpc.go" } + +func (p *protorpcPlugin) HeaderCode(g *generator.Generator, file *generator.FileDescriptor) string { + const tmpl = ` +{{- $G := .G -}} +{{- $File := .File -}} + +// Code generated by protoc-gen-stdrpc. DO NOT EDIT. +// +// plugin: https://github.com/chai2010/protorpc/tree/master/protoc-gen-plugin +// plugin: https://github.com/chai2010/protorpc/tree/master/protoc-gen-stdrpc +// +// source: {{$File.GetName}} + +package {{$File.PackageName}} + +import ( + "fmt" + "io" + "log" + "net" + "net/rpc" + "time" + + "github.com/golang/protobuf/proto" +) + +var ( + _ = fmt.Sprint + _ = io.Reader(nil) + _ = log.Print + _ = net.Addr(nil) + _ = rpc.Call{} + _ = time.Second + + _ = proto.String +) +` + var buf bytes.Buffer + t := template.Must(template.New("").Parse(tmpl)) + err := t.Execute(&buf, + struct { + G *generator.Generator + File *generator.FileDescriptor + }{ + G: g, + File: file, + }, + ) + if err != nil { + log.Fatal(err) + } + + return buf.String() +} + +func (p *protorpcPlugin) ServiceCode(g *generator.Generator, file *generator.FileDescriptor, svc *descriptor.ServiceDescriptorProto) string { + var code string + code += p.genServiceInterface(g, file, svc) + code += p.genServiceServer(g, file, svc) + code += p.genServiceClient(g, file, svc) + return code +} + +func (p *protorpcPlugin) MessageCode(g *generator.Generator, file *generator.FileDescriptor, msg *descriptor.DescriptorProto) string { + return "" +} + +func (p *protorpcPlugin) genServiceInterface( + g *generator.Generator, + file *generator.FileDescriptor, + svc *descriptor.ServiceDescriptorProto, +) string { + const serviceInterfaceTmpl = ` +type {{.ServiceName}} interface { + {{.CallMethodList}} +} +` + const callMethodTmpl = ` +{{.MethodName}}(in *{{.ArgsType}}, out *{{.ReplyType}}) error` + + // gen call method list + var callMethodList string + for _, m := range svc.Method { + out := bytes.NewBuffer([]byte{}) + t := template.Must(template.New("").Parse(callMethodTmpl)) + t.Execute(out, &struct{ ServiceName, MethodName, ArgsType, ReplyType string }{ + ServiceName: generator.CamelCase(svc.GetName()), + MethodName: generator.CamelCase(m.GetName()), + ArgsType: g.TypeName(g.ObjectNamed(m.GetInputType())), + ReplyType: g.TypeName(g.ObjectNamed(m.GetOutputType())), + }) + callMethodList += out.String() + + g.RecordTypeUse(m.GetInputType()) + g.RecordTypeUse(m.GetOutputType()) + } + + // gen all interface code + { + out := bytes.NewBuffer([]byte{}) + t := template.Must(template.New("").Parse(serviceInterfaceTmpl)) + t.Execute(out, &struct{ ServiceName, CallMethodList string }{ + ServiceName: generator.CamelCase(svc.GetName()), + CallMethodList: callMethodList, + }) + + return out.String() + } +} + +func (p *protorpcPlugin) genServiceServer( + g *generator.Generator, + file *generator.FileDescriptor, + svc *descriptor.ServiceDescriptorProto, +) string { + const serviceHelperFunTmpl = ` +// Accept{{.ServiceName}}Client accepts connections on the listener and serves requests +// for each incoming connection. Accept blocks; the caller typically +// invokes it in a go statement. +func Accept{{.ServiceName}}Client(lis net.Listener, x {{.ServiceName}}) { + srv := rpc.NewServer() + if err := srv.RegisterName("{{.ServiceRegisterName}}", x); err != nil { + log.Fatal(err) + } + + for { + conn, err := lis.Accept() + if err != nil { + log.Fatalf("lis.Accept(): %v\n", err) + } + go srv.ServeConn(conn) + } +} + +// Register{{.ServiceName}} publish the given {{.ServiceName}} implementation on the server. +func Register{{.ServiceName}}(srv *rpc.Server, x {{.ServiceName}}) error { + if err := srv.RegisterName("{{.ServiceRegisterName}}", x); err != nil { + return err + } + return nil +} + +// New{{.ServiceName}}Server returns a new {{.ServiceName}} Server. +func New{{.ServiceName}}Server(x {{.ServiceName}}) *rpc.Server { + srv := rpc.NewServer() + if err := srv.RegisterName("{{.ServiceRegisterName}}", x); err != nil { + log.Fatal(err) + } + return srv +} + +// ListenAndServe{{.ServiceName}} listen announces on the local network address laddr +// and serves the given {{.ServiceName}} implementation. +func ListenAndServe{{.ServiceName}}(network, addr string, x {{.ServiceName}}) error { + lis, err := net.Listen(network, addr) + if err != nil { + return err + } + defer lis.Close() + + srv := rpc.NewServer() + if err := srv.RegisterName("{{.ServiceRegisterName}}", x); err != nil { + return err + } + + for { + conn, err := lis.Accept() + if err != nil { + log.Fatalf("lis.Accept(): %v\n", err) + } + go srv.ServeConn(conn) + } +} + +// Serve{{.ServiceName}} serves the given {{.ServiceName}} implementation. +func Serve{{.ServiceName}}(conn io.ReadWriteCloser, x {{.ServiceName}}) { + srv := rpc.NewServer() + if err := srv.RegisterName("{{.ServiceRegisterName}}", x); err != nil { + log.Fatal(err) + } + srv.ServeConn(conn) +} +` + { + out := bytes.NewBuffer([]byte{}) + t := template.Must(template.New("").Parse(serviceHelperFunTmpl)) + t.Execute(out, &struct{ PackageName, ServiceName, ServiceRegisterName string }{ + PackageName: file.GetPackage(), + ServiceName: generator.CamelCase(svc.GetName()), + ServiceRegisterName: p.makeServiceRegisterName( + file, file.GetPackage(), generator.CamelCase(svc.GetName()), + ), + }) + + return out.String() + } +} + +func (p *protorpcPlugin) genServiceClient( + g *generator.Generator, + file *generator.FileDescriptor, + svc *descriptor.ServiceDescriptorProto, +) string { + const clientHelperFuncTmpl = ` +type {{.ServiceName}}Client struct { + *rpc.Client +} + +// New{{.ServiceName}}Client returns a {{.ServiceName}} stub to handle +// requests to the set of {{.ServiceName}} at the other end of the connection. +func New{{.ServiceName}}Client(conn io.ReadWriteCloser) (*{{.ServiceName}}Client) { + c := rpc.NewClient(conn) + return &{{.ServiceName}}Client{c} +} + +{{.MethodList}} + +// Dial{{.ServiceName}} connects to an {{.ServiceName}} at the specified network address. +func Dial{{.ServiceName}}(network, addr string) (*{{.ServiceName}}Client, error) { + c, err := rpc.Dial(network, addr) + if err != nil { + return nil, err + } + return &{{.ServiceName}}Client{c}, nil +} + +// Dial{{.ServiceName}}Timeout connects to an {{.ServiceName}} at the specified network address. +func Dial{{.ServiceName}}Timeout(network, addr string, timeout time.Duration) (*{{.ServiceName}}Client, error) { + conn, err := net.DialTimeout(network, addr, timeout) + if err != nil { + return nil, err + } + return &{{.ServiceName}}Client{rpc.NewClient(conn)}, nil +} +` + const clientMethodTmpl = ` +func (c *{{.ServiceName}}Client) {{.MethodName}}(in *{{.ArgsType}}) (out *{{.ReplyType}}, err error) { + if in == nil { + in = new({{.ArgsType}}) + } + + type Validator interface { + Validate() error + } + if x, ok := proto.Message(in).(Validator); ok { + if err := x.Validate(); err != nil { + return nil, err + } + } + + out = new({{.ReplyType}}) + if err = c.Call("{{.ServiceRegisterName}}.{{.MethodName}}", in, out); err != nil { + return nil, err + } + + if x, ok := proto.Message(out).(Validator); ok { + if err := x.Validate(); err != nil { + return out, err + } + } + + return out, nil +} + +func (c *{{.ServiceName}}Client) Async{{.MethodName}}(in *{{.ArgsType}}, out *{{.ReplyType}}, done chan *rpc.Call) *rpc.Call { + if in == nil { + in = new({{.ArgsType}}) + } + return c.Go( + "{{.ServiceRegisterName}}.{{.MethodName}}", + in, out, + done, + ) +} +` + + // gen client method list + var methodList string + for _, m := range svc.Method { + out := bytes.NewBuffer([]byte{}) + t := template.Must(template.New("").Parse(clientMethodTmpl)) + t.Execute(out, &struct{ ServiceName, ServiceRegisterName, MethodName, ArgsType, ReplyType string }{ + ServiceName: generator.CamelCase(svc.GetName()), + ServiceRegisterName: p.makeServiceRegisterName( + file, file.GetPackage(), generator.CamelCase(svc.GetName()), + ), + MethodName: generator.CamelCase(m.GetName()), + ArgsType: g.TypeName(g.ObjectNamed(m.GetInputType())), + ReplyType: g.TypeName(g.ObjectNamed(m.GetOutputType())), + }) + methodList += out.String() + } + + // gen all client code + { + out := bytes.NewBuffer([]byte{}) + t := template.Must(template.New("").Parse(clientHelperFuncTmpl)) + t.Execute(out, &struct{ PackageName, ServiceName, MethodList string }{ + PackageName: file.GetPackage(), + ServiceName: generator.CamelCase(svc.GetName()), + MethodList: methodList, + }) + + return out.String() + } +} + +func (p *protorpcPlugin) makeServiceRegisterName( + file *generator.FileDescriptor, + packageName, serviceName string, +) string { + // return packageName + "." + serviceName + return serviceName +} diff --git a/core/protorpc/protoc-gen-stdrpc/main.go b/core/protorpc/protoc-gen-stdrpc/main.go new file mode 100644 index 0000000..c5d44fe --- /dev/null +++ b/core/protorpc/protoc-gen-stdrpc/main.go @@ -0,0 +1,103 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// protoc-gen-go is a plugin for the Google protocol buffer compiler to generate +// Go code. Run it by building this program and putting it in your path with +// the name +// protoc-gen-go +// That word 'go' at the end becomes part of the option string set for the +// protocol compiler, so once the protocol compiler (protoc) is installed +// you can run +// protoc --go_out=output_directory input_directory/file.proto +// to generate Go bindings for the protocol defined by file.proto. +// With that input, the output will be written to +// output_directory/file.pb.go +// +// The generated code is documented in the package comment for +// the library. +// +// See the README and documentation for protocol buffers to learn more: +// https://developers.google.com/protocol-buffers/ +package main + +import ( + "io/ioutil" + "os" + "strings" + + "github.com/golang/protobuf/proto" + "github.com/golang/protobuf/protoc-gen-go/generator" +) + +func main() { + // Begin by allocating a generator. The request and response structures are stored there + // so we can do error handling easily - the response structure contains the field to + // report failure. + g := generator.New() + + data, err := ioutil.ReadAll(os.Stdin) + if err != nil { + g.Error(err, "reading input") + } + + if err := proto.Unmarshal(data, g.Request); err != nil { + g.Error(err, "parsing input proto") + } + + if len(g.Request.FileToGenerate) == 0 { + g.Fail("no files to generate") + } + + parameter := g.Request.GetParameter() + if !strings.Contains(parameter, "plugins=") { + parameter += ",plugins=" + netrpcPluginName + } + g.CommandLineParameters(parameter) + + // Create a wrapped version of the Descriptors and EnumDescriptors that + // point to the file that defines them. + g.WrapTypes() + + g.SetPackageNames() + g.BuildTypeNameMap() + + g.GenerateAllFiles() + + // Send back the results. + data, err = proto.Marshal(g.Response) + if err != nil { + g.Error(err, "failed to marshal output proto") + } + _, err = os.Stdout.Write(data) + if err != nil { + g.Error(err, "failed to write output proto") + } +} diff --git a/core/protorpc/protoc-gen-stdrpc/netrpc.go b/core/protorpc/protoc-gen-stdrpc/netrpc.go new file mode 100644 index 0000000..95ecfa0 --- /dev/null +++ b/core/protorpc/protoc-gen-stdrpc/netrpc.go @@ -0,0 +1,350 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "bytes" + "text/template" + + "github.com/golang/protobuf/protoc-gen-go/descriptor" + "github.com/golang/protobuf/protoc-gen-go/generator" +) + +const netrpcPluginName = "netrpc" + +// netrpcPlugin produce the Service interface. +type netrpcPlugin struct { + *generator.Generator +} + +// Name returns the name of the plugin. +func (p *netrpcPlugin) Name() string { return netrpcPluginName } + +// Init is called once after data structures are built but before +// code generation begins. +func (p *netrpcPlugin) Init(g *generator.Generator) { + p.Generator = g +} + +// Generate produces the code generated by the plugin for this file. +func (p *netrpcPlugin) GenerateImports(file *generator.FileDescriptor) { + if len(file.Service) > 0 { + p.P(`import "bufio"`) + p.P(`import "crypto/tls"`) + p.P(`import "errors"`) + p.P(`import "io"`) + p.P(`import "log"`) + p.P(`import "net"`) + p.P(`import "net/http"`) + p.P(`import "net/rpc"`) + p.P(`import "time"`) + } +} + +// Generate generates the Service interface. +// rpc service can't handle other proto message!!! +func (p *netrpcPlugin) Generate(file *generator.FileDescriptor) { + for _, svc := range file.Service { + p.genServiceInterface(file, svc) + p.genServiceServer(file, svc) + p.genServiceClient(file, svc) + } +} + +func (p *netrpcPlugin) genServiceInterface( + file *generator.FileDescriptor, + svc *descriptor.ServiceDescriptorProto, +) { + const serviceInterfaceTmpl = ` +type {{.ServiceName}} interface { + {{.CallMethodList}} +} +` + const callMethodTmpl = ` +{{.MethodName}}(in *{{.ArgsType}}, out *{{.ReplyType}}) error` + + // gen call method list + var callMethodList string + for _, m := range svc.Method { + out := bytes.NewBuffer([]byte{}) + t := template.Must(template.New("").Parse(callMethodTmpl)) + t.Execute(out, &struct{ ServiceName, MethodName, ArgsType, ReplyType string }{ + ServiceName: generator.CamelCase(svc.GetName()), + MethodName: generator.CamelCase(m.GetName()), + ArgsType: p.TypeName(p.ObjectNamed(m.GetInputType())), + ReplyType: p.TypeName(p.ObjectNamed(m.GetOutputType())), + }) + callMethodList += out.String() + + p.RecordTypeUse(m.GetInputType()) + p.RecordTypeUse(m.GetOutputType()) + } + + // gen all interface code + { + out := bytes.NewBuffer([]byte{}) + t := template.Must(template.New("").Parse(serviceInterfaceTmpl)) + t.Execute(out, &struct{ ServiceName, CallMethodList string }{ + ServiceName: generator.CamelCase(svc.GetName()), + CallMethodList: callMethodList, + }) + p.P(out.String()) + } +} + +func (p *netrpcPlugin) genServiceServer( + file *generator.FileDescriptor, + svc *descriptor.ServiceDescriptorProto, +) { + const serviceHelperFunTmpl = ` +// Accept{{.ServiceName}}Client accepts connections on the listener and serves requests +// for each incoming connection. Accept blocks; the caller typically +// invokes it in a go statement. +func Accept{{.ServiceName}}Client(lis net.Listener, x {{.ServiceName}}) { + srv := rpc.NewServer() + if err := srv.RegisterName("{{.ServiceRegisterName}}", x); err != nil { + log.Fatal(err) + } + + for { + conn, err := lis.Accept() + if err != nil { + log.Fatalf("lis.Accept(): %v\n", err) + } + go srv.ServeConn(conn) + } +} + +// Register{{.ServiceName}} publish the given {{.ServiceName}} implementation on the server. +func Register{{.ServiceName}}(srv *rpc.Server, x {{.ServiceName}}) error { + if err := srv.RegisterName("{{.ServiceRegisterName}}", x); err != nil { + return err + } + return nil +} + +// New{{.ServiceName}}Server returns a new {{.ServiceName}} Server. +func New{{.ServiceName}}Server(x {{.ServiceName}}) *rpc.Server { + srv := rpc.NewServer() + if err := srv.RegisterName("{{.ServiceRegisterName}}", x); err != nil { + log.Fatal(err) + } + return srv +} + +// ListenAndServe{{.ServiceName}} listen announces on the local network address laddr +// and serves the given {{.ServiceName}} implementation. +func ListenAndServe{{.ServiceName}}(network, addr string, x {{.ServiceName}}) error { + lis, err := net.Listen(network, addr) + if err != nil { + return err + } + defer lis.Close() + + srv := rpc.NewServer() + if err := srv.RegisterName("{{.ServiceRegisterName}}", x); err != nil { + return err + } + + for { + conn, err := lis.Accept() + if err != nil { + log.Fatalf("lis.Accept(): %v\n", err) + } + go srv.ServeConn(conn) + } +} + +// Serve{{.ServiceName}} serves the given {{.ServiceName}} implementation. +func Serve{{.ServiceName}}(conn io.ReadWriteCloser, x {{.ServiceName}}) { + srv := rpc.NewServer() + if err := srv.RegisterName("{{.ServiceRegisterName}}", x); err != nil { + log.Fatal(err) + } + srv.ServeConn(conn) +} +` + { + out := bytes.NewBuffer([]byte{}) + t := template.Must(template.New("").Parse(serviceHelperFunTmpl)) + t.Execute(out, &struct{ PackageName, ServiceName, ServiceRegisterName string }{ + PackageName: file.GetPackage(), + ServiceName: generator.CamelCase(svc.GetName()), + ServiceRegisterName: p.makeServiceRegisterName( + file, file.GetPackage(), generator.CamelCase(svc.GetName()), + ), + }) + p.P(out.String()) + } +} + +func (p *netrpcPlugin) genServiceClient( + file *generator.FileDescriptor, + svc *descriptor.ServiceDescriptorProto, +) { + const clientHelperFuncTmpl = ` +type {{.ServiceName}}Client struct { + *rpc.Client +} + +// New{{.ServiceName}}Client returns a {{.ServiceName}} stub to handle +// requests to the set of {{.ServiceName}} at the other end of the connection. +func New{{.ServiceName}}Client(conn io.ReadWriteCloser) (*{{.ServiceName}}Client) { + c := rpc.NewClient(conn) + return &{{.ServiceName}}Client{c} +} + +{{.MethodList}} + +// Dial{{.ServiceName}} connects to an {{.ServiceName}} at the specified network address. +func Dial{{.ServiceName}}(network, addr string) (*{{.ServiceName}}Client, error) { + c, err := rpc.Dial(network, addr) + if err != nil { + return nil, err + } + return &{{.ServiceName}}Client{c}, nil +} + +// Dial{{.ServiceName}}Timeout connects to an {{.ServiceName}} at the specified network address. +func Dial{{.ServiceName}}Timeout(network, addr string, timeout time.Duration) (*{{.ServiceName}}Client, error) { + conn, err := net.DialTimeout(network, addr, timeout) + if err != nil { + return nil, err + } + return &{{.ServiceName}}Client{rpc.NewClient(conn)}, nil +} + +// Dial{{.ServiceName}}HTTP connects to an HTTP RPC server at the specified network address +// listening on the default HTTP RPC path. +func Dial{{.ServiceName}}HTTP(network, address string) (*{{.ServiceName}}Client, error) { + return Dial{{.ServiceName}}HTTPPath(network, address, rpc.DefaultRPCPath) +} + +// Dial{{.ServiceName}}HTTPPath connects to an HTTP RPC server +// at the specified network address and path. +func Dial{{.ServiceName}}HTTPPath(network, address, path string) (*{{.ServiceName}}Client, error) { + conn, err := net.Dial(network, address) + if err != nil { + return nil, err + } + return dial{{.ServiceName}}Path(network, address, path, conn) +} + +// Dial{{.ServiceName}}HTTPS connects to an HTTPS RPC server at the specified network address +// listening on the default HTTP RPC path. +func Dial{{.ServiceName}}HTTPS(network, address string, tlsConfig *tls.Config) (*{{.ServiceName}}Client, error) { + return Dial{{.ServiceName}}HTTPSPath(network, address, rpc.DefaultRPCPath, tlsConfig) +} + +// Dial{{.ServiceName}}HTTPSPath connects to an HTTPS RPC server +// at the specified network address and path. +func Dial{{.ServiceName}}HTTPSPath(network, address, path string, tlsConfig *tls.Config) (*{{.ServiceName}}Client, error) { + conn, err := tls.Dial(network, address, tlsConfig) + if err != nil { + return nil, err + } + return dial{{.ServiceName}}Path(network, address, path, conn) +} + +func dial{{.ServiceName}}Path(network, address, path string, conn net.Conn) (*{{.ServiceName}}Client, error) { + const net_rpc_connected = "200 Connected to Go RPC" + + io.WriteString(conn, "CONNECT "+path+" HTTP/1.0\n\n") + + // Require successful HTTP response + // before switching to RPC protocol. + resp, err := http.ReadResponse(bufio.NewReader(conn), &http.Request{Method: "CONNECT"}) + if err == nil && resp.Status == net_rpc_connected { + return &{{.ServiceName}}Client{rpc.NewClient(conn)}, nil + } + if err == nil { + err = errors.New("unexpected HTTP response: " + resp.Status) + } + conn.Close() + return nil, &net.OpError{ + Op: "dial-http", + Net: network + " " + address, + Addr: nil, + Err: err, + } +} +` + const clientMethodTmpl = ` +func (c *{{.ServiceName}}Client) {{.MethodName}}(in *{{.ArgsType}}) (out *{{.ReplyType}}, err error) { + if in == nil { + in = new({{.ArgsType}}) + } + type Validator interface { + Validate() error + } + if x, ok := proto.Message(in).(Validator); ok { + if err := x.Validate(); err != nil { + return nil, err + } + } + out = new({{.ReplyType}}) + if err = c.Call("{{.ServiceRegisterName}}.{{.MethodName}}", in, out); err != nil { + return nil, err + } + if x, ok := proto.Message(out).(Validator); ok { + if err := x.Validate(); err != nil { + return out, err + } + } + return out, nil +} + +func (c *{{.ServiceName}}Client) Async{{.MethodName}}(in *{{.ArgsType}}, out *{{.ReplyType}}, done chan *rpc.Call) *rpc.Call { + if in == nil { + in = new({{.ArgsType}}) + } + return c.Go( + "{{.ServiceRegisterName}}.{{.MethodName}}", + in, out, + done, + ) +} +` + + // gen client method list + var methodList string + for _, m := range svc.Method { + out := bytes.NewBuffer([]byte{}) + t := template.Must(template.New("").Parse(clientMethodTmpl)) + t.Execute(out, &struct{ ServiceName, ServiceRegisterName, MethodName, ArgsType, ReplyType string }{ + ServiceName: generator.CamelCase(svc.GetName()), + ServiceRegisterName: p.makeServiceRegisterName( + file, file.GetPackage(), generator.CamelCase(svc.GetName()), + ), + MethodName: generator.CamelCase(m.GetName()), + ArgsType: p.TypeName(p.ObjectNamed(m.GetInputType())), + ReplyType: p.TypeName(p.ObjectNamed(m.GetOutputType())), + }) + methodList += out.String() + } + + // gen all client code + { + out := bytes.NewBuffer([]byte{}) + t := template.Must(template.New("").Parse(clientHelperFuncTmpl)) + t.Execute(out, &struct{ PackageName, ServiceName, MethodList string }{ + PackageName: file.GetPackage(), + ServiceName: generator.CamelCase(svc.GetName()), + MethodList: methodList, + }) + p.P(out.String()) + } +} + +func (p *netrpcPlugin) makeServiceRegisterName( + file *generator.FileDescriptor, + packageName, serviceName string, +) string { + return packageName + "." + serviceName +} + +func init() { + generator.RegisterPlugin(new(netrpcPlugin)) +} diff --git a/core/protorpc/rpc_test.go b/core/protorpc/rpc_test.go new file mode 100644 index 0000000..5bdf3ba --- /dev/null +++ b/core/protorpc/rpc_test.go @@ -0,0 +1,256 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package protorpc_test + +import ( + "errors" + "log" + "net" + "net/rpc" + "testing" + "time" + + "github.com/chai2010/protorpc" + msg "github.com/chai2010/protorpc/examples/message.pb" +) + +type Arith int + +func (t *Arith) Add(args *msg.ArithRequest, reply *msg.ArithResponse) error { + reply.C = args.A + args.B + log.Printf("Arith.Add(%v, %v): %v", args.A, args.B, reply.C) + return nil +} + +func (t *Arith) Mul(args *msg.ArithRequest, reply *msg.ArithResponse) error { + reply.C = args.A * args.B + return nil +} + +func (t *Arith) Div(args *msg.ArithRequest, reply *msg.ArithResponse) error { + if args.B == 0 { + return errors.New("divide by zero") + } + reply.C = args.A / args.B + return nil +} + +func (t *Arith) Error(args *msg.ArithRequest, reply *msg.ArithResponse) error { + return errors.New("ArithError") +} + +type Echo int + +func (t *Echo) Echo(args *msg.EchoRequest, reply *msg.EchoResponse) error { + reply.Msg = args.Msg + return nil +} + +func TestInternalMessagePkg(t *testing.T) { + err := listenAndServeArithAndEchoService("tcp", "127.0.0.1:1414") + if err != nil { + log.Fatalf("listenAndServeArithAndEchoService: %v", err) + } + + conn, err := net.Dial("tcp", "127.0.0.1:1414") + if err != nil { + t.Fatalf(`net.Dial("tcp", "127.0.0.1:1414"): %v`, err) + } + client := rpc.NewClientWithCodec(protorpc.NewClientCodec(conn)) + defer client.Close() + + testArithClient(t, client) + testEchoClient(t, client) + + testArithClientAsync(t, client) + testEchoClientAsync(t, client) +} + +func listenAndServeArithAndEchoService(network, addr string) error { + clients, err := net.Listen(network, addr) + if err != nil { + return err + } + srv := rpc.NewServer() + if err := srv.RegisterName("ArithService", new(Arith)); err != nil { + return err + } + if err := srv.RegisterName("EchoService", new(Echo)); err != nil { + return err + } + go func() { + for { + conn, err := clients.Accept() + if err != nil { + log.Printf("clients.Accept(): %v\n", err) + continue + } + go srv.ServeCodec(protorpc.NewServerCodec(conn)) + } + }() + return nil +} + +func testArithClient(t *testing.T, client *rpc.Client) { + var args msg.ArithRequest + var reply msg.ArithResponse + var err error + + // Add + args.A = 1 + args.B = 2 + if err = client.Call("ArithService.Add", &args, &reply); err != nil { + t.Fatalf(`arith.Add: %v`, err) + } + if reply.C != 3 { + t.Fatalf(`arith.Add: expected = %d, got = %d`, 3, reply.C) + } + + // Mul + args.A = 2 + args.B = 3 + if err = client.Call("ArithService.Mul", &args, &reply); err != nil { + t.Fatalf(`arith.Mul: %v`, err) + } + if reply.C != 6 { + t.Fatalf(`arith.Mul: expected = %d, got = %d`, 6, reply.C) + } + + // Div + args.A = 13 + args.B = 5 + if err = client.Call("ArithService.Div", &args, &reply); err != nil { + t.Fatalf(`arith.Div: %v`, err) + } + if reply.C != 2 { + t.Fatalf(`arith.Div: expected = %d, got = %d`, 2, reply.C) + } + + // Div zero + args.A = 1 + args.B = 0 + if err = client.Call("ArithService.Div", &args, &reply); err.Error() != "divide by zero" { + t.Fatalf(`arith.Error: expected = "%s", got = "%s"`, "divide by zero", err.Error()) + } + + // Error + args.A = 1 + args.B = 2 + if err = client.Call("ArithService.Error", &args, &reply); err.Error() != "ArithError" { + t.Fatalf(`arith.Error: expected = "%s", got = "%s"`, "ArithError", err.Error()) + } +} + +func testArithClientAsync(t *testing.T, client *rpc.Client) { + done := make(chan *rpc.Call, 16) + callInfoList := []struct { + method string + args *msg.ArithRequest + reply *msg.ArithResponse + err error + }{ + { + "ArithService.Add", + &msg.ArithRequest{A: 1, B: 2}, + &msg.ArithResponse{C: 3}, + nil, + }, + { + "ArithService.Mul", + &msg.ArithRequest{A: 2, B: 3}, + &msg.ArithResponse{C: 6}, + nil, + }, + { + "ArithService.Div", + &msg.ArithRequest{A: 13, B: 5}, + &msg.ArithResponse{C: 2}, + nil, + }, + { + "ArithService.Div", + &msg.ArithRequest{A: 1, B: 0}, + &msg.ArithResponse{}, + errors.New("divide by zero"), + }, + { + "ArithService.Error", + &msg.ArithRequest{A: 1, B: 2}, + &msg.ArithResponse{}, + errors.New("ArithError"), + }, + } + + // GoCall list + calls := make([]*rpc.Call, len(callInfoList)) + for i := 0; i < len(calls); i++ { + calls[i] = client.Go(callInfoList[i].method, + callInfoList[i].args, callInfoList[i].reply, + done, + ) + } + for i := 0; i < len(calls); i++ { + <-calls[i].Done + } + + // check result + for i := 0; i < len(calls); i++ { + if callInfoList[i].err != nil { + if calls[i].Error.Error() != callInfoList[i].err.Error() { + t.Fatalf(`%s: expected %v, Got = %v`, + callInfoList[i].method, + callInfoList[i].err, + calls[i].Error, + ) + } + continue + } + + got := calls[i].Reply.(*msg.ArithResponse).C + expected := callInfoList[i].reply.C + if got != expected { + t.Fatalf(`%v: expected %v, Got = %v`, + callInfoList[i].method, got, expected, + ) + } + } +} + +func testEchoClient(t *testing.T, client *rpc.Client) { + var args msg.EchoRequest + var reply msg.EchoResponse + var err error + + // EchoService.Echo + args.Msg = "Hello, Protobuf-RPC" + if err = client.Call("EchoService.Echo", &args, &reply); err != nil { + t.Fatalf(`EchoService.Echo: %v`, err) + } + if reply.Msg != args.Msg { + t.Fatalf(`EchoService.Echo: expected = "%s", got = "%s"`, args.Msg, reply.Msg) + } +} + +func testEchoClientAsync(t *testing.T, client *rpc.Client) { + // EchoService.Echo + args := &msg.EchoRequest{Msg: "Hello, Protobuf-RPC"} + reply := &msg.EchoResponse{} + echoCall := client.Go("EchoService.Echo", args, reply, nil) + + // sleep 1s + time.Sleep(time.Second) + + // EchoService.Echo reply + echoCall = <-echoCall.Done + if echoCall.Error != nil { + t.Fatalf(`EchoService.Echo: %v`, echoCall.Error) + } + if echoCall.Reply.(*msg.EchoResponse).Msg != args.Msg { + t.Fatalf(`EchoService.Echo: expected = "%s", got = "%s"`, + args.Msg, + echoCall.Reply.(*msg.EchoResponse).Msg, + ) + } +} diff --git a/core/protorpc/server.go b/core/protorpc/server.go new file mode 100644 index 0000000..2097779 --- /dev/null +++ b/core/protorpc/server.go @@ -0,0 +1,134 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package protorpc + +import ( + "errors" + "fmt" + "io" + "net/rpc" + "sync" + + wire "github.com/chai2010/protorpc/wire.pb" + "github.com/golang/protobuf/proto" +) + +type serverCodec struct { + r io.Reader + w io.Writer + c io.Closer + + // temporary work space + reqHeader wire.RequestHeader + + // Package rpc expects uint64 request IDs. + // We assign uint64 sequence numbers to incoming requests + // but save the original request ID in the pending map. + // When rpc responds, we use the sequence number in + // the response to find the original request ID. + mutex sync.Mutex // protects seq, pending + seq uint64 + pending map[uint64]uint64 +} + +// NewServerCodec returns a serverCodec that communicates with the ClientCodec +// on the other end of the given conn. +func NewServerCodec(conn io.ReadWriteCloser) rpc.ServerCodec { + return &serverCodec{ + r: conn, + w: conn, + c: conn, + pending: make(map[uint64]uint64), + } +} + +func (c *serverCodec) ReadRequestHeader(r *rpc.Request) error { + header := wire.RequestHeader{} + err := readRequestHeader(c.r, &header) + if err != nil { + return err + } + + c.mutex.Lock() + c.seq++ + c.pending[c.seq] = *header.Id + r.ServiceMethod = *header.Method + r.Seq = c.seq + c.mutex.Unlock() + + c.reqHeader = header + return nil +} + +func (c *serverCodec) ReadRequestBody(x interface{}) error { + if x == nil { + return nil + } + request, ok := x.(proto.Message) + if !ok { + return fmt.Errorf( + "protorpc.ServerCodec.ReadRequestBody: %T does not implement proto.Message", + x, + ) + } + + err := readRequestBody(c.r, &c.reqHeader, request) + if err != nil { + return nil + } + + c.reqHeader = wire.RequestHeader{} + return nil +} + +// A value sent as a placeholder for the server's response value when the server +// receives an invalid request. It is never decoded by the client since the Response +// contains an error when it is used. +var invalidRequest = struct{}{} + +func (c *serverCodec) WriteResponse(r *rpc.Response, x interface{}) error { + var response proto.Message + if x != nil { + var ok bool + if response, ok = x.(proto.Message); !ok { + if _, ok = x.(struct{}); !ok { + c.mutex.Lock() + delete(c.pending, r.Seq) + c.mutex.Unlock() + return fmt.Errorf( + "protorpc.ServerCodec.WriteResponse: %T does not implement proto.Message", + x, + ) + } + } + } + + c.mutex.Lock() + id, ok := c.pending[r.Seq] + if !ok { + c.mutex.Unlock() + return errors.New("protorpc: invalid sequence number in response") + } + delete(c.pending, r.Seq) + c.mutex.Unlock() + + err := writeResponse(c.w, id, r.Error, response) + if err != nil { + return err + } + + return nil +} + +func (s *serverCodec) Close() error { + return s.c.Close() +} + +// ServeConn runs the Protobuf-RPC server on a single connection. +// ServeConn blocks, serving the connection until the client hangs up. +// The caller typically invokes ServeConn in a go statement. +func ServeConn(conn io.ReadWriteCloser) { + rpc.ServeCodec(NewServerCodec(conn)) +} diff --git a/core/protorpc/wire.go b/core/protorpc/wire.go new file mode 100644 index 0000000..97ec551 --- /dev/null +++ b/core/protorpc/wire.go @@ -0,0 +1,173 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package protorpc + +import ( + "fmt" + "io" + + wire "github.com/chai2010/protorpc/wire.pb" + "github.com/golang/protobuf/proto" +) + +func To[T any](v T) *T { + return &v +} + +func maxUint32(a, b uint32) uint32 { + if a > b { + return a + } + return b +} + +func writeRequest(w io.Writer, id uint64, method string, request proto.Message) error { + // marshal request + pbRequest := []byte{} + if request != nil { + var err error + pbRequest, err = proto.Marshal(request) + if err != nil { + return err + } + } + + // generate header + header := &wire.RequestHeader{ + Id: To(id), + Method: To(method), + RawRequestLen: To(uint32(len(pbRequest))), + } + + // check header size + pbHeader, err := proto.Marshal(header) + if err != err { + return err + } + if len(pbHeader) > int(wire.Const_MAX_REQUEST_HEADER_LEN) { + return fmt.Errorf("protorpc.writeRequest: header larger than max_header_len: %d.", len(pbHeader)) + } + + // send header (more) + if err := sendFrame(w, pbHeader); err != nil { + return err + } + + // send body (end) + if err := sendFrame(w, pbRequest); err != nil { + return err + } + + return nil +} + +func readRequestHeader(r io.Reader, header *wire.RequestHeader) (err error) { + // recv header (more) + pbHeader, err := recvFrame(r, int(wire.Const_MAX_REQUEST_HEADER_LEN)) + if err != nil { + return err + } + + // Marshal Header + err = proto.Unmarshal(pbHeader, header) + if err != nil { + return err + } + + return nil +} + +func readRequestBody(r io.Reader, header *wire.RequestHeader, request proto.Message) error { + // recv body (end) + pbRequest, err := recvFrame(r, int(*header.RawRequestLen)) + if err != nil { + return err + } + + // Unmarshal to proto message + if request != nil { + err = proto.Unmarshal(pbRequest, request) + if err != nil { + return err + } + } + + return nil +} + +func writeResponse(w io.Writer, id uint64, serr string, response proto.Message) (err error) { + // clean response if error + if serr != "" { + response = nil + } + + // marshal response + pbResponse := []byte{} + if response != nil { + pbResponse, err = proto.Marshal(response) + if err != nil { + return err + } + } + + // generate header + header := &wire.ResponseHeader{ + Id: To(id), + Error: To(serr), + RawResponseLen: To(uint32(len(pbResponse))), + } + + // check header size + pbHeader, err := proto.Marshal(header) + if err != err { + return + } + + // send header (more) + if err = sendFrame(w, pbHeader); err != nil { + return + } + + // send body (end) + if err = sendFrame(w, pbResponse); err != nil { + return + } + + return nil +} + +func readResponseHeader(r io.Reader, header *wire.ResponseHeader) error { + // recv header (more) + pbHeader, err := recvFrame(r, 0) + if err != nil { + return err + } + + // Marshal Header + err = proto.Unmarshal(pbHeader, header) + if err != nil { + return err + } + + return nil +} + +func readResponseBody(r io.Reader, header *wire.ResponseHeader, response proto.Message) error { + // recv body (end) + pbResponse, err := recvFrame(r, int(*header.RawResponseLen)) + if err != nil { + return err + } + + // Unmarshal to proto message + if response != nil { + err = proto.Unmarshal(pbResponse, response) + if err != nil { + return err + } + } + + return nil +} diff --git a/core/protorpc/wire.pb/proto.go b/core/protorpc/wire.pb/proto.go new file mode 100644 index 0000000..cca30a7 --- /dev/null +++ b/core/protorpc/wire.pb/proto.go @@ -0,0 +1,7 @@ +// Copyright 2014 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:generate protoc --go_out=. wire.proto + +package protorpc_wire diff --git a/core/protorpc/wire.pb/wire.pb.go b/core/protorpc/wire.pb/wire.pb.go new file mode 100644 index 0000000..446434a --- /dev/null +++ b/core/protorpc/wire.pb/wire.pb.go @@ -0,0 +1,296 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.6 +// protoc v6.31.0 +// source: wire.proto + +// +// protorpc wire format wrapper +// +// 0. Frame Format +// len : uvarint64 +// data: byte[len] +// +// 1. Client Send Request +// Send RequestHeader: sendFrame(zsock, hdr, len(hdr)) +// Send Request: sendFrame(zsock, body, hdr.snappy_compressed_request_len) +// +// 2. Server Recv Request +// Recv RequestHeader: recvFrame(zsock, hdr, max_hdr_len, 0) +// Recv Request: recvFrame(zsock, body, hdr.snappy_compressed_request_len, 0) +// +// 3. Server Send Response +// Send ResponseHeader: sendFrame(zsock, hdr, len(hdr)) +// Send Response: sendFrame(zsock, body, hdr.snappy_compressed_response_len) +// +// 4. Client Recv Response +// Recv ResponseHeader: recvFrame(zsock, hdr, max_hdr_len, 0) +// Recv Response: recvFrame(zsock, body, hdr.snappy_compressed_response_len, 0) +// + +package protorpc_wire + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Const int32 + +const ( + Const_ZERO Const = 0 + Const_MAX_REQUEST_HEADER_LEN Const = 1024 +) + +// Enum value maps for Const. +var ( + Const_name = map[int32]string{ + 0: "ZERO", + 1024: "MAX_REQUEST_HEADER_LEN", + } + Const_value = map[string]int32{ + "ZERO": 0, + "MAX_REQUEST_HEADER_LEN": 1024, + } +) + +func (x Const) Enum() *Const { + p := new(Const) + *p = x + return p +} + +func (x Const) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Const) Descriptor() protoreflect.EnumDescriptor { + return file_wire_proto_enumTypes[0].Descriptor() +} + +func (Const) Type() protoreflect.EnumType { + return &file_wire_proto_enumTypes[0] +} + +func (x Const) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *Const) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = Const(num) + return nil +} + +// Deprecated: Use Const.Descriptor instead. +func (Const) EnumDescriptor() ([]byte, []int) { + return file_wire_proto_rawDescGZIP(), []int{0} +} + +type RequestHeader struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id *uint64 `protobuf:"varint,1,req,name=id" json:"id,omitempty"` + Method *string `protobuf:"bytes,2,req,name=method" json:"method,omitempty"` + RawRequestLen *uint32 `protobuf:"varint,3,req,name=raw_request_len,json=rawRequestLen" json:"raw_request_len,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RequestHeader) Reset() { + *x = RequestHeader{} + mi := &file_wire_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RequestHeader) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RequestHeader) ProtoMessage() {} + +func (x *RequestHeader) ProtoReflect() protoreflect.Message { + mi := &file_wire_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RequestHeader.ProtoReflect.Descriptor instead. +func (*RequestHeader) Descriptor() ([]byte, []int) { + return file_wire_proto_rawDescGZIP(), []int{0} +} + +func (x *RequestHeader) GetId() uint64 { + if x != nil && x.Id != nil { + return *x.Id + } + return 0 +} + +func (x *RequestHeader) GetMethod() string { + if x != nil && x.Method != nil { + return *x.Method + } + return "" +} + +func (x *RequestHeader) GetRawRequestLen() uint32 { + if x != nil && x.RawRequestLen != nil { + return *x.RawRequestLen + } + return 0 +} + +type ResponseHeader struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id *uint64 `protobuf:"varint,1,req,name=id" json:"id,omitempty"` + Error *string `protobuf:"bytes,2,req,name=error" json:"error,omitempty"` + RawResponseLen *uint32 `protobuf:"varint,3,req,name=raw_response_len,json=rawResponseLen" json:"raw_response_len,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ResponseHeader) Reset() { + *x = ResponseHeader{} + mi := &file_wire_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ResponseHeader) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResponseHeader) ProtoMessage() {} + +func (x *ResponseHeader) ProtoReflect() protoreflect.Message { + mi := &file_wire_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResponseHeader.ProtoReflect.Descriptor instead. +func (*ResponseHeader) Descriptor() ([]byte, []int) { + return file_wire_proto_rawDescGZIP(), []int{1} +} + +func (x *ResponseHeader) GetId() uint64 { + if x != nil && x.Id != nil { + return *x.Id + } + return 0 +} + +func (x *ResponseHeader) GetError() string { + if x != nil && x.Error != nil { + return *x.Error + } + return "" +} + +func (x *ResponseHeader) GetRawResponseLen() uint32 { + if x != nil && x.RawResponseLen != nil { + return *x.RawResponseLen + } + return 0 +} + +var File_wire_proto protoreflect.FileDescriptor + +const file_wire_proto_rawDesc = "" + + "\n" + + "\n" + + "wire.proto\x12\rprotorpc.wire\"_\n" + + "\rRequestHeader\x12\x0e\n" + + "\x02id\x18\x01 \x02(\x04R\x02id\x12\x16\n" + + "\x06method\x18\x02 \x02(\tR\x06method\x12&\n" + + "\x0fraw_request_len\x18\x03 \x02(\rR\rrawRequestLen\"`\n" + + "\x0eResponseHeader\x12\x0e\n" + + "\x02id\x18\x01 \x02(\x04R\x02id\x12\x14\n" + + "\x05error\x18\x02 \x02(\tR\x05error\x12(\n" + + "\x10raw_response_len\x18\x03 \x02(\rR\x0erawResponseLen*.\n" + + "\x05Const\x12\b\n" + + "\x04ZERO\x10\x00\x12\x1b\n" + + "\x16MAX_REQUEST_HEADER_LEN\x10\x80\bB\x0fZ\rprotorpc.wire" + +var ( + file_wire_proto_rawDescOnce sync.Once + file_wire_proto_rawDescData []byte +) + +func file_wire_proto_rawDescGZIP() []byte { + file_wire_proto_rawDescOnce.Do(func() { + file_wire_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_wire_proto_rawDesc), len(file_wire_proto_rawDesc))) + }) + return file_wire_proto_rawDescData +} + +var file_wire_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_wire_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_wire_proto_goTypes = []any{ + (Const)(0), // 0: protorpc.wire.Const + (*RequestHeader)(nil), // 1: protorpc.wire.RequestHeader + (*ResponseHeader)(nil), // 2: protorpc.wire.ResponseHeader +} +var file_wire_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_wire_proto_init() } +func file_wire_proto_init() { + if File_wire_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_wire_proto_rawDesc), len(file_wire_proto_rawDesc)), + NumEnums: 1, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_wire_proto_goTypes, + DependencyIndexes: file_wire_proto_depIdxs, + EnumInfos: file_wire_proto_enumTypes, + MessageInfos: file_wire_proto_msgTypes, + }.Build() + File_wire_proto = out.File + file_wire_proto_goTypes = nil + file_wire_proto_depIdxs = nil +} diff --git a/core/protorpc/wire.pb/wire.proto b/core/protorpc/wire.pb/wire.proto new file mode 100644 index 0000000..f1e1df5 --- /dev/null +++ b/core/protorpc/wire.pb/wire.proto @@ -0,0 +1,50 @@ +// Copyright 2013 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +syntax = "proto2"; + +// +// protorpc wire format wrapper +// +// 0. Frame Format +// len : uvarint64 +// data: byte[len] +// +// 1. Client Send Request +// Send RequestHeader: sendFrame(zsock, hdr, len(hdr)) +// Send Request: sendFrame(zsock, body, hdr.snappy_compressed_request_len) +// +// 2. Server Recv Request +// Recv RequestHeader: recvFrame(zsock, hdr, max_hdr_len, 0) +// Recv Request: recvFrame(zsock, body, hdr.snappy_compressed_request_len, 0) +// +// 3. Server Send Response +// Send ResponseHeader: sendFrame(zsock, hdr, len(hdr)) +// Send Response: sendFrame(zsock, body, hdr.snappy_compressed_response_len) +// +// 4. Client Recv Response +// Recv ResponseHeader: recvFrame(zsock, hdr, max_hdr_len, 0) +// Recv Response: recvFrame(zsock, body, hdr.snappy_compressed_response_len, 0) +// +package protorpc.wire; +option go_package = "protorpc.wire"; + +enum Const { + ZERO = 0; + MAX_REQUEST_HEADER_LEN = 1024; +} + +message RequestHeader { + required uint64 id = 1; + required string method = 2; + + required uint32 raw_request_len = 3; +} + +message ResponseHeader { + required uint64 id = 1; + required string error = 2; + + required uint32 raw_response_len = 3; +} diff --git a/core/server/gen/libcore.pb.go b/core/server/gen/libcore.pb.go deleted file mode 100644 index e2ee848..0000000 --- a/core/server/gen/libcore.pb.go +++ /dev/null @@ -1,1762 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.36.5 -// protoc v5.29.3 -// source: libcore.proto - -package gen - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" - unsafe "unsafe" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type EmptyReq struct { - state protoimpl.MessageState `protogen:"open.v1"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *EmptyReq) Reset() { - *x = EmptyReq{} - mi := &file_libcore_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *EmptyReq) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*EmptyReq) ProtoMessage() {} - -func (x *EmptyReq) ProtoReflect() protoreflect.Message { - mi := &file_libcore_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use EmptyReq.ProtoReflect.Descriptor instead. -func (*EmptyReq) Descriptor() ([]byte, []int) { - return file_libcore_proto_rawDescGZIP(), []int{0} -} - -type EmptyResp struct { - state protoimpl.MessageState `protogen:"open.v1"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *EmptyResp) Reset() { - *x = EmptyResp{} - mi := &file_libcore_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *EmptyResp) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*EmptyResp) ProtoMessage() {} - -func (x *EmptyResp) ProtoReflect() protoreflect.Message { - mi := &file_libcore_proto_msgTypes[1] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use EmptyResp.ProtoReflect.Descriptor instead. -func (*EmptyResp) Descriptor() ([]byte, []int) { - return file_libcore_proto_rawDescGZIP(), []int{1} -} - -type ErrorResp struct { - state protoimpl.MessageState `protogen:"open.v1"` - Error *string `protobuf:"bytes,1,opt,name=error,def=" json:"error,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -// Default values for ErrorResp fields. -const ( - Default_ErrorResp_Error = string("") -) - -func (x *ErrorResp) Reset() { - *x = ErrorResp{} - mi := &file_libcore_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ErrorResp) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ErrorResp) ProtoMessage() {} - -func (x *ErrorResp) ProtoReflect() protoreflect.Message { - mi := &file_libcore_proto_msgTypes[2] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ErrorResp.ProtoReflect.Descriptor instead. -func (*ErrorResp) Descriptor() ([]byte, []int) { - return file_libcore_proto_rawDescGZIP(), []int{2} -} - -func (x *ErrorResp) GetError() string { - if x != nil && x.Error != nil { - return *x.Error - } - return Default_ErrorResp_Error -} - -type LoadConfigReq struct { - state protoimpl.MessageState `protogen:"open.v1"` - CoreConfig *string `protobuf:"bytes,1,opt,name=core_config,json=coreConfig,def=" json:"core_config,omitempty"` - DisableStats *bool `protobuf:"varint,2,opt,name=disable_stats,json=disableStats,def=0" json:"disable_stats,omitempty"` - NeedExtraProcess *bool `protobuf:"varint,3,opt,name=need_extra_process,json=needExtraProcess,def=0" json:"need_extra_process,omitempty"` - ExtraProcessPath *string `protobuf:"bytes,4,opt,name=extra_process_path,json=extraProcessPath,def=" json:"extra_process_path,omitempty"` - ExtraProcessArgs *string `protobuf:"bytes,5,opt,name=extra_process_args,json=extraProcessArgs,def=" json:"extra_process_args,omitempty"` - ExtraProcessConf *string `protobuf:"bytes,6,opt,name=extra_process_conf,json=extraProcessConf,def=" json:"extra_process_conf,omitempty"` - ExtraProcessConfDir *string `protobuf:"bytes,7,opt,name=extra_process_conf_dir,json=extraProcessConfDir,def=" json:"extra_process_conf_dir,omitempty"` - ExtraNoOut *bool `protobuf:"varint,8,opt,name=extra_no_out,json=extraNoOut,def=0" json:"extra_no_out,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -// Default values for LoadConfigReq fields. -const ( - Default_LoadConfigReq_CoreConfig = string("") - Default_LoadConfigReq_DisableStats = bool(false) - Default_LoadConfigReq_NeedExtraProcess = bool(false) - Default_LoadConfigReq_ExtraProcessPath = string("") - Default_LoadConfigReq_ExtraProcessArgs = string("") - Default_LoadConfigReq_ExtraProcessConf = string("") - Default_LoadConfigReq_ExtraProcessConfDir = string("") - Default_LoadConfigReq_ExtraNoOut = bool(false) -) - -func (x *LoadConfigReq) Reset() { - *x = LoadConfigReq{} - mi := &file_libcore_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *LoadConfigReq) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*LoadConfigReq) ProtoMessage() {} - -func (x *LoadConfigReq) ProtoReflect() protoreflect.Message { - mi := &file_libcore_proto_msgTypes[3] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use LoadConfigReq.ProtoReflect.Descriptor instead. -func (*LoadConfigReq) Descriptor() ([]byte, []int) { - return file_libcore_proto_rawDescGZIP(), []int{3} -} - -func (x *LoadConfigReq) GetCoreConfig() string { - if x != nil && x.CoreConfig != nil { - return *x.CoreConfig - } - return Default_LoadConfigReq_CoreConfig -} - -func (x *LoadConfigReq) GetDisableStats() bool { - if x != nil && x.DisableStats != nil { - return *x.DisableStats - } - return Default_LoadConfigReq_DisableStats -} - -func (x *LoadConfigReq) GetNeedExtraProcess() bool { - if x != nil && x.NeedExtraProcess != nil { - return *x.NeedExtraProcess - } - return Default_LoadConfigReq_NeedExtraProcess -} - -func (x *LoadConfigReq) GetExtraProcessPath() string { - if x != nil && x.ExtraProcessPath != nil { - return *x.ExtraProcessPath - } - return Default_LoadConfigReq_ExtraProcessPath -} - -func (x *LoadConfigReq) GetExtraProcessArgs() string { - if x != nil && x.ExtraProcessArgs != nil { - return *x.ExtraProcessArgs - } - return Default_LoadConfigReq_ExtraProcessArgs -} - -func (x *LoadConfigReq) GetExtraProcessConf() string { - if x != nil && x.ExtraProcessConf != nil { - return *x.ExtraProcessConf - } - return Default_LoadConfigReq_ExtraProcessConf -} - -func (x *LoadConfigReq) GetExtraProcessConfDir() string { - if x != nil && x.ExtraProcessConfDir != nil { - return *x.ExtraProcessConfDir - } - return Default_LoadConfigReq_ExtraProcessConfDir -} - -func (x *LoadConfigReq) GetExtraNoOut() bool { - if x != nil && x.ExtraNoOut != nil { - return *x.ExtraNoOut - } - return Default_LoadConfigReq_ExtraNoOut -} - -type URLTestResp struct { - state protoimpl.MessageState `protogen:"open.v1"` - OutboundTag *string `protobuf:"bytes,1,opt,name=outbound_tag,json=outboundTag,def=" json:"outbound_tag,omitempty"` - LatencyMs *int32 `protobuf:"varint,2,opt,name=latency_ms,json=latencyMs,def=0" json:"latency_ms,omitempty"` - Error *string `protobuf:"bytes,3,opt,name=error,def=" json:"error,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -// Default values for URLTestResp fields. -const ( - Default_URLTestResp_OutboundTag = string("") - Default_URLTestResp_LatencyMs = int32(0) - Default_URLTestResp_Error = string("") -) - -func (x *URLTestResp) Reset() { - *x = URLTestResp{} - mi := &file_libcore_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *URLTestResp) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*URLTestResp) ProtoMessage() {} - -func (x *URLTestResp) ProtoReflect() protoreflect.Message { - mi := &file_libcore_proto_msgTypes[4] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use URLTestResp.ProtoReflect.Descriptor instead. -func (*URLTestResp) Descriptor() ([]byte, []int) { - return file_libcore_proto_rawDescGZIP(), []int{4} -} - -func (x *URLTestResp) GetOutboundTag() string { - if x != nil && x.OutboundTag != nil { - return *x.OutboundTag - } - return Default_URLTestResp_OutboundTag -} - -func (x *URLTestResp) GetLatencyMs() int32 { - if x != nil && x.LatencyMs != nil { - return *x.LatencyMs - } - return Default_URLTestResp_LatencyMs -} - -func (x *URLTestResp) GetError() string { - if x != nil && x.Error != nil { - return *x.Error - } - return Default_URLTestResp_Error -} - -type TestReq struct { - state protoimpl.MessageState `protogen:"open.v1"` - Config *string `protobuf:"bytes,1,opt,name=config,def=" json:"config,omitempty"` - OutboundTags []string `protobuf:"bytes,2,rep,name=outbound_tags,json=outboundTags" json:"outbound_tags,omitempty"` - UseDefaultOutbound *bool `protobuf:"varint,3,opt,name=use_default_outbound,json=useDefaultOutbound,def=0" json:"use_default_outbound,omitempty"` - Url *string `protobuf:"bytes,4,opt,name=url,def=" json:"url,omitempty"` - TestCurrent *bool `protobuf:"varint,5,opt,name=test_current,json=testCurrent,def=0" json:"test_current,omitempty"` - MaxConcurrency *int32 `protobuf:"varint,6,opt,name=max_concurrency,json=maxConcurrency,def=0" json:"max_concurrency,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -// Default values for TestReq fields. -const ( - Default_TestReq_Config = string("") - Default_TestReq_UseDefaultOutbound = bool(false) - Default_TestReq_Url = string("") - Default_TestReq_TestCurrent = bool(false) - Default_TestReq_MaxConcurrency = int32(0) -) - -func (x *TestReq) Reset() { - *x = TestReq{} - mi := &file_libcore_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *TestReq) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TestReq) ProtoMessage() {} - -func (x *TestReq) ProtoReflect() protoreflect.Message { - mi := &file_libcore_proto_msgTypes[5] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TestReq.ProtoReflect.Descriptor instead. -func (*TestReq) Descriptor() ([]byte, []int) { - return file_libcore_proto_rawDescGZIP(), []int{5} -} - -func (x *TestReq) GetConfig() string { - if x != nil && x.Config != nil { - return *x.Config - } - return Default_TestReq_Config -} - -func (x *TestReq) GetOutboundTags() []string { - if x != nil { - return x.OutboundTags - } - return nil -} - -func (x *TestReq) GetUseDefaultOutbound() bool { - if x != nil && x.UseDefaultOutbound != nil { - return *x.UseDefaultOutbound - } - return Default_TestReq_UseDefaultOutbound -} - -func (x *TestReq) GetUrl() string { - if x != nil && x.Url != nil { - return *x.Url - } - return Default_TestReq_Url -} - -func (x *TestReq) GetTestCurrent() bool { - if x != nil && x.TestCurrent != nil { - return *x.TestCurrent - } - return Default_TestReq_TestCurrent -} - -func (x *TestReq) GetMaxConcurrency() int32 { - if x != nil && x.MaxConcurrency != nil { - return *x.MaxConcurrency - } - return Default_TestReq_MaxConcurrency -} - -type TestResp struct { - state protoimpl.MessageState `protogen:"open.v1"` - Results []*URLTestResp `protobuf:"bytes,1,rep,name=results" json:"results,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *TestResp) Reset() { - *x = TestResp{} - mi := &file_libcore_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *TestResp) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*TestResp) ProtoMessage() {} - -func (x *TestResp) ProtoReflect() protoreflect.Message { - mi := &file_libcore_proto_msgTypes[6] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use TestResp.ProtoReflect.Descriptor instead. -func (*TestResp) Descriptor() ([]byte, []int) { - return file_libcore_proto_rawDescGZIP(), []int{6} -} - -func (x *TestResp) GetResults() []*URLTestResp { - if x != nil { - return x.Results - } - return nil -} - -type QueryStatsResp struct { - state protoimpl.MessageState `protogen:"open.v1"` - Ups map[string]int64 `protobuf:"bytes,1,rep,name=ups" json:"ups,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` - Downs map[string]int64 `protobuf:"bytes,2,rep,name=downs" json:"downs,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *QueryStatsResp) Reset() { - *x = QueryStatsResp{} - mi := &file_libcore_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *QueryStatsResp) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*QueryStatsResp) ProtoMessage() {} - -func (x *QueryStatsResp) ProtoReflect() protoreflect.Message { - mi := &file_libcore_proto_msgTypes[7] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use QueryStatsResp.ProtoReflect.Descriptor instead. -func (*QueryStatsResp) Descriptor() ([]byte, []int) { - return file_libcore_proto_rawDescGZIP(), []int{7} -} - -func (x *QueryStatsResp) GetUps() map[string]int64 { - if x != nil { - return x.Ups - } - return nil -} - -func (x *QueryStatsResp) GetDowns() map[string]int64 { - if x != nil { - return x.Downs - } - return nil -} - -type ListConnectionsResp struct { - state protoimpl.MessageState `protogen:"open.v1"` - Connections []*ConnectionMetaData `protobuf:"bytes,1,rep,name=connections" json:"connections,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *ListConnectionsResp) Reset() { - *x = ListConnectionsResp{} - mi := &file_libcore_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ListConnectionsResp) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListConnectionsResp) ProtoMessage() {} - -func (x *ListConnectionsResp) ProtoReflect() protoreflect.Message { - mi := &file_libcore_proto_msgTypes[8] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListConnectionsResp.ProtoReflect.Descriptor instead. -func (*ListConnectionsResp) Descriptor() ([]byte, []int) { - return file_libcore_proto_rawDescGZIP(), []int{8} -} - -func (x *ListConnectionsResp) GetConnections() []*ConnectionMetaData { - if x != nil { - return x.Connections - } - return nil -} - -type ConnectionMetaData struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id *string `protobuf:"bytes,1,opt,name=id,def=" json:"id,omitempty"` - CreatedAt *int64 `protobuf:"varint,2,opt,name=created_at,json=createdAt,def=0" json:"created_at,omitempty"` - Upload *int64 `protobuf:"varint,3,opt,name=upload,def=0" json:"upload,omitempty"` - Download *int64 `protobuf:"varint,4,opt,name=download,def=0" json:"download,omitempty"` - Outbound *string `protobuf:"bytes,5,opt,name=outbound,def=" json:"outbound,omitempty"` - Network *string `protobuf:"bytes,6,opt,name=network,def=" json:"network,omitempty"` - Dest *string `protobuf:"bytes,7,opt,name=dest,def=" json:"dest,omitempty"` - Protocol *string `protobuf:"bytes,8,opt,name=protocol,def=" json:"protocol,omitempty"` - Domain *string `protobuf:"bytes,9,opt,name=domain,def=" json:"domain,omitempty"` - Process *string `protobuf:"bytes,10,opt,name=process,def=" json:"process,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -// Default values for ConnectionMetaData fields. -const ( - Default_ConnectionMetaData_Id = string("") - Default_ConnectionMetaData_CreatedAt = int64(0) - Default_ConnectionMetaData_Upload = int64(0) - Default_ConnectionMetaData_Download = int64(0) - Default_ConnectionMetaData_Outbound = string("") - Default_ConnectionMetaData_Network = string("") - Default_ConnectionMetaData_Dest = string("") - Default_ConnectionMetaData_Protocol = string("") - Default_ConnectionMetaData_Domain = string("") - Default_ConnectionMetaData_Process = string("") -) - -func (x *ConnectionMetaData) Reset() { - *x = ConnectionMetaData{} - mi := &file_libcore_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *ConnectionMetaData) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ConnectionMetaData) ProtoMessage() {} - -func (x *ConnectionMetaData) ProtoReflect() protoreflect.Message { - mi := &file_libcore_proto_msgTypes[9] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ConnectionMetaData.ProtoReflect.Descriptor instead. -func (*ConnectionMetaData) Descriptor() ([]byte, []int) { - return file_libcore_proto_rawDescGZIP(), []int{9} -} - -func (x *ConnectionMetaData) GetId() string { - if x != nil && x.Id != nil { - return *x.Id - } - return Default_ConnectionMetaData_Id -} - -func (x *ConnectionMetaData) GetCreatedAt() int64 { - if x != nil && x.CreatedAt != nil { - return *x.CreatedAt - } - return Default_ConnectionMetaData_CreatedAt -} - -func (x *ConnectionMetaData) GetUpload() int64 { - if x != nil && x.Upload != nil { - return *x.Upload - } - return Default_ConnectionMetaData_Upload -} - -func (x *ConnectionMetaData) GetDownload() int64 { - if x != nil && x.Download != nil { - return *x.Download - } - return Default_ConnectionMetaData_Download -} - -func (x *ConnectionMetaData) GetOutbound() string { - if x != nil && x.Outbound != nil { - return *x.Outbound - } - return Default_ConnectionMetaData_Outbound -} - -func (x *ConnectionMetaData) GetNetwork() string { - if x != nil && x.Network != nil { - return *x.Network - } - return Default_ConnectionMetaData_Network -} - -func (x *ConnectionMetaData) GetDest() string { - if x != nil && x.Dest != nil { - return *x.Dest - } - return Default_ConnectionMetaData_Dest -} - -func (x *ConnectionMetaData) GetProtocol() string { - if x != nil && x.Protocol != nil { - return *x.Protocol - } - return Default_ConnectionMetaData_Protocol -} - -func (x *ConnectionMetaData) GetDomain() string { - if x != nil && x.Domain != nil { - return *x.Domain - } - return Default_ConnectionMetaData_Domain -} - -func (x *ConnectionMetaData) GetProcess() string { - if x != nil && x.Process != nil { - return *x.Process - } - return Default_ConnectionMetaData_Process -} - -type GetGeoIPListResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - Items []string `protobuf:"bytes,1,rep,name=items" json:"items,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *GetGeoIPListResponse) Reset() { - *x = GetGeoIPListResponse{} - mi := &file_libcore_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *GetGeoIPListResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetGeoIPListResponse) ProtoMessage() {} - -func (x *GetGeoIPListResponse) ProtoReflect() protoreflect.Message { - mi := &file_libcore_proto_msgTypes[10] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetGeoIPListResponse.ProtoReflect.Descriptor instead. -func (*GetGeoIPListResponse) Descriptor() ([]byte, []int) { - return file_libcore_proto_rawDescGZIP(), []int{10} -} - -func (x *GetGeoIPListResponse) GetItems() []string { - if x != nil { - return x.Items - } - return nil -} - -type GetGeoSiteListResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - Items []string `protobuf:"bytes,2,rep,name=items" json:"items,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *GetGeoSiteListResponse) Reset() { - *x = GetGeoSiteListResponse{} - mi := &file_libcore_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *GetGeoSiteListResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetGeoSiteListResponse) ProtoMessage() {} - -func (x *GetGeoSiteListResponse) ProtoReflect() protoreflect.Message { - mi := &file_libcore_proto_msgTypes[11] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetGeoSiteListResponse.ProtoReflect.Descriptor instead. -func (*GetGeoSiteListResponse) Descriptor() ([]byte, []int) { - return file_libcore_proto_rawDescGZIP(), []int{11} -} - -func (x *GetGeoSiteListResponse) GetItems() []string { - if x != nil { - return x.Items - } - return nil -} - -type GeoListRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - Path *string `protobuf:"bytes,1,opt,name=path,def=" json:"path,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -// Default values for GeoListRequest fields. -const ( - Default_GeoListRequest_Path = string("") -) - -func (x *GeoListRequest) Reset() { - *x = GeoListRequest{} - mi := &file_libcore_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *GeoListRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GeoListRequest) ProtoMessage() {} - -func (x *GeoListRequest) ProtoReflect() protoreflect.Message { - mi := &file_libcore_proto_msgTypes[12] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GeoListRequest.ProtoReflect.Descriptor instead. -func (*GeoListRequest) Descriptor() ([]byte, []int) { - return file_libcore_proto_rawDescGZIP(), []int{12} -} - -func (x *GeoListRequest) GetPath() string { - if x != nil && x.Path != nil { - return *x.Path - } - return Default_GeoListRequest_Path -} - -type CompileGeoIPToSrsRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - Item *string `protobuf:"bytes,1,opt,name=item,def=" json:"item,omitempty"` - Path *string `protobuf:"bytes,2,opt,name=path,def=" json:"path,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -// Default values for CompileGeoIPToSrsRequest fields. -const ( - Default_CompileGeoIPToSrsRequest_Item = string("") - Default_CompileGeoIPToSrsRequest_Path = string("") -) - -func (x *CompileGeoIPToSrsRequest) Reset() { - *x = CompileGeoIPToSrsRequest{} - mi := &file_libcore_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *CompileGeoIPToSrsRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CompileGeoIPToSrsRequest) ProtoMessage() {} - -func (x *CompileGeoIPToSrsRequest) ProtoReflect() protoreflect.Message { - mi := &file_libcore_proto_msgTypes[13] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CompileGeoIPToSrsRequest.ProtoReflect.Descriptor instead. -func (*CompileGeoIPToSrsRequest) Descriptor() ([]byte, []int) { - return file_libcore_proto_rawDescGZIP(), []int{13} -} - -func (x *CompileGeoIPToSrsRequest) GetItem() string { - if x != nil && x.Item != nil { - return *x.Item - } - return Default_CompileGeoIPToSrsRequest_Item -} - -func (x *CompileGeoIPToSrsRequest) GetPath() string { - if x != nil && x.Path != nil { - return *x.Path - } - return Default_CompileGeoIPToSrsRequest_Path -} - -type CompileGeoSiteToSrsRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - Item *string `protobuf:"bytes,1,opt,name=item,def=" json:"item,omitempty"` - Path *string `protobuf:"bytes,2,opt,name=path,def=" json:"path,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -// Default values for CompileGeoSiteToSrsRequest fields. -const ( - Default_CompileGeoSiteToSrsRequest_Item = string("") - Default_CompileGeoSiteToSrsRequest_Path = string("") -) - -func (x *CompileGeoSiteToSrsRequest) Reset() { - *x = CompileGeoSiteToSrsRequest{} - mi := &file_libcore_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *CompileGeoSiteToSrsRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CompileGeoSiteToSrsRequest) ProtoMessage() {} - -func (x *CompileGeoSiteToSrsRequest) ProtoReflect() protoreflect.Message { - mi := &file_libcore_proto_msgTypes[14] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CompileGeoSiteToSrsRequest.ProtoReflect.Descriptor instead. -func (*CompileGeoSiteToSrsRequest) Descriptor() ([]byte, []int) { - return file_libcore_proto_rawDescGZIP(), []int{14} -} - -func (x *CompileGeoSiteToSrsRequest) GetItem() string { - if x != nil && x.Item != nil { - return *x.Item - } - return Default_CompileGeoSiteToSrsRequest_Item -} - -func (x *CompileGeoSiteToSrsRequest) GetPath() string { - if x != nil && x.Path != nil { - return *x.Path - } - return Default_CompileGeoSiteToSrsRequest_Path -} - -type SetSystemDNSRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - Clear *bool `protobuf:"varint,1,opt,name=clear,def=0" json:"clear,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -// Default values for SetSystemDNSRequest fields. -const ( - Default_SetSystemDNSRequest_Clear = bool(false) -) - -func (x *SetSystemDNSRequest) Reset() { - *x = SetSystemDNSRequest{} - mi := &file_libcore_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *SetSystemDNSRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SetSystemDNSRequest) ProtoMessage() {} - -func (x *SetSystemDNSRequest) ProtoReflect() protoreflect.Message { - mi := &file_libcore_proto_msgTypes[15] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SetSystemDNSRequest.ProtoReflect.Descriptor instead. -func (*SetSystemDNSRequest) Descriptor() ([]byte, []int) { - return file_libcore_proto_rawDescGZIP(), []int{15} -} - -func (x *SetSystemDNSRequest) GetClear() bool { - if x != nil && x.Clear != nil { - return *x.Clear - } - return Default_SetSystemDNSRequest_Clear -} - -type IsPrivilegedResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - HasPrivilege *bool `protobuf:"varint,1,opt,name=has_privilege,json=hasPrivilege,def=0" json:"has_privilege,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -// Default values for IsPrivilegedResponse fields. -const ( - Default_IsPrivilegedResponse_HasPrivilege = bool(false) -) - -func (x *IsPrivilegedResponse) Reset() { - *x = IsPrivilegedResponse{} - mi := &file_libcore_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *IsPrivilegedResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*IsPrivilegedResponse) ProtoMessage() {} - -func (x *IsPrivilegedResponse) ProtoReflect() protoreflect.Message { - mi := &file_libcore_proto_msgTypes[16] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use IsPrivilegedResponse.ProtoReflect.Descriptor instead. -func (*IsPrivilegedResponse) Descriptor() ([]byte, []int) { - return file_libcore_proto_rawDescGZIP(), []int{16} -} - -func (x *IsPrivilegedResponse) GetHasPrivilege() bool { - if x != nil && x.HasPrivilege != nil { - return *x.HasPrivilege - } - return Default_IsPrivilegedResponse_HasPrivilege -} - -type SpeedTestRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - Config *string `protobuf:"bytes,1,opt,name=config,def=" json:"config,omitempty"` - OutboundTags []string `protobuf:"bytes,2,rep,name=outbound_tags,json=outboundTags" json:"outbound_tags,omitempty"` - TestCurrent *bool `protobuf:"varint,3,opt,name=test_current,json=testCurrent,def=0" json:"test_current,omitempty"` - UseDefaultOutbound *bool `protobuf:"varint,4,opt,name=use_default_outbound,json=useDefaultOutbound,def=0" json:"use_default_outbound,omitempty"` - TestDownload *bool `protobuf:"varint,5,opt,name=test_download,json=testDownload,def=0" json:"test_download,omitempty"` - TestUpload *bool `protobuf:"varint,6,opt,name=test_upload,json=testUpload,def=0" json:"test_upload,omitempty"` - SimpleDownload *bool `protobuf:"varint,7,opt,name=simple_download,json=simpleDownload,def=0" json:"simple_download,omitempty"` - SimpleDownloadAddr *string `protobuf:"bytes,8,opt,name=simple_download_addr,json=simpleDownloadAddr,def=" json:"simple_download_addr,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -// Default values for SpeedTestRequest fields. -const ( - Default_SpeedTestRequest_Config = string("") - Default_SpeedTestRequest_TestCurrent = bool(false) - Default_SpeedTestRequest_UseDefaultOutbound = bool(false) - Default_SpeedTestRequest_TestDownload = bool(false) - Default_SpeedTestRequest_TestUpload = bool(false) - Default_SpeedTestRequest_SimpleDownload = bool(false) - Default_SpeedTestRequest_SimpleDownloadAddr = string("") -) - -func (x *SpeedTestRequest) Reset() { - *x = SpeedTestRequest{} - mi := &file_libcore_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *SpeedTestRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SpeedTestRequest) ProtoMessage() {} - -func (x *SpeedTestRequest) ProtoReflect() protoreflect.Message { - mi := &file_libcore_proto_msgTypes[17] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SpeedTestRequest.ProtoReflect.Descriptor instead. -func (*SpeedTestRequest) Descriptor() ([]byte, []int) { - return file_libcore_proto_rawDescGZIP(), []int{17} -} - -func (x *SpeedTestRequest) GetConfig() string { - if x != nil && x.Config != nil { - return *x.Config - } - return Default_SpeedTestRequest_Config -} - -func (x *SpeedTestRequest) GetOutboundTags() []string { - if x != nil { - return x.OutboundTags - } - return nil -} - -func (x *SpeedTestRequest) GetTestCurrent() bool { - if x != nil && x.TestCurrent != nil { - return *x.TestCurrent - } - return Default_SpeedTestRequest_TestCurrent -} - -func (x *SpeedTestRequest) GetUseDefaultOutbound() bool { - if x != nil && x.UseDefaultOutbound != nil { - return *x.UseDefaultOutbound - } - return Default_SpeedTestRequest_UseDefaultOutbound -} - -func (x *SpeedTestRequest) GetTestDownload() bool { - if x != nil && x.TestDownload != nil { - return *x.TestDownload - } - return Default_SpeedTestRequest_TestDownload -} - -func (x *SpeedTestRequest) GetTestUpload() bool { - if x != nil && x.TestUpload != nil { - return *x.TestUpload - } - return Default_SpeedTestRequest_TestUpload -} - -func (x *SpeedTestRequest) GetSimpleDownload() bool { - if x != nil && x.SimpleDownload != nil { - return *x.SimpleDownload - } - return Default_SpeedTestRequest_SimpleDownload -} - -func (x *SpeedTestRequest) GetSimpleDownloadAddr() string { - if x != nil && x.SimpleDownloadAddr != nil { - return *x.SimpleDownloadAddr - } - return Default_SpeedTestRequest_SimpleDownloadAddr -} - -type SpeedTestResult struct { - state protoimpl.MessageState `protogen:"open.v1"` - DlSpeed *string `protobuf:"bytes,1,opt,name=dl_speed,json=dlSpeed,def=" json:"dl_speed,omitempty"` - UlSpeed *string `protobuf:"bytes,2,opt,name=ul_speed,json=ulSpeed,def=" json:"ul_speed,omitempty"` - Latency *int32 `protobuf:"varint,3,opt,name=latency,def=0" json:"latency,omitempty"` - OutboundTag *string `protobuf:"bytes,4,opt,name=outbound_tag,json=outboundTag,def=" json:"outbound_tag,omitempty"` - Error *string `protobuf:"bytes,5,opt,name=error,def=" json:"error,omitempty"` - ServerName *string `protobuf:"bytes,6,opt,name=server_name,json=serverName,def=" json:"server_name,omitempty"` - ServerCountry *string `protobuf:"bytes,7,opt,name=server_country,json=serverCountry,def=" json:"server_country,omitempty"` - Cancelled *bool `protobuf:"varint,8,opt,name=cancelled,def=0" json:"cancelled,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -// Default values for SpeedTestResult fields. -const ( - Default_SpeedTestResult_DlSpeed = string("") - Default_SpeedTestResult_UlSpeed = string("") - Default_SpeedTestResult_Latency = int32(0) - Default_SpeedTestResult_OutboundTag = string("") - Default_SpeedTestResult_Error = string("") - Default_SpeedTestResult_ServerName = string("") - Default_SpeedTestResult_ServerCountry = string("") - Default_SpeedTestResult_Cancelled = bool(false) -) - -func (x *SpeedTestResult) Reset() { - *x = SpeedTestResult{} - mi := &file_libcore_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *SpeedTestResult) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SpeedTestResult) ProtoMessage() {} - -func (x *SpeedTestResult) ProtoReflect() protoreflect.Message { - mi := &file_libcore_proto_msgTypes[18] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SpeedTestResult.ProtoReflect.Descriptor instead. -func (*SpeedTestResult) Descriptor() ([]byte, []int) { - return file_libcore_proto_rawDescGZIP(), []int{18} -} - -func (x *SpeedTestResult) GetDlSpeed() string { - if x != nil && x.DlSpeed != nil { - return *x.DlSpeed - } - return Default_SpeedTestResult_DlSpeed -} - -func (x *SpeedTestResult) GetUlSpeed() string { - if x != nil && x.UlSpeed != nil { - return *x.UlSpeed - } - return Default_SpeedTestResult_UlSpeed -} - -func (x *SpeedTestResult) GetLatency() int32 { - if x != nil && x.Latency != nil { - return *x.Latency - } - return Default_SpeedTestResult_Latency -} - -func (x *SpeedTestResult) GetOutboundTag() string { - if x != nil && x.OutboundTag != nil { - return *x.OutboundTag - } - return Default_SpeedTestResult_OutboundTag -} - -func (x *SpeedTestResult) GetError() string { - if x != nil && x.Error != nil { - return *x.Error - } - return Default_SpeedTestResult_Error -} - -func (x *SpeedTestResult) GetServerName() string { - if x != nil && x.ServerName != nil { - return *x.ServerName - } - return Default_SpeedTestResult_ServerName -} - -func (x *SpeedTestResult) GetServerCountry() string { - if x != nil && x.ServerCountry != nil { - return *x.ServerCountry - } - return Default_SpeedTestResult_ServerCountry -} - -func (x *SpeedTestResult) GetCancelled() bool { - if x != nil && x.Cancelled != nil { - return *x.Cancelled - } - return Default_SpeedTestResult_Cancelled -} - -type SpeedTestResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - Results []*SpeedTestResult `protobuf:"bytes,1,rep,name=results" json:"results,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *SpeedTestResponse) Reset() { - *x = SpeedTestResponse{} - mi := &file_libcore_proto_msgTypes[19] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *SpeedTestResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SpeedTestResponse) ProtoMessage() {} - -func (x *SpeedTestResponse) ProtoReflect() protoreflect.Message { - mi := &file_libcore_proto_msgTypes[19] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SpeedTestResponse.ProtoReflect.Descriptor instead. -func (*SpeedTestResponse) Descriptor() ([]byte, []int) { - return file_libcore_proto_rawDescGZIP(), []int{19} -} - -func (x *SpeedTestResponse) GetResults() []*SpeedTestResult { - if x != nil { - return x.Results - } - return nil -} - -type QuerySpeedTestResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - Result *SpeedTestResult `protobuf:"bytes,1,opt,name=result" json:"result,omitempty"` - IsRunning *bool `protobuf:"varint,2,opt,name=is_running,json=isRunning,def=0" json:"is_running,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -// Default values for QuerySpeedTestResponse fields. -const ( - Default_QuerySpeedTestResponse_IsRunning = bool(false) -) - -func (x *QuerySpeedTestResponse) Reset() { - *x = QuerySpeedTestResponse{} - mi := &file_libcore_proto_msgTypes[20] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *QuerySpeedTestResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*QuerySpeedTestResponse) ProtoMessage() {} - -func (x *QuerySpeedTestResponse) ProtoReflect() protoreflect.Message { - mi := &file_libcore_proto_msgTypes[20] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use QuerySpeedTestResponse.ProtoReflect.Descriptor instead. -func (*QuerySpeedTestResponse) Descriptor() ([]byte, []int) { - return file_libcore_proto_rawDescGZIP(), []int{20} -} - -func (x *QuerySpeedTestResponse) GetResult() *SpeedTestResult { - if x != nil { - return x.Result - } - return nil -} - -func (x *QuerySpeedTestResponse) GetIsRunning() bool { - if x != nil && x.IsRunning != nil { - return *x.IsRunning - } - return Default_QuerySpeedTestResponse_IsRunning -} - -type QueryURLTestResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - Results []*URLTestResp `protobuf:"bytes,1,rep,name=results" json:"results,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *QueryURLTestResponse) Reset() { - *x = QueryURLTestResponse{} - mi := &file_libcore_proto_msgTypes[21] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *QueryURLTestResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*QueryURLTestResponse) ProtoMessage() {} - -func (x *QueryURLTestResponse) ProtoReflect() protoreflect.Message { - mi := &file_libcore_proto_msgTypes[21] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use QueryURLTestResponse.ProtoReflect.Descriptor instead. -func (*QueryURLTestResponse) Descriptor() ([]byte, []int) { - return file_libcore_proto_rawDescGZIP(), []int{21} -} - -func (x *QueryURLTestResponse) GetResults() []*URLTestResp { - if x != nil { - return x.Results - } - return nil -} - -var File_libcore_proto protoreflect.FileDescriptor - -var file_libcore_proto_rawDesc = string([]byte{ - 0x0a, 0x0d, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, - 0x07, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x22, 0x0a, 0x0a, 0x08, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x52, 0x65, 0x71, 0x22, 0x0b, 0x0a, 0x09, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x73, - 0x70, 0x22, 0x23, 0x0a, 0x09, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x16, - 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x3a, 0x00, 0x52, - 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x83, 0x03, 0x0a, 0x0d, 0x4c, 0x6f, 0x61, 0x64, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x12, 0x21, 0x0a, 0x0b, 0x63, 0x6f, 0x72, 0x65, - 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x3a, 0x00, 0x52, - 0x0a, 0x63, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2a, 0x0a, 0x0d, 0x64, - 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, - 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x33, 0x0a, 0x12, 0x6e, 0x65, 0x65, 0x64, 0x5f, - 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x10, 0x6e, 0x65, 0x65, 0x64, - 0x45, 0x78, 0x74, 0x72, 0x61, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x2e, 0x0a, 0x12, - 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x70, 0x61, - 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x3a, 0x00, 0x52, 0x10, 0x65, 0x78, 0x74, 0x72, - 0x61, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x50, 0x61, 0x74, 0x68, 0x12, 0x2e, 0x0a, 0x12, - 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x61, 0x72, - 0x67, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x3a, 0x00, 0x52, 0x10, 0x65, 0x78, 0x74, 0x72, - 0x61, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x41, 0x72, 0x67, 0x73, 0x12, 0x2e, 0x0a, 0x12, - 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, - 0x6e, 0x66, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x3a, 0x00, 0x52, 0x10, 0x65, 0x78, 0x74, 0x72, - 0x61, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x35, 0x0a, 0x16, - 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, - 0x6e, 0x66, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x3a, 0x00, 0x52, 0x13, - 0x65, 0x78, 0x74, 0x72, 0x61, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x6e, 0x66, - 0x44, 0x69, 0x72, 0x12, 0x27, 0x0a, 0x0c, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x6e, 0x6f, 0x5f, - 0x6f, 0x75, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, - 0x52, 0x0a, 0x65, 0x78, 0x74, 0x72, 0x61, 0x4e, 0x6f, 0x4f, 0x75, 0x74, 0x22, 0x6c, 0x0a, 0x0b, - 0x55, 0x52, 0x4c, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x23, 0x0a, 0x0c, 0x6f, - 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x3a, 0x00, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, - 0x12, 0x20, 0x0a, 0x0a, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6d, 0x73, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x05, 0x3a, 0x01, 0x30, 0x52, 0x09, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, - 0x4d, 0x73, 0x12, 0x16, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x3a, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xeb, 0x01, 0x0a, 0x07, 0x54, - 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x12, 0x18, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x3a, 0x00, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x12, 0x23, 0x0a, 0x0d, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x67, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, - 0x64, 0x54, 0x61, 0x67, 0x73, 0x12, 0x37, 0x0a, 0x14, 0x75, 0x73, 0x65, 0x5f, 0x64, 0x65, 0x66, - 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x12, 0x75, 0x73, 0x65, 0x44, - 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x12, - 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x3a, 0x00, 0x52, 0x03, 0x75, - 0x72, 0x6c, 0x12, 0x28, 0x0a, 0x0c, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x65, - 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, - 0x0b, 0x74, 0x65, 0x73, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x0f, - 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x05, 0x3a, 0x01, 0x30, 0x52, 0x0e, 0x6d, 0x61, 0x78, 0x43, 0x6f, 0x6e, - 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x3a, 0x0a, 0x08, 0x54, 0x65, 0x73, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x12, 0x2e, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, - 0x55, 0x52, 0x4c, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x52, 0x07, 0x72, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x73, 0x22, 0xf0, 0x01, 0x0a, 0x0e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, - 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x12, 0x32, 0x0a, 0x03, 0x75, 0x70, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x2e, 0x55, 0x70, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x03, 0x75, 0x70, 0x73, 0x12, 0x38, 0x0a, 0x05, 0x64, - 0x6f, 0x77, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6c, 0x69, 0x62, - 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x2e, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, - 0x64, 0x6f, 0x77, 0x6e, 0x73, 0x1a, 0x36, 0x0a, 0x08, 0x55, 0x70, 0x73, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x38, 0x0a, - 0x0a, 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x54, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x43, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x12, 0x3d, - 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x43, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, - 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa6, 0x02, - 0x0a, 0x12, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, - 0x44, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x3a, 0x00, 0x52, 0x02, 0x69, 0x64, 0x12, 0x20, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x3a, 0x01, 0x30, 0x52, 0x09, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x19, 0x0a, 0x06, 0x75, 0x70, 0x6c, 0x6f, - 0x61, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x3a, 0x01, 0x30, 0x52, 0x06, 0x75, 0x70, 0x6c, - 0x6f, 0x61, 0x64, 0x12, 0x1d, 0x0a, 0x08, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x03, 0x3a, 0x01, 0x30, 0x52, 0x08, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, - 0x61, 0x64, 0x12, 0x1c, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x3a, 0x00, 0x52, 0x08, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, - 0x12, 0x1a, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x09, 0x3a, 0x00, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x14, 0x0a, 0x04, - 0x64, 0x65, 0x73, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x3a, 0x00, 0x52, 0x04, 0x64, 0x65, - 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x08, - 0x20, 0x01, 0x28, 0x09, 0x3a, 0x00, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, - 0x12, 0x18, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, - 0x3a, 0x00, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x1a, 0x0a, 0x07, 0x70, 0x72, - 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x3a, 0x00, 0x52, 0x07, 0x70, - 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x22, 0x2c, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x47, 0x65, 0x6f, - 0x49, 0x50, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, - 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x69, - 0x74, 0x65, 0x6d, 0x73, 0x22, 0x2e, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x47, 0x65, 0x6f, 0x53, 0x69, - 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, - 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x69, - 0x74, 0x65, 0x6d, 0x73, 0x22, 0x26, 0x0a, 0x0e, 0x47, 0x65, 0x6f, 0x4c, 0x69, 0x73, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x3a, 0x00, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x46, 0x0a, 0x18, - 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x54, 0x6f, 0x53, 0x72, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x3a, 0x00, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x12, 0x14, - 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x3a, 0x00, 0x52, 0x04, - 0x70, 0x61, 0x74, 0x68, 0x22, 0x48, 0x0a, 0x1a, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x47, - 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x54, 0x6f, 0x53, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x14, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x3a, 0x00, 0x52, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x12, 0x14, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x3a, 0x00, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x32, - 0x0a, 0x13, 0x53, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x44, 0x4e, 0x53, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x05, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x05, 0x63, 0x6c, 0x65, - 0x61, 0x72, 0x22, 0x42, 0x0a, 0x14, 0x49, 0x73, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, - 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x0d, 0x68, 0x61, - 0x73, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0c, 0x68, 0x61, 0x73, 0x50, 0x72, 0x69, - 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x22, 0xec, 0x02, 0x0a, 0x10, 0x53, 0x70, 0x65, 0x65, 0x64, - 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x06, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x3a, 0x00, 0x52, 0x06, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x23, 0x0a, 0x0d, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, - 0x64, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x6f, 0x75, - 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x61, 0x67, 0x73, 0x12, 0x28, 0x0a, 0x0c, 0x74, 0x65, - 0x73, 0x74, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, - 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x43, 0x75, 0x72, - 0x72, 0x65, 0x6e, 0x74, 0x12, 0x37, 0x0a, 0x14, 0x75, 0x73, 0x65, 0x5f, 0x64, 0x65, 0x66, 0x61, - 0x75, 0x6c, 0x74, 0x5f, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x12, 0x75, 0x73, 0x65, 0x44, 0x65, - 0x66, 0x61, 0x75, 0x6c, 0x74, 0x4f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x2a, 0x0a, - 0x0d, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0c, 0x74, 0x65, 0x73, - 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x26, 0x0a, 0x0b, 0x74, 0x65, 0x73, - 0x74, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, - 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, - 0x64, 0x12, 0x2e, 0x0a, 0x0f, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x64, 0x6f, 0x77, 0x6e, - 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, - 0x65, 0x52, 0x0e, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, - 0x64, 0x12, 0x32, 0x0a, 0x14, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x64, 0x6f, 0x77, 0x6e, - 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x3a, - 0x00, 0x52, 0x12, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, - 0x64, 0x41, 0x64, 0x64, 0x72, 0x22, 0x96, 0x02, 0x0a, 0x0f, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, - 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1b, 0x0a, 0x08, 0x64, 0x6c, 0x5f, - 0x73, 0x70, 0x65, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x3a, 0x00, 0x52, 0x07, 0x64, - 0x6c, 0x53, 0x70, 0x65, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x08, 0x75, 0x6c, 0x5f, 0x73, 0x70, 0x65, - 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x3a, 0x00, 0x52, 0x07, 0x75, 0x6c, 0x53, 0x70, - 0x65, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x07, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x05, 0x3a, 0x01, 0x30, 0x52, 0x07, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, - 0x12, 0x23, 0x0a, 0x0c, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x61, 0x67, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x3a, 0x00, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, - 0x6e, 0x64, 0x54, 0x61, 0x67, 0x12, 0x16, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x3a, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x21, 0x0a, - 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x09, 0x3a, 0x00, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x27, 0x0a, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x72, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x3a, 0x00, 0x52, 0x0d, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x23, 0x0a, 0x09, 0x63, 0x61, 0x6e, - 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, - 0x6c, 0x73, 0x65, 0x52, 0x09, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x64, 0x22, 0x47, - 0x0a, 0x11, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x53, - 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, - 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x70, 0x0a, 0x16, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x30, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x18, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x53, 0x70, 0x65, 0x65, - 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x12, 0x24, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, - 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x52, 0x09, - 0x69, 0x73, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x22, 0x46, 0x0a, 0x14, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x55, 0x52, 0x4c, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x55, 0x52, 0x4c, - 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x73, 0x32, 0x8d, 0x08, 0x0a, 0x0e, 0x4c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x12, 0x33, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x16, 0x2e, - 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, - 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x2d, 0x0a, 0x04, 0x53, 0x74, 0x6f, - 0x70, 0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x52, 0x65, 0x71, 0x1a, 0x12, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x39, 0x0a, 0x0b, 0x43, 0x68, 0x65, 0x63, - 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x16, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, - 0x65, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x1a, - 0x12, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, - 0x65, 0x73, 0x70, 0x12, 0x2b, 0x0a, 0x04, 0x54, 0x65, 0x73, 0x74, 0x12, 0x10, 0x2e, 0x6c, 0x69, - 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, - 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x12, 0x31, 0x0a, 0x08, 0x53, 0x74, 0x6f, 0x70, 0x54, 0x65, 0x73, 0x74, 0x12, 0x11, 0x2e, 0x6c, - 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, 0x1a, - 0x12, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, - 0x65, 0x73, 0x70, 0x12, 0x40, 0x0a, 0x0c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x55, 0x52, 0x4c, 0x54, - 0x65, 0x73, 0x74, 0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1d, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, - 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x55, 0x52, 0x4c, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x0a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, - 0x61, 0x74, 0x73, 0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x17, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, - 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x12, - 0x42, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1c, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x12, 0x46, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x4c, - 0x69, 0x73, 0x74, 0x12, 0x17, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x47, 0x65, - 0x6f, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, - 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x4c, - 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x0e, 0x47, - 0x65, 0x74, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x17, 0x2e, - 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x47, 0x65, 0x6f, 0x4c, 0x69, 0x73, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, - 0x2e, 0x47, 0x65, 0x74, 0x47, 0x65, 0x6f, 0x53, 0x69, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x11, 0x43, 0x6f, 0x6d, 0x70, 0x69, - 0x6c, 0x65, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x54, 0x6f, 0x53, 0x72, 0x73, 0x12, 0x21, 0x2e, 0x6c, - 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x47, 0x65, - 0x6f, 0x49, 0x50, 0x54, 0x6f, 0x53, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x12, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, - 0x65, 0x73, 0x70, 0x12, 0x4e, 0x0a, 0x13, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x47, 0x65, - 0x6f, 0x53, 0x69, 0x74, 0x65, 0x54, 0x6f, 0x53, 0x72, 0x73, 0x12, 0x23, 0x2e, 0x6c, 0x69, 0x62, - 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x47, 0x65, 0x6f, 0x53, - 0x69, 0x74, 0x65, 0x54, 0x6f, 0x53, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x12, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, - 0x65, 0x73, 0x70, 0x12, 0x40, 0x0a, 0x0c, 0x53, 0x65, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x44, 0x4e, 0x53, 0x12, 0x1c, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x53, 0x65, - 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x44, 0x4e, 0x53, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x12, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x52, 0x65, 0x73, 0x70, 0x12, 0x40, 0x0a, 0x0c, 0x49, 0x73, 0x50, 0x72, 0x69, 0x76, 0x69, - 0x6c, 0x65, 0x67, 0x65, 0x64, 0x12, 0x11, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, 0x1a, 0x1d, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, - 0x72, 0x65, 0x2e, 0x49, 0x73, 0x50, 0x72, 0x69, 0x76, 0x69, 0x6c, 0x65, 0x67, 0x65, 0x64, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x09, 0x53, 0x70, 0x65, 0x65, 0x64, - 0x54, 0x65, 0x73, 0x74, 0x12, 0x19, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x53, - 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1a, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, - 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0e, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x12, 0x11, 0x2e, - 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, - 0x1a, 0x1f, 0x2e, 0x6c, 0x69, 0x62, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x53, 0x70, 0x65, 0x65, 0x64, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x42, 0x13, 0x48, 0x03, 0x5a, 0x0f, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x2f, 0x67, 0x65, 0x6e, -}) - -var ( - file_libcore_proto_rawDescOnce sync.Once - file_libcore_proto_rawDescData []byte -) - -func file_libcore_proto_rawDescGZIP() []byte { - file_libcore_proto_rawDescOnce.Do(func() { - file_libcore_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_libcore_proto_rawDesc), len(file_libcore_proto_rawDesc))) - }) - return file_libcore_proto_rawDescData -} - -var file_libcore_proto_msgTypes = make([]protoimpl.MessageInfo, 24) -var file_libcore_proto_goTypes = []any{ - (*EmptyReq)(nil), // 0: libcore.EmptyReq - (*EmptyResp)(nil), // 1: libcore.EmptyResp - (*ErrorResp)(nil), // 2: libcore.ErrorResp - (*LoadConfigReq)(nil), // 3: libcore.LoadConfigReq - (*URLTestResp)(nil), // 4: libcore.URLTestResp - (*TestReq)(nil), // 5: libcore.TestReq - (*TestResp)(nil), // 6: libcore.TestResp - (*QueryStatsResp)(nil), // 7: libcore.QueryStatsResp - (*ListConnectionsResp)(nil), // 8: libcore.ListConnectionsResp - (*ConnectionMetaData)(nil), // 9: libcore.ConnectionMetaData - (*GetGeoIPListResponse)(nil), // 10: libcore.GetGeoIPListResponse - (*GetGeoSiteListResponse)(nil), // 11: libcore.GetGeoSiteListResponse - (*GeoListRequest)(nil), // 12: libcore.GeoListRequest - (*CompileGeoIPToSrsRequest)(nil), // 13: libcore.CompileGeoIPToSrsRequest - (*CompileGeoSiteToSrsRequest)(nil), // 14: libcore.CompileGeoSiteToSrsRequest - (*SetSystemDNSRequest)(nil), // 15: libcore.SetSystemDNSRequest - (*IsPrivilegedResponse)(nil), // 16: libcore.IsPrivilegedResponse - (*SpeedTestRequest)(nil), // 17: libcore.SpeedTestRequest - (*SpeedTestResult)(nil), // 18: libcore.SpeedTestResult - (*SpeedTestResponse)(nil), // 19: libcore.SpeedTestResponse - (*QuerySpeedTestResponse)(nil), // 20: libcore.QuerySpeedTestResponse - (*QueryURLTestResponse)(nil), // 21: libcore.QueryURLTestResponse - nil, // 22: libcore.QueryStatsResp.UpsEntry - nil, // 23: libcore.QueryStatsResp.DownsEntry -} -var file_libcore_proto_depIdxs = []int32{ - 4, // 0: libcore.TestResp.results:type_name -> libcore.URLTestResp - 22, // 1: libcore.QueryStatsResp.ups:type_name -> libcore.QueryStatsResp.UpsEntry - 23, // 2: libcore.QueryStatsResp.downs:type_name -> libcore.QueryStatsResp.DownsEntry - 9, // 3: libcore.ListConnectionsResp.connections:type_name -> libcore.ConnectionMetaData - 18, // 4: libcore.SpeedTestResponse.results:type_name -> libcore.SpeedTestResult - 18, // 5: libcore.QuerySpeedTestResponse.result:type_name -> libcore.SpeedTestResult - 4, // 6: libcore.QueryURLTestResponse.results:type_name -> libcore.URLTestResp - 3, // 7: libcore.LibcoreService.Start:input_type -> libcore.LoadConfigReq - 0, // 8: libcore.LibcoreService.Stop:input_type -> libcore.EmptyReq - 3, // 9: libcore.LibcoreService.CheckConfig:input_type -> libcore.LoadConfigReq - 5, // 10: libcore.LibcoreService.Test:input_type -> libcore.TestReq - 0, // 11: libcore.LibcoreService.StopTest:input_type -> libcore.EmptyReq - 0, // 12: libcore.LibcoreService.QueryURLTest:input_type -> libcore.EmptyReq - 0, // 13: libcore.LibcoreService.QueryStats:input_type -> libcore.EmptyReq - 0, // 14: libcore.LibcoreService.ListConnections:input_type -> libcore.EmptyReq - 12, // 15: libcore.LibcoreService.GetGeoIPList:input_type -> libcore.GeoListRequest - 12, // 16: libcore.LibcoreService.GetGeoSiteList:input_type -> libcore.GeoListRequest - 13, // 17: libcore.LibcoreService.CompileGeoIPToSrs:input_type -> libcore.CompileGeoIPToSrsRequest - 14, // 18: libcore.LibcoreService.CompileGeoSiteToSrs:input_type -> libcore.CompileGeoSiteToSrsRequest - 15, // 19: libcore.LibcoreService.SetSystemDNS:input_type -> libcore.SetSystemDNSRequest - 0, // 20: libcore.LibcoreService.IsPrivileged:input_type -> libcore.EmptyReq - 17, // 21: libcore.LibcoreService.SpeedTest:input_type -> libcore.SpeedTestRequest - 0, // 22: libcore.LibcoreService.QuerySpeedTest:input_type -> libcore.EmptyReq - 2, // 23: libcore.LibcoreService.Start:output_type -> libcore.ErrorResp - 2, // 24: libcore.LibcoreService.Stop:output_type -> libcore.ErrorResp - 2, // 25: libcore.LibcoreService.CheckConfig:output_type -> libcore.ErrorResp - 6, // 26: libcore.LibcoreService.Test:output_type -> libcore.TestResp - 1, // 27: libcore.LibcoreService.StopTest:output_type -> libcore.EmptyResp - 21, // 28: libcore.LibcoreService.QueryURLTest:output_type -> libcore.QueryURLTestResponse - 7, // 29: libcore.LibcoreService.QueryStats:output_type -> libcore.QueryStatsResp - 8, // 30: libcore.LibcoreService.ListConnections:output_type -> libcore.ListConnectionsResp - 10, // 31: libcore.LibcoreService.GetGeoIPList:output_type -> libcore.GetGeoIPListResponse - 11, // 32: libcore.LibcoreService.GetGeoSiteList:output_type -> libcore.GetGeoSiteListResponse - 1, // 33: libcore.LibcoreService.CompileGeoIPToSrs:output_type -> libcore.EmptyResp - 1, // 34: libcore.LibcoreService.CompileGeoSiteToSrs:output_type -> libcore.EmptyResp - 1, // 35: libcore.LibcoreService.SetSystemDNS:output_type -> libcore.EmptyResp - 16, // 36: libcore.LibcoreService.IsPrivileged:output_type -> libcore.IsPrivilegedResponse - 19, // 37: libcore.LibcoreService.SpeedTest:output_type -> libcore.SpeedTestResponse - 20, // 38: libcore.LibcoreService.QuerySpeedTest:output_type -> libcore.QuerySpeedTestResponse - 23, // [23:39] is the sub-list for method output_type - 7, // [7:23] is the sub-list for method input_type - 7, // [7:7] is the sub-list for extension type_name - 7, // [7:7] is the sub-list for extension extendee - 0, // [0:7] is the sub-list for field type_name -} - -func init() { file_libcore_proto_init() } -func file_libcore_proto_init() { - if File_libcore_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_libcore_proto_rawDesc), len(file_libcore_proto_rawDesc)), - NumEnums: 0, - NumMessages: 24, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_libcore_proto_goTypes, - DependencyIndexes: file_libcore_proto_depIdxs, - MessageInfos: file_libcore_proto_msgTypes, - }.Build() - File_libcore_proto = out.File - file_libcore_proto_goTypes = nil - file_libcore_proto_depIdxs = nil -} diff --git a/core/server/gen/libcore.proto b/core/server/gen/libcore.proto index fe242d3..6dae321 100644 --- a/core/server/gen/libcore.proto +++ b/core/server/gen/libcore.proto @@ -1,8 +1,7 @@ syntax = "proto2"; package libcore; -option go_package = "grpc_server/gen"; -option optimize_for = LITE_RUNTIME; +option go_package = "./;gen"; service LibcoreService { rpc Start(LoadConfigReq) returns (ErrorResp); diff --git a/core/server/gen/libcore_grpc.pb.go b/core/server/gen/libcore_grpc.pb.go deleted file mode 100644 index 1985821..0000000 --- a/core/server/gen/libcore_grpc.pb.go +++ /dev/null @@ -1,691 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.5.1 -// - protoc v5.29.3 -// source: libcore.proto - -package gen - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.64.0 or later. -const _ = grpc.SupportPackageIsVersion9 - -const ( - LibcoreService_Start_FullMethodName = "/libcore.LibcoreService/Start" - LibcoreService_Stop_FullMethodName = "/libcore.LibcoreService/Stop" - LibcoreService_CheckConfig_FullMethodName = "/libcore.LibcoreService/CheckConfig" - LibcoreService_Test_FullMethodName = "/libcore.LibcoreService/Test" - LibcoreService_StopTest_FullMethodName = "/libcore.LibcoreService/StopTest" - LibcoreService_QueryURLTest_FullMethodName = "/libcore.LibcoreService/QueryURLTest" - LibcoreService_QueryStats_FullMethodName = "/libcore.LibcoreService/QueryStats" - LibcoreService_ListConnections_FullMethodName = "/libcore.LibcoreService/ListConnections" - LibcoreService_GetGeoIPList_FullMethodName = "/libcore.LibcoreService/GetGeoIPList" - LibcoreService_GetGeoSiteList_FullMethodName = "/libcore.LibcoreService/GetGeoSiteList" - LibcoreService_CompileGeoIPToSrs_FullMethodName = "/libcore.LibcoreService/CompileGeoIPToSrs" - LibcoreService_CompileGeoSiteToSrs_FullMethodName = "/libcore.LibcoreService/CompileGeoSiteToSrs" - LibcoreService_SetSystemDNS_FullMethodName = "/libcore.LibcoreService/SetSystemDNS" - LibcoreService_IsPrivileged_FullMethodName = "/libcore.LibcoreService/IsPrivileged" - LibcoreService_SpeedTest_FullMethodName = "/libcore.LibcoreService/SpeedTest" - LibcoreService_QuerySpeedTest_FullMethodName = "/libcore.LibcoreService/QuerySpeedTest" -) - -// LibcoreServiceClient is the client API for LibcoreService service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type LibcoreServiceClient interface { - Start(ctx context.Context, in *LoadConfigReq, opts ...grpc.CallOption) (*ErrorResp, error) - Stop(ctx context.Context, in *EmptyReq, opts ...grpc.CallOption) (*ErrorResp, error) - CheckConfig(ctx context.Context, in *LoadConfigReq, opts ...grpc.CallOption) (*ErrorResp, error) - Test(ctx context.Context, in *TestReq, opts ...grpc.CallOption) (*TestResp, error) - StopTest(ctx context.Context, in *EmptyReq, opts ...grpc.CallOption) (*EmptyResp, error) - QueryURLTest(ctx context.Context, in *EmptyReq, opts ...grpc.CallOption) (*QueryURLTestResponse, error) - QueryStats(ctx context.Context, in *EmptyReq, opts ...grpc.CallOption) (*QueryStatsResp, error) - ListConnections(ctx context.Context, in *EmptyReq, opts ...grpc.CallOption) (*ListConnectionsResp, error) - GetGeoIPList(ctx context.Context, in *GeoListRequest, opts ...grpc.CallOption) (*GetGeoIPListResponse, error) - GetGeoSiteList(ctx context.Context, in *GeoListRequest, opts ...grpc.CallOption) (*GetGeoSiteListResponse, error) - CompileGeoIPToSrs(ctx context.Context, in *CompileGeoIPToSrsRequest, opts ...grpc.CallOption) (*EmptyResp, error) - CompileGeoSiteToSrs(ctx context.Context, in *CompileGeoSiteToSrsRequest, opts ...grpc.CallOption) (*EmptyResp, error) - SetSystemDNS(ctx context.Context, in *SetSystemDNSRequest, opts ...grpc.CallOption) (*EmptyResp, error) - IsPrivileged(ctx context.Context, in *EmptyReq, opts ...grpc.CallOption) (*IsPrivilegedResponse, error) - SpeedTest(ctx context.Context, in *SpeedTestRequest, opts ...grpc.CallOption) (*SpeedTestResponse, error) - QuerySpeedTest(ctx context.Context, in *EmptyReq, opts ...grpc.CallOption) (*QuerySpeedTestResponse, error) -} - -type libcoreServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewLibcoreServiceClient(cc grpc.ClientConnInterface) LibcoreServiceClient { - return &libcoreServiceClient{cc} -} - -func (c *libcoreServiceClient) Start(ctx context.Context, in *LoadConfigReq, opts ...grpc.CallOption) (*ErrorResp, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(ErrorResp) - err := c.cc.Invoke(ctx, LibcoreService_Start_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *libcoreServiceClient) Stop(ctx context.Context, in *EmptyReq, opts ...grpc.CallOption) (*ErrorResp, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(ErrorResp) - err := c.cc.Invoke(ctx, LibcoreService_Stop_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *libcoreServiceClient) CheckConfig(ctx context.Context, in *LoadConfigReq, opts ...grpc.CallOption) (*ErrorResp, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(ErrorResp) - err := c.cc.Invoke(ctx, LibcoreService_CheckConfig_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *libcoreServiceClient) Test(ctx context.Context, in *TestReq, opts ...grpc.CallOption) (*TestResp, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(TestResp) - err := c.cc.Invoke(ctx, LibcoreService_Test_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *libcoreServiceClient) StopTest(ctx context.Context, in *EmptyReq, opts ...grpc.CallOption) (*EmptyResp, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(EmptyResp) - err := c.cc.Invoke(ctx, LibcoreService_StopTest_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *libcoreServiceClient) QueryURLTest(ctx context.Context, in *EmptyReq, opts ...grpc.CallOption) (*QueryURLTestResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(QueryURLTestResponse) - err := c.cc.Invoke(ctx, LibcoreService_QueryURLTest_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *libcoreServiceClient) QueryStats(ctx context.Context, in *EmptyReq, opts ...grpc.CallOption) (*QueryStatsResp, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(QueryStatsResp) - err := c.cc.Invoke(ctx, LibcoreService_QueryStats_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *libcoreServiceClient) ListConnections(ctx context.Context, in *EmptyReq, opts ...grpc.CallOption) (*ListConnectionsResp, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(ListConnectionsResp) - err := c.cc.Invoke(ctx, LibcoreService_ListConnections_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *libcoreServiceClient) GetGeoIPList(ctx context.Context, in *GeoListRequest, opts ...grpc.CallOption) (*GetGeoIPListResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(GetGeoIPListResponse) - err := c.cc.Invoke(ctx, LibcoreService_GetGeoIPList_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *libcoreServiceClient) GetGeoSiteList(ctx context.Context, in *GeoListRequest, opts ...grpc.CallOption) (*GetGeoSiteListResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(GetGeoSiteListResponse) - err := c.cc.Invoke(ctx, LibcoreService_GetGeoSiteList_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *libcoreServiceClient) CompileGeoIPToSrs(ctx context.Context, in *CompileGeoIPToSrsRequest, opts ...grpc.CallOption) (*EmptyResp, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(EmptyResp) - err := c.cc.Invoke(ctx, LibcoreService_CompileGeoIPToSrs_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *libcoreServiceClient) CompileGeoSiteToSrs(ctx context.Context, in *CompileGeoSiteToSrsRequest, opts ...grpc.CallOption) (*EmptyResp, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(EmptyResp) - err := c.cc.Invoke(ctx, LibcoreService_CompileGeoSiteToSrs_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *libcoreServiceClient) SetSystemDNS(ctx context.Context, in *SetSystemDNSRequest, opts ...grpc.CallOption) (*EmptyResp, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(EmptyResp) - err := c.cc.Invoke(ctx, LibcoreService_SetSystemDNS_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *libcoreServiceClient) IsPrivileged(ctx context.Context, in *EmptyReq, opts ...grpc.CallOption) (*IsPrivilegedResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(IsPrivilegedResponse) - err := c.cc.Invoke(ctx, LibcoreService_IsPrivileged_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *libcoreServiceClient) SpeedTest(ctx context.Context, in *SpeedTestRequest, opts ...grpc.CallOption) (*SpeedTestResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(SpeedTestResponse) - err := c.cc.Invoke(ctx, LibcoreService_SpeedTest_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *libcoreServiceClient) QuerySpeedTest(ctx context.Context, in *EmptyReq, opts ...grpc.CallOption) (*QuerySpeedTestResponse, error) { - cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(QuerySpeedTestResponse) - err := c.cc.Invoke(ctx, LibcoreService_QuerySpeedTest_FullMethodName, in, out, cOpts...) - if err != nil { - return nil, err - } - return out, nil -} - -// LibcoreServiceServer is the server API for LibcoreService service. -// All implementations must embed UnimplementedLibcoreServiceServer -// for forward compatibility. -type LibcoreServiceServer interface { - Start(context.Context, *LoadConfigReq) (*ErrorResp, error) - Stop(context.Context, *EmptyReq) (*ErrorResp, error) - CheckConfig(context.Context, *LoadConfigReq) (*ErrorResp, error) - Test(context.Context, *TestReq) (*TestResp, error) - StopTest(context.Context, *EmptyReq) (*EmptyResp, error) - QueryURLTest(context.Context, *EmptyReq) (*QueryURLTestResponse, error) - QueryStats(context.Context, *EmptyReq) (*QueryStatsResp, error) - ListConnections(context.Context, *EmptyReq) (*ListConnectionsResp, error) - GetGeoIPList(context.Context, *GeoListRequest) (*GetGeoIPListResponse, error) - GetGeoSiteList(context.Context, *GeoListRequest) (*GetGeoSiteListResponse, error) - CompileGeoIPToSrs(context.Context, *CompileGeoIPToSrsRequest) (*EmptyResp, error) - CompileGeoSiteToSrs(context.Context, *CompileGeoSiteToSrsRequest) (*EmptyResp, error) - SetSystemDNS(context.Context, *SetSystemDNSRequest) (*EmptyResp, error) - IsPrivileged(context.Context, *EmptyReq) (*IsPrivilegedResponse, error) - SpeedTest(context.Context, *SpeedTestRequest) (*SpeedTestResponse, error) - QuerySpeedTest(context.Context, *EmptyReq) (*QuerySpeedTestResponse, error) - mustEmbedUnimplementedLibcoreServiceServer() -} - -// UnimplementedLibcoreServiceServer must be embedded to have -// forward compatible implementations. -// -// NOTE: this should be embedded by value instead of pointer to avoid a nil -// pointer dereference when methods are called. -type UnimplementedLibcoreServiceServer struct{} - -func (UnimplementedLibcoreServiceServer) Start(context.Context, *LoadConfigReq) (*ErrorResp, error) { - return nil, status.Errorf(codes.Unimplemented, "method Start not implemented") -} -func (UnimplementedLibcoreServiceServer) Stop(context.Context, *EmptyReq) (*ErrorResp, error) { - return nil, status.Errorf(codes.Unimplemented, "method Stop not implemented") -} -func (UnimplementedLibcoreServiceServer) CheckConfig(context.Context, *LoadConfigReq) (*ErrorResp, error) { - return nil, status.Errorf(codes.Unimplemented, "method CheckConfig not implemented") -} -func (UnimplementedLibcoreServiceServer) Test(context.Context, *TestReq) (*TestResp, error) { - return nil, status.Errorf(codes.Unimplemented, "method Test not implemented") -} -func (UnimplementedLibcoreServiceServer) StopTest(context.Context, *EmptyReq) (*EmptyResp, error) { - return nil, status.Errorf(codes.Unimplemented, "method StopTest not implemented") -} -func (UnimplementedLibcoreServiceServer) QueryURLTest(context.Context, *EmptyReq) (*QueryURLTestResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method QueryURLTest not implemented") -} -func (UnimplementedLibcoreServiceServer) QueryStats(context.Context, *EmptyReq) (*QueryStatsResp, error) { - return nil, status.Errorf(codes.Unimplemented, "method QueryStats not implemented") -} -func (UnimplementedLibcoreServiceServer) ListConnections(context.Context, *EmptyReq) (*ListConnectionsResp, error) { - return nil, status.Errorf(codes.Unimplemented, "method ListConnections not implemented") -} -func (UnimplementedLibcoreServiceServer) GetGeoIPList(context.Context, *GeoListRequest) (*GetGeoIPListResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetGeoIPList not implemented") -} -func (UnimplementedLibcoreServiceServer) GetGeoSiteList(context.Context, *GeoListRequest) (*GetGeoSiteListResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetGeoSiteList not implemented") -} -func (UnimplementedLibcoreServiceServer) CompileGeoIPToSrs(context.Context, *CompileGeoIPToSrsRequest) (*EmptyResp, error) { - return nil, status.Errorf(codes.Unimplemented, "method CompileGeoIPToSrs not implemented") -} -func (UnimplementedLibcoreServiceServer) CompileGeoSiteToSrs(context.Context, *CompileGeoSiteToSrsRequest) (*EmptyResp, error) { - return nil, status.Errorf(codes.Unimplemented, "method CompileGeoSiteToSrs not implemented") -} -func (UnimplementedLibcoreServiceServer) SetSystemDNS(context.Context, *SetSystemDNSRequest) (*EmptyResp, error) { - return nil, status.Errorf(codes.Unimplemented, "method SetSystemDNS not implemented") -} -func (UnimplementedLibcoreServiceServer) IsPrivileged(context.Context, *EmptyReq) (*IsPrivilegedResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method IsPrivileged not implemented") -} -func (UnimplementedLibcoreServiceServer) SpeedTest(context.Context, *SpeedTestRequest) (*SpeedTestResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method SpeedTest not implemented") -} -func (UnimplementedLibcoreServiceServer) QuerySpeedTest(context.Context, *EmptyReq) (*QuerySpeedTestResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method QuerySpeedTest not implemented") -} -func (UnimplementedLibcoreServiceServer) mustEmbedUnimplementedLibcoreServiceServer() {} -func (UnimplementedLibcoreServiceServer) testEmbeddedByValue() {} - -// UnsafeLibcoreServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to LibcoreServiceServer will -// result in compilation errors. -type UnsafeLibcoreServiceServer interface { - mustEmbedUnimplementedLibcoreServiceServer() -} - -func RegisterLibcoreServiceServer(s grpc.ServiceRegistrar, srv LibcoreServiceServer) { - // If the following call pancis, it indicates UnimplementedLibcoreServiceServer was - // embedded by pointer and is nil. This will cause panics if an - // unimplemented method is ever invoked, so we test this at initialization - // time to prevent it from happening at runtime later due to I/O. - if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { - t.testEmbeddedByValue() - } - s.RegisterService(&LibcoreService_ServiceDesc, srv) -} - -func _LibcoreService_Start_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(LoadConfigReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(LibcoreServiceServer).Start(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: LibcoreService_Start_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(LibcoreServiceServer).Start(ctx, req.(*LoadConfigReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _LibcoreService_Stop_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(EmptyReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(LibcoreServiceServer).Stop(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: LibcoreService_Stop_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(LibcoreServiceServer).Stop(ctx, req.(*EmptyReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _LibcoreService_CheckConfig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(LoadConfigReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(LibcoreServiceServer).CheckConfig(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: LibcoreService_CheckConfig_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(LibcoreServiceServer).CheckConfig(ctx, req.(*LoadConfigReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _LibcoreService_Test_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(TestReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(LibcoreServiceServer).Test(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: LibcoreService_Test_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(LibcoreServiceServer).Test(ctx, req.(*TestReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _LibcoreService_StopTest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(EmptyReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(LibcoreServiceServer).StopTest(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: LibcoreService_StopTest_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(LibcoreServiceServer).StopTest(ctx, req.(*EmptyReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _LibcoreService_QueryURLTest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(EmptyReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(LibcoreServiceServer).QueryURLTest(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: LibcoreService_QueryURLTest_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(LibcoreServiceServer).QueryURLTest(ctx, req.(*EmptyReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _LibcoreService_QueryStats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(EmptyReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(LibcoreServiceServer).QueryStats(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: LibcoreService_QueryStats_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(LibcoreServiceServer).QueryStats(ctx, req.(*EmptyReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _LibcoreService_ListConnections_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(EmptyReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(LibcoreServiceServer).ListConnections(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: LibcoreService_ListConnections_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(LibcoreServiceServer).ListConnections(ctx, req.(*EmptyReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _LibcoreService_GetGeoIPList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GeoListRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(LibcoreServiceServer).GetGeoIPList(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: LibcoreService_GetGeoIPList_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(LibcoreServiceServer).GetGeoIPList(ctx, req.(*GeoListRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _LibcoreService_GetGeoSiteList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GeoListRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(LibcoreServiceServer).GetGeoSiteList(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: LibcoreService_GetGeoSiteList_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(LibcoreServiceServer).GetGeoSiteList(ctx, req.(*GeoListRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _LibcoreService_CompileGeoIPToSrs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(CompileGeoIPToSrsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(LibcoreServiceServer).CompileGeoIPToSrs(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: LibcoreService_CompileGeoIPToSrs_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(LibcoreServiceServer).CompileGeoIPToSrs(ctx, req.(*CompileGeoIPToSrsRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _LibcoreService_CompileGeoSiteToSrs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(CompileGeoSiteToSrsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(LibcoreServiceServer).CompileGeoSiteToSrs(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: LibcoreService_CompileGeoSiteToSrs_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(LibcoreServiceServer).CompileGeoSiteToSrs(ctx, req.(*CompileGeoSiteToSrsRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _LibcoreService_SetSystemDNS_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SetSystemDNSRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(LibcoreServiceServer).SetSystemDNS(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: LibcoreService_SetSystemDNS_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(LibcoreServiceServer).SetSystemDNS(ctx, req.(*SetSystemDNSRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _LibcoreService_IsPrivileged_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(EmptyReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(LibcoreServiceServer).IsPrivileged(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: LibcoreService_IsPrivileged_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(LibcoreServiceServer).IsPrivileged(ctx, req.(*EmptyReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _LibcoreService_SpeedTest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SpeedTestRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(LibcoreServiceServer).SpeedTest(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: LibcoreService_SpeedTest_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(LibcoreServiceServer).SpeedTest(ctx, req.(*SpeedTestRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _LibcoreService_QuerySpeedTest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(EmptyReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(LibcoreServiceServer).QuerySpeedTest(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: LibcoreService_QuerySpeedTest_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(LibcoreServiceServer).QuerySpeedTest(ctx, req.(*EmptyReq)) - } - return interceptor(ctx, in, info, handler) -} - -// LibcoreService_ServiceDesc is the grpc.ServiceDesc for LibcoreService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var LibcoreService_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "libcore.LibcoreService", - HandlerType: (*LibcoreServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "Start", - Handler: _LibcoreService_Start_Handler, - }, - { - MethodName: "Stop", - Handler: _LibcoreService_Stop_Handler, - }, - { - MethodName: "CheckConfig", - Handler: _LibcoreService_CheckConfig_Handler, - }, - { - MethodName: "Test", - Handler: _LibcoreService_Test_Handler, - }, - { - MethodName: "StopTest", - Handler: _LibcoreService_StopTest_Handler, - }, - { - MethodName: "QueryURLTest", - Handler: _LibcoreService_QueryURLTest_Handler, - }, - { - MethodName: "QueryStats", - Handler: _LibcoreService_QueryStats_Handler, - }, - { - MethodName: "ListConnections", - Handler: _LibcoreService_ListConnections_Handler, - }, - { - MethodName: "GetGeoIPList", - Handler: _LibcoreService_GetGeoIPList_Handler, - }, - { - MethodName: "GetGeoSiteList", - Handler: _LibcoreService_GetGeoSiteList_Handler, - }, - { - MethodName: "CompileGeoIPToSrs", - Handler: _LibcoreService_CompileGeoIPToSrs_Handler, - }, - { - MethodName: "CompileGeoSiteToSrs", - Handler: _LibcoreService_CompileGeoSiteToSrs_Handler, - }, - { - MethodName: "SetSystemDNS", - Handler: _LibcoreService_SetSystemDNS_Handler, - }, - { - MethodName: "IsPrivileged", - Handler: _LibcoreService_IsPrivileged_Handler, - }, - { - MethodName: "SpeedTest", - Handler: _LibcoreService_SpeedTest_Handler, - }, - { - MethodName: "QuerySpeedTest", - Handler: _LibcoreService_QuerySpeedTest_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "libcore.proto", -} diff --git a/core/server/go.mod b/core/server/go.mod index 128a9ee..b13b1fb 100644 --- a/core/server/go.mod +++ b/core/server/go.mod @@ -2,12 +2,12 @@ module Core go 1.23.6 -toolchain go1.24.4 - require ( github.com/Mahdi-zarei/speedtest-go v1.7.12 + github.com/chai2010/protorpc v1.1.4 github.com/dustin/go-humanize v1.0.1 github.com/gofrs/uuid/v5 v5.3.2 + github.com/golang/protobuf v1.5.4 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/oschwald/maxminddb-golang v1.13.1 github.com/sagernet/sing v0.6.11 @@ -16,7 +16,6 @@ require ( github.com/sagernet/sing-tun v0.6.9 github.com/spf13/cobra v1.9.1 golang.org/x/sys v0.34.0 - google.golang.org/grpc v1.74.2 google.golang.org/protobuf v1.36.6 ) @@ -26,6 +25,8 @@ replace github.com/sagernet/sing-dns => github.com/Mahdi-zarei/sing-dns v0.3.0-b replace github.com/sagernet/wireguard-go => github.com/throneproj/wireguard-go v0.0.1-beta.7.0.20250728063157-408bba78ad26 +replace github.com/chai2010/protorpc => ../protorpc + require ( github.com/ajg/form v1.5.1 // indirect github.com/andybalholm/brotli v1.0.6 // indirect @@ -97,6 +98,7 @@ require ( golang.org/x/time v0.7.0 // indirect golang.org/x/tools v0.28.0 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect + google.golang.org/grpc v1.63.2 // indirect lukechampine.com/blake3 v1.3.0 // indirect ) diff --git a/core/server/go.sum b/core/server/go.sum index 325c48d..5a8cef0 100644 --- a/core/server/go.sum +++ b/core/server/go.sum @@ -24,10 +24,8 @@ github.com/go-chi/chi/v5 v5.2.2 h1:CMwsvRVTbXVytCk1Wd72Zy1LAsAh9GxMmSNWLHCG618= github.com/go-chi/chi/v5 v5.2.2/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops= github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4= github.com/go-chi/render v1.0.3/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0= -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= @@ -48,8 +46,6 @@ github.com/google/pprof v0.0.0-20231101202521-4ca4178f5c7a h1:fEBsGL/sjAuJrgah5X github.com/google/pprof v0.0.0-20231101202521-4ca4178f5c7a/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8= github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -171,18 +167,6 @@ github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg= github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ= github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= -go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= -go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg= -go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E= -go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE= -go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= -go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs= -go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY= -go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis= -go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= -go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= -go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -227,10 +211,10 @@ golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4= -google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY= +google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= +google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/core/server/main.go b/core/server/main.go index e6e33a8..6649409 100644 --- a/core/server/main.go +++ b/core/server/main.go @@ -6,9 +6,7 @@ import ( "context" "flag" "fmt" - "google.golang.org/grpc" "log" - "net" "os" "runtime" runtimeDebug "runtime/debug" @@ -46,22 +44,12 @@ func RunCore() { }() boxmain.DisableColor() - // GRPC - lis, err := net.Listen("tcp", "127.0.0.1:"+strconv.Itoa(*_port)) + // RPC + fmt.Printf("Core listening at %v\n", "127.0.0.1:"+strconv.Itoa(*_port)) + err := gen.ListenAndServeLibcoreService("tcp", "127.0.0.1:"+strconv.Itoa(*_port), new(server)) if err != nil { log.Fatalf("failed to listen: %v", err) } - - s := grpc.NewServer( - grpc.MaxRecvMsgSize(1024*1024*1024), // 1 gigaByte - grpc.MaxSendMsgSize(1024*1024*1024), // 1 gigaByte - ) - gen.RegisterLibcoreServiceServer(s, &server{}) - - fmt.Printf("Core listening at %v\n", lis.Addr()) - if err := s.Serve(lis); err != nil { - log.Fatalf("failed to serve: %v", err) - } } func main() { diff --git a/core/server/server.go b/core/server/server.go index e1c21cb..e2f2ab3 100644 --- a/core/server/server.go +++ b/core/server/server.go @@ -31,20 +31,17 @@ var systemProxyAddr metadata.Socksaddr var instanceCancel context.CancelFunc var debug bool -type server struct { - gen.UnimplementedLibcoreServiceServer -} +type server int // To returns a pointer to the given value. func To[T any](v T) *T { return &v } -func (s *server) Start(ctx context.Context, in *gen.LoadConfigReq) (out *gen.ErrorResp, _ error) { +func (s *server) Start(in *gen.LoadConfigReq, out *gen.ErrorResp) (_ error) { var err error defer func() { - out = &gen.ErrorResp{} if err != nil { out.Error = To(err.Error()) boxInstance = nil @@ -107,11 +104,10 @@ func (s *server) Start(ctx context.Context, in *gen.LoadConfigReq) (out *gen.Err return } -func (s *server) Stop(ctx context.Context, in *gen.EmptyReq) (out *gen.ErrorResp, _ error) { +func (s *server) Stop(in *gen.EmptyReq, out *gen.ErrorResp) (_ error) { var err error defer func() { - out = &gen.ErrorResp{} if err != nil { out.Error = To(err.Error()) } @@ -140,35 +136,35 @@ func (s *server) Stop(ctx context.Context, in *gen.EmptyReq) (out *gen.ErrorResp return } -func (s *server) CheckConfig(ctx context.Context, in *gen.LoadConfigReq) (*gen.ErrorResp, error) { +func (s *server) CheckConfig(in *gen.LoadConfigReq, out *gen.ErrorResp) error { err := boxmain.Check([]byte(*in.CoreConfig)) if err != nil { - return &gen.ErrorResp{ - Error: To(err.Error()), - }, nil + out.Error = To(err.Error()) + return nil } - return &gen.ErrorResp{}, nil + return nil } -func (s *server) Test(ctx context.Context, in *gen.TestReq) (*gen.TestResp, error) { +func (s *server) Test(in *gen.TestReq, out *gen.TestResp) error { var testInstance *boxbox.Box var cancel context.CancelFunc var err error var twice = true if *in.TestCurrent { if boxInstance == nil { - return &gen.TestResp{Results: []*gen.URLTestResp{{ + out.Results = []*gen.URLTestResp{{ OutboundTag: To("proxy"), LatencyMs: To(int32(0)), Error: To("Instance is not running"), - }}}, nil + }} + return nil } testInstance = boxInstance twice = false } else { testInstance, cancel, err = boxmain.Create([]byte(*in.Config)) if err != nil { - return nil, err + return err } defer cancel() defer testInstance.Close() @@ -199,82 +195,79 @@ func (s *server) Test(ctx context.Context, in *gen.TestReq) (*gen.TestResp, erro }) } - return &gen.TestResp{Results: res}, nil + out.Results = res + return nil } -func (s *server) StopTest(ctx context.Context, in *gen.EmptyReq) (*gen.EmptyResp, error) { +func (s *server) StopTest(in *gen.EmptyReq, out *gen.EmptyResp) error { cancelTests() testCtx, cancelTests = context.WithCancel(context.Background()) - return &gen.EmptyResp{}, nil + return nil } -func (s *server) QueryURLTest(ctx context.Context, in *gen.EmptyReq) (*gen.QueryURLTestResponse, error) { +func (s *server) QueryURLTest(in *gen.EmptyReq, out *gen.QueryURLTestResponse) error { results := URLReporter.Results() - resp := &gen.QueryURLTestResponse{} for _, r := range results { errStr := "" if r.Error != nil { errStr = r.Error.Error() } - resp.Results = append(resp.Results, &gen.URLTestResp{ + out.Results = append(out.Results, &gen.URLTestResp{ OutboundTag: To(r.Tag), LatencyMs: To(int32(r.Duration.Milliseconds())), Error: To(errStr), }) } - return resp, nil + return nil } -func (s *server) QueryStats(ctx context.Context, _ *gen.EmptyReq) (*gen.QueryStatsResp, error) { - resp := &gen.QueryStatsResp{ - Ups: make(map[string]int64), - Downs: make(map[string]int64), - } +func (s *server) QueryStats(in *gen.EmptyReq, out *gen.QueryStatsResp) error { + out.Ups = make(map[string]int64) + out.Downs = make(map[string]int64) if boxInstance != nil { clash := service.FromContext[adapter.ClashServer](boxInstance.Context()) if clash != nil { cApi, ok := clash.(*clashapi.Server) if !ok { log.Println("Failed to assert clash server") - return nil, E.New("invalid clash server type") + return E.New("invalid clash server type") } outbounds := service.FromContext[adapter.OutboundManager](boxInstance.Context()) if outbounds == nil { log.Println("Failed to get outbound manager") - return nil, E.New("nil outbound manager") + return E.New("nil outbound manager") } endpoints := service.FromContext[adapter.EndpointManager](boxInstance.Context()) if endpoints == nil { log.Println("Failed to get endpoint manager") - return nil, E.New("nil endpoint manager") + return E.New("nil endpoint manager") } - for _, out := range outbounds.Outbounds() { - u, d := cApi.TrafficManager().TotalOutbound(out.Tag()) - resp.Ups[out.Tag()] = u - resp.Downs[out.Tag()] = d + for _, ob := range outbounds.Outbounds() { + u, d := cApi.TrafficManager().TotalOutbound(ob.Tag()) + out.Ups[ob.Tag()] = u + out.Downs[ob.Tag()] = d } for _, ep := range endpoints.Endpoints() { u, d := cApi.TrafficManager().TotalOutbound(ep.Tag()) - resp.Ups[ep.Tag()] = u - resp.Downs[ep.Tag()] = d + out.Ups[ep.Tag()] = u + out.Downs[ep.Tag()] = d } } } - - return resp, nil + return nil } -func (s *server) ListConnections(ctx context.Context, in *gen.EmptyReq) (*gen.ListConnectionsResp, error) { +func (s *server) ListConnections(in *gen.EmptyReq, out *gen.ListConnectionsResp) error { if boxInstance == nil { - return &gen.ListConnectionsResp{}, nil + return nil } if service.FromContext[adapter.ClashServer](boxInstance.Context()) == nil { - return nil, errors.New("no clash server found") + return errors.New("no clash server found") } clash, ok := service.FromContext[adapter.ClashServer](boxInstance.Context()).(*clashapi.Server) if !ok { - return nil, errors.New("invalid state, should not be here") + return errors.New("invalid state, should not be here") } connections := clash.TrafficManager().Connections() @@ -299,16 +292,14 @@ func (s *server) ListConnections(ctx context.Context, in *gen.EmptyReq) (*gen.Li } res = append(res, r) } - out := &gen.ListConnectionsResp{ - Connections: res, - } - return out, nil + out.Connections = res + return nil } -func (s *server) GetGeoIPList(ctx context.Context, in *gen.GeoListRequest) (*gen.GetGeoIPListResponse, error) { +func (s *server) GetGeoIPList(in *gen.GeoListRequest, out *gen.GetGeoIPListResponse) error { resp, err := boxmain.ListGeoip(*in.Path + string(os.PathSeparator) + "geoip.db") if err != nil { - return nil, err + return err } res := make([]string, 0) @@ -317,13 +308,14 @@ func (s *server) GetGeoIPList(ctx context.Context, in *gen.GeoListRequest) (*gen res = append(res, r) } - return &gen.GetGeoIPListResponse{Items: res}, nil + out.Items = res + return nil } -func (s *server) GetGeoSiteList(ctx context.Context, in *gen.GeoListRequest) (*gen.GetGeoSiteListResponse, error) { +func (s *server) GetGeoSiteList(in *gen.GeoListRequest, out *gen.GetGeoSiteListResponse) error { resp, err := boxmain.GeositeList(*in.Path + string(os.PathSeparator) + "geosite.db") if err != nil { - return nil, err + return err } res := make([]string, 0) @@ -332,42 +324,43 @@ func (s *server) GetGeoSiteList(ctx context.Context, in *gen.GeoListRequest) (*g res = append(res, r) } - return &gen.GetGeoSiteListResponse{Items: res}, nil + out.Items = res + return nil } -func (s *server) CompileGeoIPToSrs(ctx context.Context, in *gen.CompileGeoIPToSrsRequest) (*gen.EmptyResp, error) { +func (s *server) CompileGeoIPToSrs(in *gen.CompileGeoIPToSrsRequest, out *gen.EmptyResp) error { category := strings.TrimSuffix(*in.Item, "_IP") err := boxmain.CompileRuleSet(*in.Path+string(os.PathSeparator)+"geoip.db", category, boxmain.IpRuleSet, "./rule_sets/"+*in.Item+".srs") if err != nil { - return nil, err + return err } - return &gen.EmptyResp{}, nil + return nil } -func (s *server) CompileGeoSiteToSrs(ctx context.Context, in *gen.CompileGeoSiteToSrsRequest) (*gen.EmptyResp, error) { +func (s *server) CompileGeoSiteToSrs(in *gen.CompileGeoSiteToSrsRequest, out *gen.EmptyResp) error { category := strings.TrimSuffix(*in.Item, "_SITE") err := boxmain.CompileRuleSet(*in.Path+string(os.PathSeparator)+"geosite.db", category, boxmain.SiteRuleSet, "./rule_sets/"+*in.Item+".srs") if err != nil { - return nil, err + return err } - return &gen.EmptyResp{}, nil + return nil } -func (s *server) IsPrivileged(ctx context.Context, _ *gen.EmptyReq) (*gen.IsPrivilegedResponse, error) { +func (s *server) IsPrivileged(in *gen.EmptyReq, out *gen.IsPrivilegedResponse) error { if runtime.GOOS == "windows" { - return &gen.IsPrivilegedResponse{ - HasPrivilege: To(false), - }, nil + out.HasPrivilege = To(false) + return nil } - return &gen.IsPrivilegedResponse{HasPrivilege: To(os.Geteuid() == 0)}, nil + out.HasPrivilege = To(os.Geteuid() == 0) + return nil } -func (s *server) SpeedTest(ctx context.Context, in *gen.SpeedTestRequest) (*gen.SpeedTestResponse, error) { +func (s *server) SpeedTest(in *gen.SpeedTestRequest, out *gen.SpeedTestResponse) error { if !*in.TestDownload && !*in.TestUpload && !*in.SimpleDownload { - return nil, errors.New("cannot run empty test") + return errors.New("cannot run empty test") } var testInstance *boxbox.Box var cancel context.CancelFunc @@ -375,16 +368,17 @@ func (s *server) SpeedTest(ctx context.Context, in *gen.SpeedTestRequest) (*gen. var err error if *in.TestCurrent { if boxInstance == nil { - return &gen.SpeedTestResponse{Results: []*gen.SpeedTestResult{{ + out.Results = []*gen.SpeedTestResult{{ OutboundTag: To("proxy"), Error: To("Instance is not running"), - }}}, nil + }} + return nil } testInstance = boxInstance } else { testInstance, cancel, err = boxmain.Create([]byte(*in.Config)) if err != nil { - return nil, err + return err } defer cancel() defer testInstance.Close() @@ -415,17 +409,17 @@ func (s *server) SpeedTest(ctx context.Context, in *gen.SpeedTestRequest) (*gen. }) } - return &gen.SpeedTestResponse{Results: res}, nil + out.Results = res + return nil } -func (s *server) QuerySpeedTest(context.Context, *gen.EmptyReq) (*gen.QuerySpeedTestResponse, error) { +func (s *server) QuerySpeedTest(in *gen.EmptyReq, out *gen.QuerySpeedTestResponse) error { res, isRunning := SpTQuerier.Result() errStr := "" if res.Error != nil { errStr = res.Error.Error() } - return &gen.QuerySpeedTestResponse{ - Result: &gen.SpeedTestResult{ + out.Result = &gen.SpeedTestResult{ DlSpeed: To(res.DlSpeed), UlSpeed: To(res.UlSpeed), Latency: To(res.Latency), @@ -434,7 +428,7 @@ func (s *server) QuerySpeedTest(context.Context, *gen.EmptyReq) (*gen.QuerySpeed ServerName: To(res.ServerName), ServerCountry: To(res.ServerCountry), Cancelled: To(res.Cancelled), - }, - IsRunning: To(isRunning), - }, nil + } + out.IsRunning = To(isRunning) + return nil } diff --git a/core/server/server_darwin.go b/core/server/server_darwin.go new file mode 100644 index 0000000..29b8abd --- /dev/null +++ b/core/server/server_darwin.go @@ -0,0 +1,9 @@ +package main + +import ( + "Core/gen" +) + +func (s *server) SetSystemDNS(in *gen.SetSystemDNSRequest, out *gen.EmptyResp) error { + return nil +} diff --git a/core/server/server_linux.go b/core/server/server_linux.go new file mode 100644 index 0000000..29b8abd --- /dev/null +++ b/core/server/server_linux.go @@ -0,0 +1,9 @@ +package main + +import ( + "Core/gen" +) + +func (s *server) SetSystemDNS(in *gen.SetSystemDNSRequest, out *gen.EmptyResp) error { + return nil +} diff --git a/core/server/server_windows.go b/core/server/server_windows.go index e55dae8..709d7a1 100644 --- a/core/server/server_windows.go +++ b/core/server/server_windows.go @@ -3,14 +3,13 @@ package main import ( "Core/gen" "Core/internal/boxdns" - "context" ) -func (s *server) SetSystemDNS(ctx context.Context, in *gen.SetSystemDNSRequest) (*gen.EmptyResp, error) { +func (s *server) SetSystemDNS(in *gen.SetSystemDNSRequest, out *gen.EmptyResp) error { err := boxdns.DnsManagerInstance.SetSystemDNS(nil, *in.Clear) if err != nil { - return nil, err + return err } - return &gen.EmptyResp{}, nil + return nil } diff --git a/include/api/gRPC.h b/include/api/RPC.h similarity index 84% rename from include/api/gRPC.h rename to include/api/RPC.h index 043a85b..a54dd09 100644 --- a/include/api/gRPC.h +++ b/include/api/RPC.h @@ -4,17 +4,14 @@ #include "libcore.pb.h" #endif #include - -namespace QtGrpc { - class Http2GrpcChannelPrivate; -} +#include "3rdparty/protorpc/rpc_client.h" namespace API { enum GeoRuleSetType {ip, site}; class Client { public: - explicit Client(std::function onError, const QString &target); + explicit Client(std::function onError, const QString &host, int port); // QString returns is error string @@ -47,8 +44,7 @@ namespace API { libcore::QuerySpeedTestResponse QueryCurrentSpeedTests(bool *rpcOK); private: - std::function()> make_grpc_channel; - std::unique_ptr default_grpc_channel; + std::function()> make_rpc_client; std::function onError; }; diff --git a/script/build_go.sh b/script/build_go.sh index aea4b61..c35e94b 100755 --- a/script/build_go.sh +++ b/script/build_go.sh @@ -39,7 +39,7 @@ popd #### Go: core #### pushd core/server pushd gen -protoc -I . --go_out=. --go_opt paths=source_relative --go-grpc_out=. --go-grpc_opt paths=source_relative libcore.proto +protoc -I . --go_out=. --protorpc_out=. libcore.proto popd VERSION_SINGBOX=$(go list -m -f '{{.Version}}' github.com/sagernet/sing-box) $GOCMD build -v -o $DEST -trimpath -ldflags "-w -s -X 'github.com/sagernet/sing-box/constant.Version=${VERSION_SINGBOX}'" -tags "with_clash_api,with_gvisor,with_quic,with_wireguard,with_utls,with_ech,with_dhcp" diff --git a/src/api/RPC.cpp b/src/api/RPC.cpp new file mode 100644 index 0000000..7ab8995 --- /dev/null +++ b/src/api/RPC.cpp @@ -0,0 +1,295 @@ +#include "include/api/RPC.h" + +#include "include/global/Configs.hpp" + +namespace API { + + Client::Client(std::function onError, const QString &host, int port) { + this->make_rpc_client = [=]() { return std::make_unique(host.toStdString().c_str(), port); }; + this->onError = std::move(onError); + } + +#define NOT_OK \ + *rpcOK = false; \ + onError(QString("LibcoreService error: %1\n").arg(QString::fromStdString(err.String()))); + + QString Client::Start(bool *rpcOK, const libcore::LoadConfigReq &request) { + libcore::ErrorResp reply; + std::string resp, req = spb::pb::serialize(request); + auto err = make_rpc_client()->CallMethod("LibcoreService.Start", &req, &resp); + + if(err.IsNil()) { + reply = spb::pb::deserialize< libcore::ErrorResp >(resp); + *rpcOK = true; + return QString::fromStdString(reply.error.value()); + } else { + NOT_OK + return ""; + } + } + + QString Client::Stop(bool *rpcOK) { + libcore::EmptyReq request; + libcore::ErrorResp reply; + std::string resp, req = spb::pb::serialize(request); + auto err = make_rpc_client()->CallMethod("LibcoreService.Stop", &req, &resp); + + if(err.IsNil()) { + reply = spb::pb::deserialize< libcore::ErrorResp >( resp ); + *rpcOK = true; + return QString::fromStdString(reply.error.value()); + } else { + NOT_OK + return ""; + } + } + + libcore::QueryStatsResp Client::QueryStats() { + libcore::EmptyReq request; + libcore::QueryStatsResp reply; + std::string resp, req = spb::pb::serialize(request); + auto err = make_rpc_client()->CallMethod("LibcoreService.QueryStats", &req, &resp); + + if(err.IsNil()) { + reply = spb::pb::deserialize< libcore::QueryStatsResp >( resp ); + return reply; + } else { + return {}; + } + } + + libcore::TestResp Client::Test(bool *rpcOK, const libcore::TestReq &request) { + libcore::TestResp reply; + std::string resp, req = spb::pb::serialize(request); + auto err = make_rpc_client()->CallMethod("LibcoreService.Test", &req, &resp); + + if(err.IsNil()) { + reply = spb::pb::deserialize< libcore::TestResp >( resp ); + *rpcOK = true; + return reply; + } else { + NOT_OK + return reply; + } + } + + void Client::StopTests(bool *rpcOK) { + const libcore::EmptyReq request; + std::string resp, req = spb::pb::serialize(request); + auto err = make_rpc_client()->CallMethod("LibcoreService.StopTest", &req, &resp); + + if(err.IsNil()) { + *rpcOK = true; + } else { + NOT_OK + } + } + + libcore::QueryURLTestResponse Client::QueryURLTest(bool *rpcOK) + { + libcore::EmptyReq request; + libcore::QueryURLTestResponse reply; + std::string resp, req = spb::pb::serialize(request); + auto err = make_rpc_client()->CallMethod("LibcoreService.QueryURLTest", &req, &resp); + + if(err.IsNil()) { + reply = spb::pb::deserialize< libcore::QueryURLTestResponse >( resp ); + *rpcOK = true; + return reply; + } else { + NOT_OK + return reply; + } + } + + QStringList Client::GetGeoList(bool *rpcOK, GeoRuleSetType mode, const QString& basePath) { + switch (mode) { + case GeoRuleSetType::ip: { + libcore::GeoListRequest request; + libcore::GetGeoIPListResponse reply; + request.path = basePath.toStdString(); + std::string resp, req = spb::pb::serialize(request); + auto err = make_rpc_client()->CallMethod("LibcoreService.GetGeoIPList", &req, &resp); + + if(err.IsNil()) { + QStringList res; + reply = spb::pb::deserialize< libcore::GetGeoIPListResponse >( resp ); + for (const auto & i : reply.items) { + res.append(QString::fromStdString(i)); + } + *rpcOK = true; + return res; + } else { + NOT_OK + return {}; + } + } + case GeoRuleSetType::site: { + libcore::GeoListRequest request; + libcore::GetGeoSiteListResponse reply; + request.path = basePath.toStdString(); + std::string resp, req = spb::pb::serialize(request); + auto err = make_rpc_client()->CallMethod("LibcoreService.GetGeoSiteList", &req, &resp); + + if(err.IsNil()) { + QStringList res; + reply = spb::pb::deserialize< libcore::GetGeoSiteListResponse >( resp ); + for (const auto & i : reply.items) { + res.append(QString::fromStdString(i)); + } + *rpcOK = true; + return res; + } else { + NOT_OK + return {}; + } + } + } + return {}; + } + + QString Client::CompileGeoSet(bool *rpcOK, GeoRuleSetType mode, std::string category, const QString& basePath) { + switch (mode) { + case ip: { + libcore::CompileGeoIPToSrsRequest request; + libcore::EmptyResp reply; + request.item = category; + request.path = basePath.toStdString(); + std::string resp, req = spb::pb::serialize(request); + + auto err = make_rpc_client()->CallMethod("LibcoreService.CompileGeoIPToSrs", &req, &resp); + if(err.IsNil()) { + *rpcOK = true; + return ""; + } else { + NOT_OK + return QString::fromStdString(err.String()); + } + } + case site: { + libcore::CompileGeoSiteToSrsRequest request; + libcore::EmptyResp reply; + request.item = category; + request.path = basePath.toStdString(); + std::string resp, req = spb::pb::serialize(request); + + auto err = make_rpc_client()->CallMethod("LibcoreService.CompileGeoSiteToSrs", &req, &resp); + if(err.IsNil()) { + *rpcOK = true; + return ""; + } else { + NOT_OK + return QString::fromStdString(err.String()); + } + } + } + return ""; + } + + QString Client::SetSystemDNS(bool *rpcOK, const bool clear) const { + libcore::SetSystemDNSRequest request; + request.clear = clear; + std::string resp, req = spb::pb::serialize(request); + + auto err = make_rpc_client()->CallMethod("LibcoreService.SetSystemDNS", &req, &resp); + if(err.IsNil()) { + *rpcOK = true; + return ""; + } else { + NOT_OK + return QString::fromStdString(err.String()); + } + } + + libcore::ListConnectionsResp Client::ListConnections(bool* rpcOK) const + { + libcore::EmptyReq request; + libcore::ListConnectionsResp reply; + std::string resp, req = spb::pb::serialize(request); + auto err = make_rpc_client()->CallMethod("LibcoreService.ListConnections", &req, &resp); + if(err.IsNil()) { + reply = spb::pb::deserialize< libcore::ListConnectionsResp >( resp ); + *rpcOK = true; + return reply; + } else { + NOT_OK + MW_show_log(QString("Failed to list connections: ") + QString::fromStdString(err.String())); + return {}; + } + } + + QString Client::CheckConfig(bool* rpcOK, const QString& config) const + { + libcore::LoadConfigReq request; + libcore::ErrorResp reply; + request.core_config = config.toStdString(); + std::string resp, req = spb::pb::serialize(request); + auto err = make_rpc_client()->CallMethod("LibcoreService.CheckConfig", &req, &resp); + + if(err.IsNil()) + { + reply = spb::pb::deserialize< libcore::ErrorResp >( resp ); + *rpcOK = true; + return QString::fromStdString(reply.error.value()); + } else + { + NOT_OK + return QString::fromStdString(err.String()); + } + + } + + bool Client::IsPrivileged(bool* rpcOK) const + { + libcore::EmptyReq request; + libcore::IsPrivilegedResponse reply; + std::string resp, req = spb::pb::serialize(request); + auto err = make_rpc_client()->CallMethod("LibcoreService.IsPrivileged", &req, &resp); + + if(err.IsNil()) + { + reply = spb::pb::deserialize< libcore::IsPrivilegedResponse >( resp ); + *rpcOK = true; + return reply.has_privilege.value(); + } else + { + NOT_OK + return false; + } + } + + libcore::SpeedTestResponse Client::SpeedTest(bool *rpcOK, const libcore::SpeedTestRequest &request) + { + libcore::SpeedTestResponse reply; + std::string resp, req = spb::pb::serialize(request); + auto err = make_rpc_client()->CallMethod("LibcoreService.SpeedTest", &req, &resp); + + if(err.IsNil()) { + reply = spb::pb::deserialize< libcore::SpeedTestResponse >( resp ); + *rpcOK = true; + return reply; + } else { + NOT_OK + return reply; + } + } + + libcore::QuerySpeedTestResponse Client::QueryCurrentSpeedTests(bool *rpcOK) + { + const libcore::EmptyReq request; + libcore::QuerySpeedTestResponse reply; + std::string resp, req = spb::pb::serialize(request); + auto err = make_rpc_client()->CallMethod("LibcoreService.QuerySpeedTest", &req, &resp); + + if(err.IsNil()) { + reply = spb::pb::deserialize< libcore::QuerySpeedTestResponse >( resp ); + *rpcOK = true; + return reply; + } else { + NOT_OK + return reply; + } + } + + +} // namespace API diff --git a/src/api/gRPC.cpp b/src/api/gRPC.cpp deleted file mode 100644 index 9323a82..0000000 --- a/src/api/gRPC.cpp +++ /dev/null @@ -1,474 +0,0 @@ -#include "include/api/gRPC.h" - -#include - -#include "include/global/Configs.hpp" - -#include -#include -#include -#include -#include -#include -#include - -namespace QtGrpc { - const char *GrpcAcceptEncodingHeader = "grpc-accept-encoding"; - const char *AcceptEncodingHeader = "accept-encoding"; - const char *TEHeader = "te"; - const char *GrpcStatusHeader = "grpc-status"; - const char *GrpcStatusMessage = "grpc-message"; - const int GrpcMessageSizeHeaderSize = 5; - - class NoCache : public QAbstractNetworkCache { - public: - QNetworkCacheMetaData metaData(const QUrl &url) override { - return {}; - } - void updateMetaData(const QNetworkCacheMetaData &metaData) override { - } - QIODevice *data(const QUrl &url) override { - return nullptr; - } - bool remove(const QUrl &url) override { - return false; - } - [[nodiscard]] qint64 cacheSize() const override { - return 0; - } - QIODevice *prepare(const QNetworkCacheMetaData &metaData) override { - return nullptr; - } - void insert(QIODevice *device) override { - } - void clear() override { - } - }; - - class Http2GrpcChannelPrivate { - private: - QThread *thread; - QNetworkAccessManager *nm; - - QString url_base; - QString serviceName; - - // async - QNetworkReply *post(const QString &method, const QString &service, const QByteArray &args) { - QUrl callUrl = url_base + "/" + service + "/" + method; - - QNetworkRequest request(callUrl); - request.setAttribute(QNetworkRequest::Http2DirectAttribute, true); - request.setHeader(QNetworkRequest::ContentTypeHeader, QLatin1String{"application/grpc"}); - request.setRawHeader("Cache-Control", "no-store"); - request.setRawHeader(GrpcAcceptEncodingHeader, QByteArray{"identity,deflate,gzip"}); - request.setRawHeader(AcceptEncodingHeader, QByteArray{"identity,gzip"}); - request.setRawHeader(TEHeader, QByteArray{"trailers"}); - - QByteArray msg(GrpcMessageSizeHeaderSize, '\0'); - *reinterpret_cast(msg.data() + 1) = qToBigEndian((int) args.size()); - msg += args; - - QNetworkReply *networkReply = nm->post(request, msg); - return networkReply; - } - - static QByteArray processReply(QNetworkReply *networkReply, QNetworkReply::NetworkError &statusCode) { - // Check if no network error occured - if (networkReply->error() != QNetworkReply::NoError) { - statusCode = networkReply->error(); - return {}; - } - - // Check if server answer with error - auto errCode = networkReply->rawHeader(GrpcStatusHeader).toInt(); - if (errCode != 0) { - QStringList errstr; - errstr << "grpc-status error code:" << Int2String(errCode) << ", error msg:" - << QLatin1String(networkReply->rawHeader(GrpcStatusMessage)); - MW_show_log(errstr.join(" ")); - statusCode = QNetworkReply::NetworkError::ProtocolUnknownError; - return {}; - } - statusCode = QNetworkReply::NetworkError::NoError; - return networkReply->readAll().mid(GrpcMessageSizeHeaderSize); - } - - QNetworkReply::NetworkError call(const QString &method, const QString &service, const QByteArray &args, QByteArray &qByteArray, int timeout_ms) { - QNetworkReply *networkReply = post(method, service, args); - - QTimer *abortTimer = nullptr; - if (timeout_ms > 0) { - abortTimer = new QTimer; - abortTimer->setSingleShot(true); - abortTimer->setInterval(timeout_ms); - QObject::connect(abortTimer, &QTimer::timeout, networkReply, &QNetworkReply::abort); - abortTimer->start(); - } - - { - QEventLoop loop; - QObject::connect(networkReply, &QNetworkReply::finished, &loop, &QEventLoop::quit); - loop.exec(); - } - - if (abortTimer != nullptr) { - abortTimer->stop(); - abortTimer->deleteLater(); - } - - auto grpcStatus = QNetworkReply::NetworkError::ProtocolUnknownError; - qByteArray = processReply(networkReply, grpcStatus); - - networkReply->deleteLater(); - return grpcStatus; - } - - public: - Http2GrpcChannelPrivate(const QString &url_, const QString &serviceName_) { - url_base = "http://" + url_; - serviceName = serviceName_; - // - thread = new QThread; - nm = new QNetworkAccessManager(); - nm->setCache(new NoCache); - nm->moveToThread(thread); - thread->start(); - } - - ~Http2GrpcChannelPrivate() { - nm->deleteLater(); - thread->quit(); - thread->wait(); - thread->deleteLater(); - } - - QNetworkReply::NetworkError Call(const QString &methodName, - const std::string req, std::vector &rsp, - int timeout_ms = 0) { - if (!Configs::dataStore->core_running) return QNetworkReply::NetworkError(-1919); - - auto requestArray = QByteArray::fromStdString(req); - - QByteArray responseArray; - QNetworkReply::NetworkError err; - QMutex lock; - lock.lock(); - - runOnThread( - [&] { - err = call(methodName, serviceName, requestArray, responseArray, timeout_ms); - lock.unlock(); - }, - nm); - - lock.lock(); - lock.unlock(); - // qDebug() << "rsp err" << err; - // qDebug() << "rsp array" << responseArray; - - if (err != QNetworkReply::NetworkError::NoError) { - return err; - } - rsp.assign(responseArray.begin(), responseArray.end()); - return QNetworkReply::NetworkError::NoError; - } - }; -} // namespace QtGrpc - -namespace API { - - Client::Client(std::function onError, const QString &target) { - this->make_grpc_channel = [=]() { return std::make_unique(target, "libcore.LibcoreService"); }; - this->default_grpc_channel = make_grpc_channel(); - this->onError = std::move(onError); - } - -#define NOT_OK \ - *rpcOK = false; \ - onError(QString("QNetworkReply::NetworkError code: %1\n").arg(status)); - - QString Client::Start(bool *rpcOK, const libcore::LoadConfigReq &request) { - libcore::ErrorResp reply; - std::vector rsp; - auto status = default_grpc_channel->Call("Start", spb::pb::serialize< std::string >( request ), rsp); - - if (status == QNetworkReply::NoError) { - reply = spb::pb::deserialize< libcore::ErrorResp >( rsp ); - *rpcOK = true; - return {reply.error.value().c_str()}; - } else { - NOT_OK - return reply.error.value().c_str(); - } - } - - QString Client::Stop(bool *rpcOK) { - libcore::EmptyReq request; - libcore::ErrorResp reply; - std::vector rsp; - auto status = default_grpc_channel->Call("Stop", spb::pb::serialize< std::string >( request ), rsp); - - if (status == QNetworkReply::NoError) { - reply = spb::pb::deserialize< libcore::ErrorResp >( rsp ); - *rpcOK = true; - return {reply.error.value().c_str()}; - } else { - NOT_OK - return ""; - } - } - - libcore::QueryStatsResp Client::QueryStats() { - libcore::EmptyReq request; - libcore::QueryStatsResp reply; - std::vector rsp; - auto status = default_grpc_channel->Call("QueryStats", spb::pb::serialize< std::string >( request ), rsp, 500); - - if (status == QNetworkReply::NoError) { - reply = spb::pb::deserialize< libcore::QueryStatsResp >( rsp ); - return reply; - } else { - return {}; - } - } - - libcore::TestResp Client::Test(bool *rpcOK, const libcore::TestReq &request) { - libcore::TestResp reply; - std::vector rsp; - auto status = make_grpc_channel()->Call("Test", spb::pb::serialize< std::string >( request ), rsp); - - if (status == QNetworkReply::NoError) { - reply = spb::pb::deserialize< libcore::TestResp >( rsp ); - *rpcOK = true; - return reply; - } else { - NOT_OK - return reply; - } - } - - void Client::StopTests(bool *rpcOK) { - const libcore::EmptyReq req; - libcore::EmptyResp resp; - std::vector rsp; - auto status = make_grpc_channel()->Call("StopTest", spb::pb::serialize< std::string >( req ), rsp); - - if (status == QNetworkReply::NoError) { - *rpcOK = true; - } else { - NOT_OK - } - } - - libcore::QueryURLTestResponse Client::QueryURLTest(bool *rpcOK) - { - libcore::EmptyReq request; - libcore::QueryURLTestResponse resp; - std::vector rsp; - auto status = make_grpc_channel()->Call("QueryURLTest", spb::pb::serialize< std::string >( request ), rsp); - - if (status == QNetworkReply::NoError) { - resp = spb::pb::deserialize< libcore::QueryURLTestResponse >( rsp ); - *rpcOK = true; - return resp; - } else { - NOT_OK - return resp; - } - } - - QStringList Client::GetGeoList(bool *rpcOK, GeoRuleSetType mode, const QString& basePath) { - switch (mode) { - case GeoRuleSetType::ip: { - libcore::GeoListRequest req; - libcore::GetGeoIPListResponse resp; - std::vector rsp; - req.path = basePath.toStdString(); - - auto status = default_grpc_channel->Call("GetGeoIPList", spb::pb::serialize< std::string >( req ), rsp); - - if (status == QNetworkReply::NoError) { - QStringList res; - resp = spb::pb::deserialize< libcore::GetGeoIPListResponse >( rsp ); - for (const auto & i : resp.items) { - res.append(QString::fromStdString(i)); - } - *rpcOK = true; - return res; - } else { - NOT_OK - return {}; - } - } - case GeoRuleSetType::site: { - libcore::GeoListRequest req; - libcore::GetGeoSiteListResponse resp; - std::vector rsp; - req.path = basePath.toStdString(); - - auto status = default_grpc_channel->Call("GetGeoSiteList", spb::pb::serialize< std::string >( req ), rsp); - - if (status == QNetworkReply::NoError) { - QStringList res; - resp = spb::pb::deserialize< libcore::GetGeoSiteListResponse >( rsp ); - for (const auto & i : resp.items) { - res.append(QString::fromStdString(i)); - } - *rpcOK = true; - return res; - } else { - NOT_OK - return {}; - } - } - } - return {}; - } - - QString Client::CompileGeoSet(bool *rpcOK, GeoRuleSetType mode, std::string category, const QString& basePath) { - switch (mode) { - case ip: { - libcore::CompileGeoIPToSrsRequest req; - libcore::EmptyResp resp; - std::vector rsp; - req.item = category; - req.path = basePath.toStdString(); - - auto status = default_grpc_channel->Call("CompileGeoIPToSrs", spb::pb::serialize< std::string >( req ), rsp); - if (status == QNetworkReply::NoError) { - *rpcOK = true; - return ""; - } else { - NOT_OK - return qt_error_string(status); - } - } - case site: { - libcore::CompileGeoSiteToSrsRequest req; - libcore::EmptyResp resp; - std::vector rsp; - req.item = category; - req.path = basePath.toStdString(); - - auto status = default_grpc_channel->Call("CompileGeoSiteToSrs", spb::pb::serialize< std::string >( req ), rsp); - if (status == QNetworkReply::NoError) { - *rpcOK = true; - return ""; - } else { - NOT_OK - return qt_error_string(status); - } - } - } - return ""; - } - - QString Client::SetSystemDNS(bool *rpcOK, const bool clear) const { - libcore::SetSystemDNSRequest req; - libcore::EmptyResp resp; - std::vector rsp; - req.clear = clear; - - auto status = default_grpc_channel->Call("SetSystemDNS", spb::pb::serialize< std::string >( req ), rsp); - if (status == QNetworkReply::NoError) { - *rpcOK = true; - return ""; - } else { - NOT_OK - return qt_error_string(status); - } - } - - libcore::ListConnectionsResp Client::ListConnections(bool* rpcOK) const - { - libcore::EmptyReq req; - libcore::ListConnectionsResp resp; - std::vector rsp; - auto status = default_grpc_channel->Call("ListConnections", spb::pb::serialize< std::string >( req ), rsp); - if (status == QNetworkReply::NoError) { - resp = spb::pb::deserialize< libcore::ListConnectionsResp >( rsp ); - *rpcOK = true; - return resp; - } else { - NOT_OK - MW_show_log(QString("Failed to list connections: " + qt_error_string(status))); - return {}; - } - } - - QString Client::CheckConfig(bool* rpcOK, const QString& config) const - { - libcore::LoadConfigReq req; - libcore::ErrorResp resp; - std::vector rsp; - req.core_config = config.toStdString(); - auto status = default_grpc_channel->Call("CheckConfig", spb::pb::serialize< std::string >( req ), rsp); - - if (status == QNetworkReply::NoError) - { - resp = spb::pb::deserialize< libcore::ErrorResp >( rsp ); - *rpcOK = true; - return {resp.error.value().c_str()}; - } else - { - NOT_OK - return qt_error_string(status); - } - - } - - bool Client::IsPrivileged(bool* rpcOK) const - { - auto req = libcore::EmptyReq(); - auto resp = libcore::IsPrivilegedResponse(); - std::vector rsp; - auto status = default_grpc_channel->Call("IsPrivileged", spb::pb::serialize< std::string >( req ), rsp); - - if (status == QNetworkReply::NoError) - { - resp = spb::pb::deserialize< libcore::IsPrivilegedResponse >( rsp ); - *rpcOK = true; - return resp.has_privilege.value(); - } else - { - NOT_OK - return false; - } - } - - libcore::SpeedTestResponse Client::SpeedTest(bool *rpcOK, const libcore::SpeedTestRequest &request) - { - libcore::SpeedTestResponse reply; - std::vector rsp; - auto status = make_grpc_channel()->Call("SpeedTest", spb::pb::serialize< std::string >( request ), rsp); - - if (status == QNetworkReply::NoError) { - reply = spb::pb::deserialize< libcore::SpeedTestResponse >( rsp ); - *rpcOK = true; - return reply; - } else { - NOT_OK - return reply; - } - } - - libcore::QuerySpeedTestResponse Client::QueryCurrentSpeedTests(bool *rpcOK) - { - const libcore::EmptyReq req; - libcore::QuerySpeedTestResponse reply; - std::vector rsp; - auto status = make_grpc_channel()->Call("QuerySpeedTest", spb::pb::serialize< std::string >( req ), rsp); - - if (status == QNetworkReply::NoError) { - reply = spb::pb::deserialize< libcore::QuerySpeedTestResponse >( rsp ); - *rpcOK = true; - return reply; - } else { - NOT_OK - return reply; - } - } - - -} // namespace API diff --git a/src/configs/ConfigBuilder.cpp b/src/configs/ConfigBuilder.cpp index 7799b99..43df7f7 100644 --- a/src/configs/ConfigBuilder.cpp +++ b/src/configs/ConfigBuilder.cpp @@ -2,7 +2,7 @@ #include "include/dataStore/Database.hpp" #include "include/configs/proxy/includes.h" #include "include/configs/proxy/Preset.hpp" -#include "include/api/gRPC.h" +#include "include/api/RPC.h" #include #include diff --git a/src/global/Configs.cpp b/src/global/Configs.cpp index ddba4a9..ad92d1a 100644 --- a/src/global/Configs.cpp +++ b/src/global/Configs.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include #ifdef Q_OS_WIN #include "include/sys/windows/guihelper.h" diff --git a/src/stats/connectionLister/connectionLister.cpp b/src/stats/connectionLister/connectionLister.cpp index 114854e..27137b6 100644 --- a/src/stats/connectionLister/connectionLister.cpp +++ b/src/stats/connectionLister/connectionLister.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include "include/ui/mainwindow_interface.h" #include diff --git a/src/stats/traffic/TrafficLooper.cpp b/src/stats/traffic/TrafficLooper.cpp index 2cabc2f..dfea54d 100644 --- a/src/stats/traffic/TrafficLooper.cpp +++ b/src/stats/traffic/TrafficLooper.cpp @@ -1,6 +1,6 @@ #include "include/stats/traffic/TrafficLooper.hpp" -#include "include/api/gRPC.h" +#include "include/api/RPC.h" #include "include/ui/mainwindow_interface.h" #include diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index 095e91c..a507257 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -53,7 +53,6 @@ #include #include <3rdparty/QHotkey/qhotkey.h> #include <3rdparty/qv2ray/v2/proxy/QvProxyConfigurator.hpp> -#include #include #include "include/sys/macos/MacOS.h" diff --git a/src/ui/mainwindow_grpc.cpp b/src/ui/mainwindow_grpc.cpp index e76c144..155014b 100644 --- a/src/ui/mainwindow_grpc.cpp +++ b/src/ui/mainwindow_grpc.cpp @@ -3,7 +3,7 @@ #include "include/dataStore/Database.hpp" #include "include/configs/ConfigBuilder.hpp" #include "include/stats/traffic/TrafficLooper.hpp" -#include "include/api/gRPC.h" +#include "include/api/RPC.h" #include "include/ui/utils//MessageBoxTimer.h" #include "3rdparty/qv2ray/v2/proxy/QvProxyConfigurator.hpp" @@ -22,7 +22,7 @@ void MainWindow::setup_grpc() { [=](const QString &errStr) { MW_show_log("[Error] Core: " + errStr); }, - "127.0.0.1:" + Int2String(Configs::dataStore->core_port)); + "127.0.0.1", Configs::dataStore->core_port); // Looper runOnNewThread([=] { Stats::trafficLooper->Loop(); }); @@ -64,7 +64,7 @@ void MainWindow::runURLTest(const QString& config, bool useDefault, const QStrin { int entid = -1; if (!tag2entID.empty()) { - entid = tag2entID.count(QString(res.outbound_tag.value().c_str())) == 0 ? -1 : tag2entID[QString(res.outbound_tag.value().c_str())]; + entid = tag2entID.count(QString::fromStdString(res.outbound_tag.value())) == 0 ? -1 : tag2entID[QString::fromStdString(res.outbound_tag.value())]; } if (entid == -1) { continue; @@ -76,11 +76,11 @@ void MainWindow::runURLTest(const QString& config, bool useDefault, const QStrin if (res.error.value().empty()) { ent->latency = res.latency_ms.value(); } else { - if (QString(res.error.value().c_str()).contains("test aborted") || - QString(res.error.value().c_str()).contains("context canceled")) ent->latency=0; + if (QString::fromStdString(res.error.value()).contains("test aborted") || + QString::fromStdString(res.error.value()).contains("context canceled")) ent->latency=0; else { ent->latency = -1; - MW_show_log(tr("[%1] test error: %2").arg(ent->bean->DisplayTypeAndName(), res.error.value().c_str())); + MW_show_log(tr("[%1] test error: %2").arg(ent->bean->DisplayTypeAndName(), QString::fromStdString(res.error.value()))); } } ent->Save(); @@ -104,7 +104,7 @@ void MainWindow::runURLTest(const QString& config, bool useDefault, const QStrin for (const auto &res: result.results) { if (!tag2entID.empty()) { - entID = tag2entID.count(QString(res.outbound_tag.value().c_str())) == 0 ? -1 : tag2entID[QString(res.outbound_tag.value().c_str())]; + entID = tag2entID.count(QString::fromStdString(res.outbound_tag.value())) == 0 ? -1 : tag2entID[QString::fromStdString(res.outbound_tag.value())]; } if (entID == -1) { MW_show_log(tr("Something is very wrong, the subject ent cannot be found!")); @@ -120,11 +120,11 @@ void MainWindow::runURLTest(const QString& config, bool useDefault, const QStrin if (res.error.value().empty()) { ent->latency = res.latency_ms.value(); } else { - if (QString(res.error.value().c_str()).contains("test aborted") || - QString(res.error.value().c_str()).contains("context canceled")) ent->latency=0; + if (QString::fromStdString(res.error.value()).contains("test aborted") || + QString::fromStdString(res.error.value()).contains("context canceled")) ent->latency=0; else { ent->latency = -1; - MW_show_log(tr("[%1] test error: %2").arg(ent->bean->DisplayTypeAndName(), res.error.value().c_str())); + MW_show_log(tr("[%1] test error: %2").arg(ent->bean->DisplayTypeAndName(), QString::fromStdString(res.error.value()))); } } ent->Save(); @@ -212,7 +212,7 @@ void MainWindow::url_test_current() { runOnUiThread([=] { if (!result.results[0].error.value().empty()) { - MW_show_log(QString("UrlTest error: %1").arg(result.results[0].error.value().c_str())); + MW_show_log(QString("UrlTest error: %1").arg(QString::fromStdString(result.results[0].error.value()))); } if (latency <= 0) { ui->label_running->setText(tr("Test Result") + ": " + tr("Unavailable")); @@ -304,7 +304,7 @@ void MainWindow::runSpeedTest(const QString& config, bool useDefault, bool testC { continue; } - auto profile = testCurrent ? running : Configs::profileManager->GetProfile(tag2entID[res.result.value().outbound_tag.value().c_str()]); + auto profile = testCurrent ? running : Configs::profileManager->GetProfile(tag2entID[QString::fromStdString(res.result.value().outbound_tag.value())]); if (profile == nullptr) { continue; @@ -318,8 +318,8 @@ void MainWindow::runSpeedTest(const QString& config, bool useDefault, bool testC if (res.result.value().error.value().empty() && !res.result.value().cancelled.value() && lastProxyListUpdate.msecsTo(QDateTime::currentDateTime()) >= 500) { - if (!res.result.value().dl_speed.value().empty()) profile->dl_speed = res.result.value().dl_speed.value().c_str(); - if (!res.result.value().ul_speed.value().empty()) profile->ul_speed = res.result.value().ul_speed.value().c_str(); + if (!res.result.value().dl_speed.value().empty()) profile->dl_speed = QString::fromStdString(res.result.value().dl_speed.value()); + if (!res.result.value().ul_speed.value().empty()) profile->ul_speed = QString::fromStdString(res.result.value().ul_speed.value()); if (profile->latency <= 0 && res.result.value().latency.value() > 0) profile->latency = res.result.value().latency.value(); refresh_proxy_list(profile->id); lastProxyListUpdate = QDateTime::currentDateTime(); @@ -343,7 +343,7 @@ void MainWindow::runSpeedTest(const QString& config, bool useDefault, bool testC for (const auto &res: result.results) { if (testCurrent) entID = running ? running->id : -1; else { - entID = tag2entID.count(QString(res.outbound_tag.value().c_str())) == 0 ? -1 : tag2entID[QString(res.outbound_tag.value().c_str())]; + entID = tag2entID.count(QString::fromStdString(res.outbound_tag.value())) == 0 ? -1 : tag2entID[QString::fromStdString(res.outbound_tag.value())]; } if (entID == -1) { MW_show_log(tr("Something is very wrong, the subject ent cannot be found!")); @@ -359,14 +359,14 @@ void MainWindow::runSpeedTest(const QString& config, bool useDefault, bool testC if (res.cancelled.value()) continue; if (res.error.value().empty()) { - ent->dl_speed = res.dl_speed.value().c_str(); - ent->ul_speed = res.ul_speed.value().c_str(); + ent->dl_speed = QString::fromStdString(res.dl_speed.value()); + ent->ul_speed = QString::fromStdString(res.ul_speed.value()); if (ent->latency <= 0 && res.latency.value() > 0) ent->latency = res.latency.value(); } else { ent->dl_speed = "N/A"; ent->ul_speed = "N/A"; ent->latency = -1; - MW_show_log(tr("[%1] speed test error: %2").arg(ent->bean->DisplayTypeAndName(), res.error.value().c_str())); + MW_show_log(tr("[%1] speed test error: %2").arg(ent->bean->DisplayTypeAndName(), QString::fromStdString(res.error.value()))); } ent->Save(); } diff --git a/src/ui/setting/RouteItem.cpp b/src/ui/setting/RouteItem.cpp index a31f758..b34e287 100644 --- a/src/ui/setting/RouteItem.cpp +++ b/src/ui/setting/RouteItem.cpp @@ -1,7 +1,7 @@ #include "include/ui/setting/RouteItem.h" #include "include/dataStore/RouteEntity.h" #include "include/dataStore/Database.hpp" -#include "include/api/gRPC.h" +#include "include/api/RPC.h" void adjustComboBoxWidth(const QComboBox *comboBox) { int maxWidth = 0; diff --git a/src/ui/setting/dialog_manage_routes.cpp b/src/ui/setting/dialog_manage_routes.cpp index 5051e48..8f0b160 100644 --- a/src/ui/setting/dialog_manage_routes.cpp +++ b/src/ui/setting/dialog_manage_routes.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include void DialogManageRoutes::reloadProfileItems() { if (chainList.empty()) {