grpc框架在linux系统下安装与使用

qq_46489304 2024-09-05 13:37:01 阅读 69

一、编译grpc源码

(1)源码下载,这里准备好了源码连接,直接按下面链接源码和依赖库。

链接: https://pan.baidu.com/s/1UcHkDLbMWb8yNsLEQh3Wxw 提取码: grpc 。

(2)安装必要依赖工具

<code>sudo apt-get install autoconf automake libtool

(3)安装cmake和gcc/g++

本文主要用到cmake来进行编译,所以需要安装cmake和gcc/g++,注意需要保证cmake的版本大于3.15,gcc/g++的版本大于7.0吗。

如果已经安装的cmake,版本号低于3.15,先卸载再安装新的cmake。

卸载命令

sudo apt-get autoremove cmake

安装新的cmake

1.压缩包下载

wget https://cmake.org/files/v3.23/cmake-3.23.0-linux-x86_64.tar.gz

2.解压

tar zxf cmake-3.23.0-linux-x86_64.tar.gz

3.创建软连接

sudo ln -sf /opt/cmake-3.23.0/bin/* /usr/bin/

 创建软连接到/usr/bin/下的目的是可以在系统的任何目录下直接运行cmake命令。

(4)解压grpc源码

tar -jxf grpc-v1.45.2.tar.bz2

(5)编译和安转

        命令如下,首先进入压缩后的grpc文件夹下,执行如下命令。

mkdir build

cd build

cmake ../

make

sudo make install

(6)protobuf安装

        这里的protobuf主要用来数据传输的序列化,使用grpc/third_party/protobuf 里面编译安装对应的 protobuf,不要手动下载其他的protbuf,不然版本可能和grcp不匹配。命令如下。

cd third_party/protobuf/

./autogen.sh

./configure --prefix=/usr/local

make

sudo make install

sudo ldconfig # 使得新安装的动态库能被加载

protoc --version

显示3.19.4

(7)测试

1.编译helloword例子

cd grpc/examples/cpp/helloworld/

mkdir build

cd build/

cmake ..

make

2.启动客户端和服务器

# 启动服务端,监听在50051端口

./greeter_server

Server listening on 0.0.0.0:50051

# 启动客户端,服务端返回Hello world

./greeter_client

Greeter received: Hello world

出现上述结果说明编译成功。

二、如何在c++中使用grpc进行通信

(1)编写proto文件,这文件主要是用来定义服务接口函数和一些消息体结构,然后通过protobuf工具用该文件生成对应的grpc.pb.cc文件和消息体结构类。代码如下:

syntax = "proto3";//声明使用protoc3版本

package myserver;//定义命令空间,主要是为了区分不同的proto文件有相同的函数名和消息体名

service Greeter//定义接口服务

{

rpc SayHello(HelloRequest) returns (HelloRepose){}//接口函数,通过该函数来与服务器进行通信

}

message HelloRequest//请求消息体结构

{

bytes message = 1;//成员变量

}

message HelloRepose//响应消息体结构

{

bytes message = 1;

}

上面代码中,定义个叫Greeter的服务类,在这个类中定义一个接口函数,该函数的功能是接受一个单一的消息,服务器返回单一的消息,这里我只定义了一个,大家可以随意定义。下面接受以下grpc的四种接口模式。

1.简单接口模型

即客户端发起一次请求,服务端响应处理后返回一个结果给客户端。在proto文件对应如下。

rpc SayHello(HelloRequest) returns (HelloResponse);

 2.服务端数据流模式

即客户端发起一次请求,服务端可以连续返回数据流。比如:客户端向服务端发送了一个查询数据库的请求,服务端持续返回多次结果。(即客户端发送一次请求,服务端查询到数据库有一万条数据,服务端分批返回10次,每次返回1000条数据给客户端)。

rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);

用到了stream关键字。

3.客户端数据流模式

与服务端数据流模式相反,客户端持续向服务端发送数据流,在发送结束后,由服务端返回一个响应。比如:客户端有一万条数据 ,分批多次请求服务端,服务端接收后把这些数据都存到数据库,然后返回一次结果给客户端。

在 proto 文件中可如下定义:

rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);

4.双向数据流模式

也称双向流式 RPC,即客户端和服务端都可以向对方多次收发数据。比如:客户端有一万条数据 ,分批多次请求服务端,服务端每次接收后存到数据库后都发送一次结果给客户端。在 proto 文件中可如下定义:

rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);

(2)使用protobuf工具将上面的proto文件生成对应的c++语法结构的grpc.pb.cc和grpc.pb.h文件

命名如下:

上面--grpc_out是grpc.pb.cc文件的输出目录,--plugin是 grpc_cpp_plugin这个插件的路径。执行上面命令后会在当前项目路径下生成下面两个文件。

(3)使用protobuf工具将上面的proto文件生成对应的c++语法结构消息体结构类 

命令如下:

<code>protoc -I=./ server.proto --cpp_out=./

-I表示proto文件所在目录,--cpp_out表示输出文件的输出目录。生成文件如下。

(4) 服务器代码

<code>/*

*

* Copyright 2015 gRPC authors.

*

* Licensed under the Apache License, Version 2.0 (the "License");

* you may not use this file except in compliance with the License.

* You may obtain a copy of the License at

*

* http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*

*/

