c++实现gRPC

        一篇文章学会grpc,全网最详细grpc教程

        无论什么语言,实现grpc的核心是.proto文件,通过protoc命令将.proto文件生成grpc框架的接口文件*gb*, 该文件中包含.proto定义的方法及参数接口,服务器,客户端相关操作接口;然后再编写服务器,客户端代码,调用*gb*文件生成的接口。

        直接实例代码介绍其过程:

        核心文件:hello.proto

syntax = "proto3"; // 规定使用proto3的语法
service MsgService { // 定义服务, 流数据放到括号里面
    rpc GetMsg (MsgRequest) returns (MsgResponse){}
}
 
message MsgRequest { // 请求的结构, 也可以定义int32,int64,double,float等数据类型, 等号后面的数字表示第几个
    string name = 1;
}
 
message MsgResponse { // 回应的结果
    string msg = 1;
}

        然后执行:

protoc -I . --cpp_out=. ./hello.proto#生成hello.pb.cc文件

protoc -I . --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` ./hello.proto#生成hello.grpc.pb.cc文件
或者
protoc -I . --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` ./hello.proto#一起生成两个文件

-I :(-IPATH)指定要在其中搜索导入(import)的目录。可指定多次,目录将按顺序搜索。如果没有给出,则使用当前工作目录。
--cpp_out = . : 以c++语言格式输出,等号后面为输出文件存放的路径
--grpc_out = . :输出grpc框架接口文件。等号后面为输出文件存放的路径
--plugin=`which grpc_cpp_plugin` :指定一个protobuf插件(grpc_cpp_plugin)来生成grpc代码。

hello.proto : 核心文件,可以是路径./hello.proto,或者绝对路径。

        执行成功后,指定的目录下会生成两个文件:

        hello_pb.cc/hello_pb.h:主要是对参数(MsgRequest,MsgResponse)的属性设置,参数类的重定向,参数成员的设置,获取等操作。

        hello_pb_grpc.cc/hello_grpc_pb.h :该文件生成了proto方法(GetMsg)的属性操作接口,通过该存根实现服务器与客户端的通讯

        生成这两个文件之后就可以编写服务器,客户端代码了:

        服务器代码(hello_server.cc):

#include <iostream>
#include <memory>
#include <string>

#include <grpcpp/grpcpp.h>

#include "hello.grpc.pb.h"
#include "hello.pb.h"

using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;

//创建类,继承MsgService::Service, 父类在生成的hello.grpc.pb.cc/h文件中,属于grpc的服务端接口类
class MyServer final : public MsgService::Service{
    Status GetMsg(ServerContext* context, const MsgRequest* request, MsgResponse* reply) override{//hello.grpc.pb文件生成的类接口
        std::string str("Hello ");
        reply->set_msg( str + request->name());//hello.pb文件生成的类接口,设置回复结构的成员数据

        return Status::OK;
    }
};

void RunServer(){
    std::string server_address("0.0.0.0:50051");
    MyServer service;
    ServerBuilder builder;
    builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
    builder.RegisterService(&service);
    std::unique_ptr<Server> server(builder.BuildAndStart());
    std::cout << "server listen on ..." << server_address << std::endl;

    server->Wait();
}


int main(int argc, char **argv)
{
    RunServer();
    return 0;
}

客户端:

#include <iostream>
#include <memory>
#include <string>

#include <grpcpp/grpcpp.h> // 和python一样, import grp

// 在包含两个信息和应用的头文件
#include "hello.grpc.pb.h"
#include "hello.pb.h"

// 这是通用工具
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;



class MsgServiceClient {
 public:
  MsgServiceClient(std::shared_ptr<Channel> channel)
      : stub_(MsgService::NewStub(channel)) {}


  MsgResponse GetMsg(const std::string& user, int num1, double num2) {
    // 请求数据数据格式化到request
    MsgRequest request; 
    request.set_name(user);
    request.set_num1(num1);
    request.set_num2(num2);

    // 服务器返回端
    MsgResponse reply;

    //客户端上下文。它可以用来传递额外的信息
    //服务器和/或调整某些RPC行为。
    ClientContext context;

    // The actual RPC.
    Status status = stub_->GetMsg(&context, request, &reply);

    if (status.ok()) {
      return reply;
    } else {
      std::cout << status.error_code() << ": " << status.error_message()
                << std::endl;
      return reply;
    }
  }

