1. 如何获取grpc框架源码
源码可以去github获取:https://github.com/grpc/grpc
2. 如何编译
2.1 环境
Golang编译工具,源代码编译(非必须)
下载地址:https://www.golangtc.com/download
Perl编译工具,源代码编译(非必须)
下载地址:http://www.perl.org/get.html
VS2015 源代码编译,也就是工程构建后,用vs2015打开解决方案,然后进行编译
CMake,用于工程配置, 这个很重要,用来构建工程的,必须的。
下载地址:https://cmake.org/download/
2.2 编译
2.2.1 由于下载grpc源码后,一些模块源码是缺少的,需要单独下载,具体可以参考文件.gitmodules, 截图如下:
一般来说主要下载模块有:zlib,protobuf, gflags, boringssl, benchmark,c-ares , 如下图:
2.2.2 项目配置和生成vs2015项目
注意:如果有错误产生,需要看下具体原因,逐个排除即可。
最终生成的vs2015解决方案及若干项目,如下图:
此后:我们可以生成我们需要的项目模块目标文件即可。
3. 夸语言调用
grpc 可以跨语言调用,例如:c++,java,go等等,服务端的开发语言和客户端可有不一样,但是需要定义好协议,一般来说,我们定义一个proto文件,里面描述了大体的数据结构。
3.1 定义proto协议
说明:本协议其实就是求2个数的和,接口为Add
3.2 c++ 服务端
生成相关c++文件,截图如下:
protoc --cpp_out=. calculator.proto
protoc.exe --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin.exe calculator.proto
需要拷贝生成的文件到服务端工程目录下:
需要导入相关lib库:
address_sorting.lib;cares.lib;crypto.lib;gpr.lib;grpc.lib;grpc++.lib;libprotobufd.lib;ssl.lib;zlibd.lib;zlibstaticd.lib;Ws2_32.lib;upb.lib;
相关服务端代码:
#include "stdafx.h"
#include "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<grpc::Server> server(builder.BuildAndStart());
std::cout << "Server listening on " << server_address << std::endl;
server->Wait();
return 0;
}
3.3 java 客户端
3.1需要相关的jar包
3.2 利用工具根据proto文件生成java代码:
3.3 代码如下:
3.31. 定义CalculateService 类
package sample;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import java.util.concurrent.TimeUnit;
import io.grpc.StatusRuntimeException;
import io.grpc.netty.NegotiationType;
import io.grpc.netty.NettyChannelBuilder;
import java.util.logging.Level;
import java.util.logging.Logger;
public class CalculateService {
private ManagedChannel channel;
private calc.CaltulatorGrpc.CaltulatorBlockingStub blockingStub = null;
private CalculateService(ManagedChannel channel) {
this.channel = channel;
blockingStub = calc.CaltulatorGrpc.newBlockingStub(channel);
}
public CalculateService(String host, int port) {
//this(ManagedChannelBuilder.forAddress(host, port)
// .usePlaintext()
// .build());
channel = NettyChannelBuilder.forAddress(host, port).negotiationType(NegotiationType.PLAINTEXT).build();
}
public void shutdown() throws InterruptedException {
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
}
public int operate(int num1, int num2) {
calc.Calculator.Request request= calc.Calculator.Request.newBuilder().setA(num1).setB(num2).build();
calc.Calculator.Response response= blockingStub.add(request);
return (int) response.getSum();
}
}
3.3.2 调用代码如下:
CalculateService service= new CalculateService("localhost", 50051);System.out.println(service.operate(100, 1));
结束语: 如果需要相关代码及编译调试遇到问题,可以联系我们, 2736483347@qq.com