#include <iostream> // 包含输入输出流操作所需的头文件

#include <memory> // 包含智能指针(如 std::unique_ptr)的支持

#include <string> // 包含 std::string 类

#include <grpcpp/ext/proto_server_reflection_plugin.h> // 包含 gRPC 服务器反射插件的支持

#include <grpcpp/grpcpp.h> // 包含 gRPC 核心功能的头文件

#include <grpcpp/health_check_service_interface.h> // 包含健康检查服务的接口

#include "server.grpc.pb.h" // 包含由 .proto 文件生成的头文件

using grpc::Server; // 使用 gRPC Server 类

using grpc::ServerBuilder; // 使用 gRPC ServerBuilder 类

using grpc::ServerContext; // 使用 gRPC ServerContext 类

using grpc::Status; // 使用 gRPC Status 类

using myserver::Greeter; // 使用从 .proto 文件生成的 Greeter 服务类

using myserver::HelloRepose; // 使用从 .proto 文件生成的 HelloRepose 消息类

using myserver::HelloRequest; // 使用从 .proto 文件生成的 HelloRequest 消息类

// Greeter 服务的实现类

class GreeterServiceImpl final : public Greeter::Service {

// 实现 SayHello RPC 方法

Status SayHello(ServerContext* context, const HelloRequest* request,

HelloRepose* reply) override {

// 创建问候前缀

std::string prefix("Hello ");

// 将请求中的内容与前缀拼接,并设置为响应内容

reply->set_contents(prefix + request->contents());

// 返回表示成功的状态

return Status::OK;

}

};

// 设置并运行服务器的函数

void RunServer() {

std::string server_address("0.0.0.0:50051"); // 服务器监听的地址和端口

GreeterServiceImpl service; // 创建 Greeter 服务的实现实例

// 启用默认健康检查服务

grpc::EnableDefaultHealthCheckService(true);

// 初始化 gRPC 服务器反射插件以支持反射功能

grpc::reflection::InitProtoReflectionServerBuilderPlugin();

ServerBuilder builder; // 创建 ServerBuilder 对象

// 将监听端口和不安全凭证添加到服务器构建器

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();

}

// 程序的入口点

int main(int argc, char** argv) {

// 启动服务器

RunServer();

// 返回成功的状态码

return 0;

}

(5) 客户端代码

#include <string> // 包含 std::string 类,用于字符串操作

#include <iostream> // 包含输入输出流操作所需的头文件

#include <memory> // 包含智能指针(如 std::unique_ptr)的支持