 private:
  std::unique_ptr<MsgService::Stub> stub_;
};

int main(int argc, char** argv) {
  MsgServiceClient z_msg(grpc::CreateChannel(
      "localhost:50051", grpc::InsecureChannelCredentials()));
  std::string user("world");
  MsgResponse reply = z_msg.GetMsg(user);
  std::cout<<reply.msg()<<std::endl;
  printf("num1 = %d;  num2=%f\n", reply.num1(), reply.num2());
  
  return 0;
}

        cmake编译:

        CMakeLists.txt编写:

cmake_minimum_required(VERSION 3.5)
project(test2)

include(/XXX/gRPC/grpc/examples/cpp/cmake/common.cmake)#调用grpc环境配置,该路径为绝对路径

set(PWDIR ${CMAKE_CURRENT_SOURCE_DIR})
set(GRPCDIR "/XXX/gRPC/grpc/cmake/build/_install")#编译grpc时指定的安装路径

include_directories(
    ${PWDIR}
    ${GRPCDIR}/include
)

link_directories(
    ${GRPCDIR}/lib
)

add_library(hw_grpc_proto
    "${PWDIR}/hello.grpc.pb.cc"
    "${PWDIR}/hello.pb.cc"
)
target_link_libraries(hw_grpc_proto protobuf protobuf-lite protoc grpc++_reflection gRPC::grpc++)

foreach(_target
  hello_server hello_client)
  add_executable(${_target} "${_target}.cpp")
  target_link_libraries(${_target}
    hw_grpc_proto)
endforeach()

        后期会发布一篇grpc程序编写的完整流程,从proto,*.pb.cc, *.grpc.pb.cc解析 到服务器 客户端代码编写,cmake编写,返回状态设置,.cmake文件解析, rpc流式传输 的全面刨析,让您一篇文章学会grpc。

        感兴趣的话关注。一起交流学习。

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要使用 C++ 实现 HTTP 接口,可以使用 gRPC 的 HTTP/1.1 网关。gRPC 的 HTTP/1.1 网关是一个 gRPC 服务器,它将 RESTful HTTP API 转换为 gRPC。这个网关可以用于将现有的 RESTful HTTP API 转换为 gRPC,或者让 gRPC 服务提供 RESTful HTTP API。 以下是实现过程的一些步骤: 1. 安装和设置 gRPC:在 C++ 中使用 gRPC,需要安装 gRPCProtocol Buffers。可以从 gRPC 官方网站下载和安装 gRPC。 2. 定义 proto 文件:定义包含 HTTP 端点和请求/响应消息的 proto 文件。可以使用 protobuf 编译器将 proto 文件编译成 C++ 代码。 3. 实现 gRPC 服务:实现 gRPC 服务并编写处理程序来处理 HTTP 端点。 4. 配置 HTTP/1.1 网关:配置 HTTP/1.1 网关,使其将 RESTful HTTP API 转换为 gRPC。 5. 启动 HTTP/1.1 网关:启动 HTTP/1.1 网关,并且可以使用 RESTful HTTP API 访问 gRPC 服务。 在实现过程中,需要注意以下几点: 1. 在定义 proto 文件时,需要使用 HTTP 规范定义请求/响应消息。 2. 在实现 gRPC 服务时,需要根据 HTTP 规范处理 HTTP 请求和响应。 3. 在配置 HTTP/1.1 网关时,可以使用 Envoy 或 Istio 这样的开源代理来进行配置。 4. 在启动 HTTP/1.1 网关时,需要将其绑定到正确的端口,以便可以使用 RESTful HTTP API 访问 gRPC 服务。 总体来说,使用 gRPC 的 HTTP/1.1 网关可以在 C++实现 HTTP 接口,同时也可以让 gRPC 服务提供 RESTful HTTP API。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

迷茫的蜉蝣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值