根据 ' 下的 Google Protocol Buffers 文档定义服务 https://developers.google.com/protocol-buffers/docs/proto3#services' 他们说,
也可以将协议缓冲区与您自己的 RPC 实现一起使用。
据我了解,Protocol Buffers 本身并没有实现 RPC。相反,它们提供了一系列必须由用户(那就是我!)实现的抽象接口。所以我想利用 ZeroMQ 来实现这些抽象接口来进行网络通信。
我正在尝试使用 ZeroMQ 创建一个 RPC 实现,因为我正在开发的项目已经实现了 ZeroMQ 来进行基本消息传递(因此我not使用 gRPC,如文档建议)。
彻底阅读原型文档后,我发现我必须实现抽象接口Rpc通道 https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.service#RpcChannel and Rpc控制器 https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.service#RpcController为了我自己的实现。
我已经构建了一个最小化的示例,展示了我目前的 RPC 实现情况
.proto 文件: 为简洁起见,省略了 SearchRequest 和 SearchResponse 架构
service SearchService {
rpc Search (SearchRequest) returns (SearchResponse);
}
搜索服务Impl.h:
class SearchServiceImpl : public SearchService {
public:
void Search(google::protobuf::RpcController *controller,
const SearchRequest *request,
SearchResponse *response,
google::protobuf::Closure *done) override {
// Static function that processes the request and gets the result
SearchResponse res = GetSearchResult(request);
// Call the callback function
if (done != NULL) {
done->Run();
}
}
}
};
MyRPCController.h:
class MyRPCController : public google::protobuf::RpcController {
public:
MyRPCController();
void Reset() override;
bool Failed() const override;
std::string ErrorText() const override;
void StartCancel() override;
void SetFailed(const std::string &reason) override;
bool IsCanceled() const override;
void NotifyOnCancel(google::protobuf::Closure *callback) override;
private:
bool failed_;
std::string message_;
};
MyRPCController.cpp- 基于this https://github.com/madwyn/libpbrpc/blob/master/src/pbrpc/ControllerRPC.hh
void MyRPCController::Reset() { failed_ = false; }
bool MyRPCController::Failed() const { return failed_; }
std::string MyRPCController::ErrorText() const { return message_; }
void MyRPCController::StartCancel() { }
void MyRPCController::SetFailed(const std::string &reason) {
failed_ = true;
message_ = reason;
}
bool MyRPCController::IsCanceled() const { return false; }
void MyRPCController::NotifyOnCancel(google::protobuf::Closure *callback) { }
MyRPCController::ChiRpcController() : RpcController() { Reset(); }
MyRpcChannel.h:
class MyRPCChannel: public google::protobuf::RpcChannel {
public:
void CallMethod(const google::protobuf::MethodDescriptor *method, google::protobuf::RpcController *controller,
const google::protobuf::Message *request, google::protobuf::Message *response,
google::protobuf::Closure *done) override;
};
到目前为止,我对我的例子有疑问:
- Where do I fit ZeroMQ into this?
- 看起来它应该进入 RPCChannel,因为在我看到的示例中(参见第三个代码块here https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.service),它们传递一个具有要绑定的端口的字符串(即
MyRpcChannel channel("rpc:hostname:1234/myservice");
)
- 我关心我的 RPCController 实现,它看起来太简单了。应该有更多人去这里吗?
- 我如何实现RPCChannel,它看起来与SearchServiceImpl非常相似。这些类中的 1 个虚函数具有非常相似的方法签名,只是它是通用的。
以下是我遇到的其他一些 Stack Overflow 问题,其中包含有关该主题的一些有用信息:
-
Protobuf-Net:实现服务器、rpc控制器和rpc通道 https://stackoverflow.com/questions/30882556/protobuf-net-implementing-server-rpc-controller-and-rpc-channel- 这是我找到 RPCController 实现示例的地方。
-
Using Protocol Buffers for implementing RPC in ZeroMQ https://stackoverflow.com/questions/48038494/using-protocol-buffers-for-implementing-rpc-in-zeromq - This answer is interesting because in the top answer, is seems that they're recommending against using Protobufs built in RPC formatting for the .proto file.
- 我也注意到了同样的概念this https://github.com/madwyn/libpbrpc/blob/master/proto/pbrpc.proto文件,位于名为的存储库中libpbrpc https://github.com/madwyn/libpbrpc这似乎是示例代码的一个很好的来源
- 我可以/我应该使用现有的实现吗,例如RPCZ https://github.com/thesamet/rpcz?
感谢您的帮助。我希望我提供了足够的信息并且清楚我在寻找什么。如果有不清楚或缺乏信息,请告诉我。我很乐意相应地编辑问题。