#include <grpcpp/grpcpp.h> // 包含 gRPC 核心功能的头文件

#include "server.grpc.pb.h" // 包含由 .proto 文件生成的头文件

using grpc::ClientContext; // 使用 gRPC ClientContext 类

using grpc::Channel; // 使用 gRPC Channel 类

using grpc::Status; // 使用 gRPC Status 类

using myserver::HelloRepose; // 使用从 .proto 文件生成的 HelloRepose 消息类

using myserver::HelloRequest; // 使用从 .proto 文件生成的 HelloRequest 消息类

using myserver::Greeter; // 使用从 .proto 文件生成的 Greeter 服务类

// FCClient 类,封装了与 gRPC 服务器的通信

class FCClient {

public:

// 构造函数,接受一个共享的 Channel 对象,创建 Greeter 的 Stub

FCClient(std::shared_ptr<Channel> channel)

: stub_(Greeter::NewStub(channel)) {

}

// 发送 SayHello 请求到 gRPC 服务器

std::string SayHello(std::string name) {

ClientContext context; // 创建客户端上下文对象

HelloRepose reply; // 用于接收服务器响应的对象

HelloRequest request; // 创建请求对象并设置内容

request.set_contents(name); // 将传入的名字设置到请求中

// 调用 gRPC 服务方法 SayHello 并获取响应

Status status = stub_->SayHello(&context, request, &reply);

if (status.ok()) {

// 如果请求成功,返回响应中的内容

return reply.contents();

} else {

// 如果请求失败,返回错误信息

return "failure " + status.error_message();

}

}

private:

std::unique_ptr<Greeter::Stub> stub_; // 用于调用 gRPC 服务的 Stub

};

// 程序的入口点

int main(int argc, char* argv[]) {

// 创建与 gRPC 服务器的通道,并指定服务器地址和使用的不安全凭证

auto channel = grpc::CreateChannel("127.0.0.1:50051", grpc::InsecureChannelCredentials());

FCClient client(channel); // 创建 FCClient 实例

// 调用 SayHello 方法并阻塞,直到从 RPC 服务器获取结果

std::string result = client.SayHello("hello , llfc.club !");

// 输出结果

printf("get result [%s]\n", result.c_str());

return 0; // 返回成功状态码

}

(6)CmakeLists文件编写

        在linux端采用cmake来编译服务器端和客户端的代码。cmakelists文件如下。

cmake_minimum_required(VERSION 3.1)

project(GrpcClient LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_CXX_STANDARD 17)

set(CMAKE_CXX_STANDARD_REQUIRED ON)

#假设已经安装好grpc了

find_package(Threads REQUIRED)

set(protobuf_MODULE_COMPATIBLE TRUE)

find_package(Protobuf CONFIG REQUIRED)

message(STATUS "Using protobuf ${Protobuf_VERSION}")

set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf)

set(_REFLECTION gRPC::grpc++_reflection)

# Find gRPC installation

# Looks for gRPCConfig.cmake file installed by gRPC's cmake installation.

find_package(gRPC CONFIG REQUIRED)

message(STATUS "Using gRPC ${gRPC_VERSION}")

set(_GRPC_GRPCPP gRPC::grpc++)

# 添加可执行文件和源文件

file(GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)

file(GLOB PBSOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)

add_executable(GrpcClient ${SOURCES}

${PBSOURCES})

target_link_libraries(GrpcClient

${_REFLECTION}

${_GRPC_GRPCPP}

${_PROTOBUF_LIBPROTOBUF})

将该文件分别放到,服务器端和客户端的项目文件夹下,比如:

在该目录下打开终端。执行如下命令生成可执行文件

<code>mkdir build

cd ./build

cmake ../

make

 可执行就会生成在build文件夹下。

 服务器启动

客户端启动并收到服务器的回应

 总结,以上就是grpc在linux系统下的编译与简单应用,grpc主要用在服务器上各个服务之间的通信,基于http2,支持异步和同步,效率比较高。



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。