前言
? ? ? gRPC作為Google開源的高性能RPC框架,在微服務架構中扮演著重要角色。本文將詳細介紹在Windows平臺下,使用Visual Studio 2022和Vcpkg進行gRPC開發的完整流程,包括環境配置、項目搭建、常見問題解決等實用內容。
環境準備
1. 安裝必要組件
首先確保已安裝以下軟件:
-
Visual Studio 2022(需勾選"C++桌面開發"工作負載)
-
Git(用于Vcpkg管理)
2. 配置Vcpkg(具體可以參考這個C ++第三方庫安裝工具)
# 克隆Vcpkg倉庫
git clone https://github.com/microsoft/vcpkg.git
cd vcpkg# 安裝Vcpkg
.\bootstrap-vcpkg.bat# 集成到全局(需要管理員權限)
.\vcpkg integrate install
二、安裝gRPC依賴
在vcpkg的根目錄下打開cmd
# 安裝gRPC和Protobuf
vcpkg install grpc:x64-windows protobuf:x64-windows# 可選:安裝測試工具
vcpkg install grpc:x64-windows protobuf:x64-windows gtest:x64-windows
三、使用?protoc
?編譯?.proto
?文件
1.在任意位置新建文件夾,并新建.proto
?文件,如HelloWorld.proto,并編輯文件類容。
syntax = "proto3";
package HelloWorld;
service Greeter{rpc SayHello (HelloRequest) returns (HelloReply){
}
}message HelloRequest {string name = 1;
}message HelloReply{string message =1;}
2.在相應的當前目錄下打開cmd,編譯此 .proto 文件(生成 .pb.h 和 .pb.cc)
protoc --proto_path=你的proto文件目錄 --cpp_out=輸出目錄 HelloWorld.proto
比如我的位置
protoc --proto_path=. --cpp_out=. HelloWorld.protoprotoc --proto_path=. --grpc_out=. --plugin=protoc-gen-grpc="E:\Vcpkg\vcpkg\installed\x64-windows\tools\grpc\grpc_cpp_plugin.exe" HelloWorld.proto
2.1如果protoc -- 編譯失敗,可能是編譯路徑不對,可以將protoc 編譯環境變量配置到全局變量中。
3.再編譯完成之后,會在你的測試文件夾下生成相應的編譯文件
三、在vs2022中創建客戶端與服務端項目進行測試
設置項目結構如下,服務端和客戶端工程目錄結構一樣。
(1)客戶端代碼如下
#include <grpcpp/grpcpp.h>#include "../HelloWorld.pb.h" // 確保路徑正確
#include "../HelloWorld.grpc.pb.h"using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using HelloWorld::HelloRequest;
using HelloWorld::HelloReply;
using HelloWorld::Greeter;class GreeterClient {
public:GreeterClient(std::shared_ptr<Channel> channel): stub_(Greeter::NewStub(channel)) {}std::string SayHello(const std::string& name) {HelloRequest request;request.set_name(name);HelloReply reply;ClientContext context;// 發起RPC調用Status status = stub_->SayHello(&context, request, &reply);if (status.ok()) {return reply.message();}else {std::cerr << "RPC failed: " << status.error_message() << std::endl;return "RPC Error";}}private:std::unique_ptr<Greeter::Stub> stub_;
};int main() {// 連接到服務端(地址需與服務端一致)std::string server_address("localhost:50059");GreeterClient client(grpc::CreateChannel(server_address,grpc::InsecureChannelCredentials() // 測試用非安全連接));// 發起請求std::string name("World");std::string response = client.SayHello(name);std::cout << "Server responded: " << response << std::endl;return 0;
}
(2)服務端代碼如下
HelloWorldService.h
#pragma once
#include <grpcpp/grpcpp.h>
#include "../HelloWorld.pb.h"
#include "../HelloWorld.grpc.pb.h"using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;
using HelloWorld::HelloRequest;
using HelloWorld::HelloReply;
using HelloWorld::Greeter;// 添加RunServer函數聲明
void RunServer(); //class GreeterServiceImpl final : public Greeter::Service {
public:Status SayHello(ServerContext* context,const HelloRequest* request,HelloReply* reply) override;
};
HelloWorldService.cpp
#include "HelloWorldService.h"Status GreeterServiceImpl::SayHello(ServerContext* context,const HelloRequest* request,HelloReply* reply) {std::string prefix("Hello ");reply->set_message(prefix + request->name());return Status::OK;
}void RunServer() {std::string server_address("0.0.0.0:50059");GreeterServiceImpl service;ServerBuilder builder;builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());builder.RegisterService(&service);std::unique_ptr<Server> server(builder.BuildAndStart());std::cout << "Server listening on " << server_address << std::endl;server->Wait();
}
main.cpp
// 只包含頭文件,不要包含.cpp文件!
#include "HelloWorldService.h" int main() {RunServer();return 0;
}
同時啟動項目,結果如下。