根据“Defining Services”下的Google Protocol Buffer 文档,他们说,
据我了解, Protocol Buffer 并不是本地实现RPC的。相反,它们提供了必须由用户实现的一系列抽象接口(interface)(多数民众赞成!)。因此,我想利用ZeroMQ来实现这些抽象接口(interface)进行网络通信。
我正在尝试使用ZeroMQ创建RPC实现,因为我正在处理的项目已经为基本消息传递实现了ZeroMQ(因此,为什么我不按文档建议使用gRPC)。
彻底阅读了原始文档之后,我发现必须为自己的实现实现抽象接口(interface)RpcChannel和RpcController。
我已经构建了一个最小化示例,说明了我目前在RPC实现中所处的位置
.proto文件:为了简洁起见,省略了SearchRequest和SearchResponse模式
service SearchService {
rpc Search (SearchRequest) returns (SearchResponse);
}
SearchServiceImpl.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
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;
};
到目前为止,我对我的示例有疑问:
MyRpcChannel channel("rpc:hostname:1234/myservice");
)这是我遇到的其他一些Stack Overflow问题,其中包含有关该主题的一些有用信息:
感谢您的帮助。我希望我能提供足够的信息,并且清楚我要寻找的内容。如果有不清楚或缺乏信息的地方,请告诉我。我很乐意相应地编辑问题。
最佳答案
ZeroMQ和gRPC均以不同方式为网络通信提供支持。您必须选择ZeroMQ或gRPC进行网络通信。
如果选择ZeroMQ,则可以使用ProtoBuffers交换二进制结构化数据来对消息进行编码。
要点是ProtoBuffers库允许对变体记录(类似于C/C++ union )进行编码和解码,这些变体记录可以完全模拟具有交换ProtoBuffers消息功能的RPC服务所提供的功能。
因此,选项为:
(这里可以使用很多组合)
该选项可能取决于
客户端的
对于第一个选项,与第二个选项相比,您必须做很多事情。您必须将发送的消息类型与期望接收的消息类型进行匹配。
如果其他人将开发客户端,则第二个选项将允许更轻松/更快地理解所提供服务的功能。
为了在ZeroMQ的顶部开发RPC服务,我将定义.proto文件,以指定函数,参数(所有可能的输入和输出参数)和类似以下的错误:
enum Function
{
F1 = 0;
F2 = 1;
F3 = 2;
}
enum Error
{
E1 = 0;
E2 = 1;
E3 = 2;
}
message Request
{
required Function function = 1;
repeated Input data = 2;
}
message Response
{
required Function function = 1;
required Error error = 2;
repeated Output data = 3;
}
message Input
{
optional Input1 data1 = 1;
optional Input2 data2 = 2;
...
optional InputN dataN = n;
}
message Output
{
optional Output1 data1 = 1;
optional Output2 data2 = 2;
...
optional OutputN dataN = n;
}
message Message
{
repeated Request requests;
repeated Response responses;
}
并根据功能ID,在运行时必须检查参数的数量和类型。
关于c++ - 如何使用ZeroMQ为 Protocol Buffer 编写自己的RPC实现,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59616929/