本例的环境为:WIN10 + VS2015
gRPC 的版本为: 1.35.1
protobuf 的版本为: 3.3.2
> perl -v
This is perl 5, version 24, subversion 1 (v5.24.1) built for MSWin32-x86-multi-thread-64int
(with 1 registered patch, see perl -V for more detail)
下载并安装 Go 注意:你可能需要设置代理来下载)。本例下载的是:go1.8.3.windows-amd64.msi。安装后打开命令行,输入以下命令验证安装,如果出现版本信息,就说明安装成功了。
go version
go version go1.8.3 windows/amd64
打开命令行,新建一个目录专门用来放置 gRPC 的源码,然后进入该目录。本例是在 G 盘下建立的 grpc
目录,大家应该根据实际情况修改。
cd G:
md grpc & cd grpc
用 git 下载 gRPC 源码,本例下载的版本是 1.4.2 。
git clone -b v1.4.2 https://github.com/grpc/grpc.git grpc_v1.4.2
下载后可以在源码根目录找到 INSTALL.md,里面详细介绍了编译方法。
下载源码后,可以在源码根目录下找到 .gitmodules 文件,该文件是 git 用来描述依赖库的,可以看到 gRPC 的依赖库有:protobuf,gflags,googletest,boringssl,cares,zlib。这些依赖库都需要下载到 third_party 目录下。可以执行以下命令下载这些依赖库,也可以跳过这一步,转到第 5 步开始手动下载。
git submodule update --init
进入到 third_party 目录,下面开始下载 gRPC 的依赖库。
cd third_party
下载 protobuf,这里下载的版本是 3.3.2。
git clone -b v3.3.2 https://github.com/google/protobuf.git protobuf
下载 gflags。
git clone https://github.com/gflags/gflags.git gflags
下载 googletest 。
git clone https://github.com/google/googletest.git googletest
下载 boringssl 。
git clone https://github.com/google/boringssl.git boringssl
下载 cares 。需要注意下载的版本为:cares-1_12_0 。下载的目录为 cares\cares 。
git clone -b cares-1_12_0 https://github.com/c-ares/c-ares.git cares/cares
下载 zlib 。
git clone https://github.com/madler/zlib.git zlib
找到 third_party\boringssl 目录下的 CMakeLists.txt,用编辑器打开它,搜索
MSVC_DISABLED_WARNINGS_LIST,找到后,在下面添加
“C4819”,消除警告:该文件包含不能在当前代码页(数字)中表示的字符。 以 Unicode 格式保存该文件防止数据丢失。
切换到源码目录,在源码目录下创建一个 .build (如果要编译64位,则是
.build_x64)子目录,我们用该目录保存所有生成的工程文件。创建后进入该目录。
32位:
md .build & cd .build
64位:
md .build_x64 &cd .build_x64
用 cmake 生成工程文件。生成后可以在 .build (或 .build_x64)目录下看到生成的工程和项目文件。
32位:
cmake … -G “Visual Studio 14 2015” -DCMAKE_BUILD_TYPE=Release
64位:
cmake … -G “Visual Studio 14 2015 Win64” -DCMAKE_BUILD_TYPE=Release
使用 MSBuild 编译工程。打开 VS2015 开发人员命令提示符,切换到 .build (或
.build_x64)目录下,执行下面的命令进行编译。
编译 32 位 Debug 版本:
MSBuild ALL_BUILD.vcxproj /t:Build /p:Configuration=Debug;Platform=Win32
编译 32 位 Release 版本:
MSBuild ALL_BUILD.vcxproj /t:Build /p:Configuration=Release;Platform=Win32
编译 64 位 Debug 版本:
MSBuild ALL_BUILD.vcxproj /t:Build /p:Configuration=Debug;Platform=x64
编译 64 位 Release 版本:
MSBuild ALL_BUILD.vcxproj /t:Build /p:Configuration=Release;Platform=x64
如果遇到如下错误,则用编辑器打开.build\third_party\boringssl\crypto_test_data.cc ,在第 2604 行最后面的双引号 " 之前加个空格。保存,退出,重新编译。
> G:\grpc\grpc_v1.4.2\.build\third_party\boringssl\crypto_test_data.cc(2604): error C2001: 常量中有换行符
编译好之后,可以在相应项目目录下的 Debug 和 Release 子目录中找到我们需要的库和工具。如下所示(仅列出重要部分):
实例
下面写一个小程序测试一下。
新建 [空白解决方案],命名为 Calculator。如下图:
这里写图片描述
创建接口
添加 [Win32 控制台应用程序],命名为 ICalc。如下图:
这里写图片描述
在 [应用程序设置页面],勾选 [空项目]。如下图所示。点击完成。
这里写图片描述
将 .build\third_party\protobuf\Debug\protoc.exe 和 .build\Debug\grpc_cpp_plugin.exe 拷贝到项目目录中。拷贝后的目录如下所示:
这里写图片描述
新建 [C++ 文件(.cpp)],命名为 calculator.proto。注意一定要带 .proto 后缀,否则的话后缀就变成 .cpp 了。如下图所示:
这里写图片描述
calculator.proto 右键,[属性]。 [项类型] 选择 [自定义生成工具]。点击[应用] 按钮。如下图所示:
这里写图片描述
在 [自定义生成工具] -> [常规] 下,[命令行]填写如下命令:
protoc --cpp_out=. calculator.proto
protoc --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin.exe calculator.proto
[说明] 填写 Performing Protoc Build Tools。[输出] 填写 None。[链接对象] 改为 [否]。 如下图所示:
这里写图片描述
打开 calculator.proto,编写如下代码:
syntax = “proto3”;
package calc;
service Caltulator {
rpc Add(Request) returns (Response) {}
}
message Request {
int32 a = 1;
int32 b = 2;
}
message Response {
int32 sum = 1;
}
编译项目,成功后会在项目目录中生成如下文件:
calculator.pb.h
calculator.pb.cc
calculator.grpc.pb.h
calculator.grpc.pb.cc
其中,calculator.pb.h 和 calculator.pb.cc 是通过 protoc.exe 编译生成的接口数据类型,在这里就是我们在 calculator.proto 中定义的 Request 和 Response。calculator.grpc.pb.h 和 calculator.grpc.pb.cc 是通过 grpc_cpp_plugin.exe 编译生成的服务器以及存根代码。有了这些文件,就可以开始编写服务器和客户端的代码了。
实现服务器
新建 [Win32 控制台应用程序],命名为 Server。如下图所示:
这里写图片描述
在 [应用程序设置] 页面,勾选 [空项目] 。如下图所示:
这里写图片描述
项目右键,[添加现有项],选择上面生成的那四个接口文件:
这里写图片描述
项目 [属性] -> [C/C++] -> [常规] -> [附加包含目录],加入 gRPC 和 Protocol Buffer 的头文件,如下图所示。注意这里应该换成自己实际的目录。
这里写图片描述
项目 [属性] -> [链接器] -> [常规] -> [附加库目录],添加 gRPC 及其依赖库的目录,如下图所示。注意这里应该换成自己实际的目录。
这里写图片描述
项目 [属性] -> [链接器] -> [输入] -> [附加依赖库],添加 gRPC 及其依赖的库,如下图所示。
这里写图片描述
工程 [属性] -> [C/C++] -> [预处理器] -> [预处理器定义],添加 _WIN32_WINNT=0x600。
新建 [C++ 文件(.cpp)],命名为 main.cpp,代码如下:
#include “…/ICalc/calculator.grpc.pb.h”
#include “grpc++/grpc++.h”
class CalcualtorService : public calc::Caltulator::Service
{
// 构造、析构
public:
// 接口实现
public:
virtual ::grpc::Status Add(::grpc::ServerContext* context,
const ::calc::Request* request, ::calc::Response* response) override
{
response->set_sum(request->a() + request->b());
return grpc::Status::OK;
}
};
int main()
{
std::string server_address(“0.0.0.0:50051”);
CalcualtorService service;
grpc::ServerBuilder builder;
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
builder.RegisterService(&service);
std::unique_ptr server(builder.BuildAndStart());
std::cout << "Server listening on " << server_address << std::endl;
server->Wait();
return 0;
}
编译工程。生成 Server.exe。
实现客户端
实现客户端的步骤和实现服务器的一样,只是最后的 main.cpp 不一样而已。这里简单列出步骤。
新建 [Win32 控制台应用程序],命名为 Client。
添加在创建接口那一步生成的四个文件:calculator.pb.h calculator.pb.cc calculator.grpc.pb.h calculator.grpc.pb.cc
接下来和服务器一样,设置好 [附加包含目录],[附加库目录],[附加依赖库]。
[预处理器定义] 添加 _WIN32_WINNT=0x600
新建 main.cpp,代码如下:
#include
#include “grpc++/grpc++.h”
#include “…/ICalc/calculator.grpc.pb.h”
class Client
{
public:
Client(std::shared_ptrgrpc::Channel channel)
: stub_(calc::Caltulator::NewStub(channel)) {}
google::protobuf::int32 Add(google::protobuf::int32 a, google::protobuf::int32 b)
{
calc::Request request;
request.set_a(a);
request.set_b(b);
calc::Response response;
grpc::ClientContext context;
grpc::Status status = stub_->Add(&context, request, &response);
if (status.ok())
{
return response.sum();
}
else
{
return -1;
}
}
private:
std::unique_ptrcalc::Caltulator::Stub stub_;
};
int main()
{
Client client(grpc::CreateChannel(
“localhost:50051”, grpc::InsecureChannelCredentials()));
auto result = client.Add(1, 2);
std::cout << "1 + 2 = " << result << std::endl;
return 0;
}
编译工程。生成 Client.exe。
测试
先启动 Server.exe,再启动 Client.exe。