grpc的go和c++示例

微服务-gRPC的go和c++示例

一、环境搭建

1.1 go的gRPC环境搭建
1 protobuf环境搭建
# 安装 Go 的 Protocol Buffers 插件 `protoc-gen-go`(将protoc文件转为go文件) 并且引入protobuf相关go文件
go get -u github.com/golang/protobuf/protoc-gen-go
2 grpc环境搭建
go mod init 项目名称
go mod tidy`
go get -u google.golang.org/grpc
1.2 c++的gRPC环境搭建

1 protobuf环境搭建

参考:https://blog.csdn.net/weixin_54720578/article/details/132765947?spm=1001.2014.3001.5501

2 grpc环境搭建

参考:https://blog.csdn.net/weixin_54720578/article/details/132902296?spm=1001.2014.3001.5501

二、搭建一个微服务-go

2.1 服务端
1 编写proto文件
//文件位置:Server-gRPC/Profile/hello.proto
syntax = "proto3";
option go_package = "../Server";  //生成的go文件位于上一级文件下的Server文件下的Server包
service Server{     //服务
    rpc SayHello(HelloRequest) returns (HelloReply){}
    rpc GetMsg(HelloRequest) returns (HelloMessages){}
}
message HelloRequest{
    string name = 1;
}
message HelloReply{
    string message = 1;
}
message HelloMessages{
    string msg = 1;
}
2 生成go文件

在Server-gRPC/Profile目录下运行如下脚本:

protoc --go_out=plugins=grpc:. hello.proto

运行后将会在Server-gRPC/Server目录下生成hello.pb.go文件

3 编写服务
//文件位置:Server-gRPC/Server/hello.go
package Server
import (
	"context"
	"fmt"
)
type HelloServer struct{}
func (hs *HelloServer) SayHello(ctx context.Context, in *HelloRequest) (*HelloReply, error) {
	return &HelloReply{Message: "Hello"}, nil
}
func (hs *HelloServer) GetMsg(ctx context.Context, in *HelloRequest) (*HelloMessages, error) {
	fmt.Println(in.Name)
	return &HelloMessages{Msg: in.Name}, nil
}
4 开启服务
//文件位置:Server-gRPC/main.go
package main
import (
	"Service-rpc/Server"
	"fmt"
	"net"
	"google.golang.org/grpc"
)
func main() {
	//开启网络监听
	ln, err := net.Listen("tcp", "127.0.0.1:7777")
	if err != nil {
		fmt.Println(err)
	}
	//创建一个grpc服务
	srv := grpc.NewServer()
	//注册服务
	Server.RegisterServerServer(srv, &Server.HelloServer{})
	//服务开始监听
	fmt.Println("wait.....")
	err = srv.Serve(ln)
	if err != nil {
		fmt.Println(err)
	}
}

2.2 客户端
1 编写proto文件
//文件位置:Client-gRPC/Profile/hello.proto
syntax = "proto3";
option go_package = "../Server";  //生成的go文件位于上一级文件下的Server文件下的Server包
service Server{     //服务
    rpc SayHello(HelloRequest) returns (HelloReply){}
    rpc GetMsg(HelloRequest) returns (HelloMessages){}
}
message HelloRequest{
    string name = 1;
}
message HelloReply{
    string message = 1;
}
message HelloMessages{
    string msg = 1;
}
2 生成go文件

在Client-gRPC/Profile目录下运行如下脚本:

protoc --go_out=plugins=grpc:. hello.proto

运行后将会在Client-gRPC/Server目录下生成hello.pb.go文件

3 客户端调用服务
package main
import (
	"Client-gRPC/Server"
	"context"
	"fmt"

	"google.golang.org/grpc"

)
func main() {
	//连接gPRC服务器
	conn, err := grpc.Dial("127.0.0.1:7777", grpc.WithInsecure())
	if err != nil {
		fmt.Println(err)
	}
	defer conn.Close()
	//创建rpc客户端
	client := Server.NewServerClient(conn)
	//创建请求数据
	re := &Server.HelloRequest{Name: "zxh"}
	//远程调用
	reply, err := client.SayHello(context.Background(), re)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("SayHello:" + reply.Message)
	r, err := client.GetMsg(context.Background(), re)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("GetMsg:" + r.Msg)
}


三、搭建一个微服务-c++

3.1 服务端
1 编写proto文件
//文件位置:Server-gRPC-c++/Profile/hello.proto
syntax = "proto3";
package HServer;
service HelloServer{     //服务
    rpc SayHello(HelloRequest) returns (HelloReply){}
    rpc GetMsg(HelloRequest) returns (HelloMessages){}
}
message HelloRequest{
    string name = 1;
}
message HelloReply{
    string message = 1;
}
message HelloMessages{
    string msg = 1;
}
2 生成.h .cc文件

在Server-gRPC-c++/Profile/hello.proto中运行如下脚本

protoc --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` hello.proto

运行后将在Server-gRPC-c++/Profile中生成hello.grpc.pb.cc、hello.grpc.pb.h、hello.pb.cc、hello.pb.h文件

3 编写服务
//文件位置:Server-gRPC-c++/Server/hello.h
#include"../Profile/hello.grpc.pb.h"
#include<iostream>
using namespace std;

class HelloService final:public HServer::HelloServer::Service{
public:
    grpc::Status SayHello(grpc::ServerContext* context,const HServer::HelloRequest* request,HServer::HelloReply* reply)override;
    grpc::Status GetMsg(grpc::ServerContext* context,const HServer::HelloRequest* request,HServer::HelloMessages* hm)override;
};
//文件位置:Server-gRPC-c++/Server/hello.cpp
#include "hello.h"

grpc::Status HelloService::SayHello(
    grpc::ServerContext *context,
    const HServer::HelloRequest *request,
    HServer::HelloReply *reply)
{
    cout << "SayHello" << endl;
    reply->set_message("hello this is cpp server");
    return grpc::Status::OK;
}

grpc::Status HelloService::GetMsg(
    grpc::ServerContext *context,
    const HServer::HelloRequest *request,
    HServer::HelloMessages *hm)
{
    cout << request->name() << endl;
    hm->set_msg(request->name());
    return grpc::Status::OK;
}
4 开启服务
//文件位置:Server-gRPC-c++/main.cpp
#include<string>
#include <grpcpp/ext/proto_server_reflection_plugin.h>
#include<grpc++/grpc++.h>
#include <grpcpp/health_check_service_interface.h>
#include "Service/hello.h"
using namespace std;
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using HServer::HelloRequest;
using HServer::HelloReply;
using HServer::HelloMessages;
using HServer::HelloServer;

int main(){
    // 创建 gRPC 服务器
    grpc::EnableDefaultHealthCheckService(true);
    grpc::reflection::InitProtoReflectionServerBuilderPlugin();
    grpc::ServerBuilder builder;
    std::string server_address("0.0.0.0:50051"); // 监听地址和端口

    // 添加监听地址
    builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());

    // 注册您的服务实现类
    HelloService service;
    builder.RegisterService(&service);

    // 构建服务器
    std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
    std::cout << "wait.... " << server_address << std::endl;

    // 阻塞并等待关闭
    server->Wait();

    return 0;
}
5 编译(makefile)
# 根目录的Makefile

# 定义编译器和编译选项
CXX := g++
CXXFLAGS := -std=c++11 -Wl,--no-as-needed -Wl,--as-needed

# 定义第三方库的头文件和库文件路径
THIRD_PARTY_LIB1 := -L/usr/local/lib `pkg-config --libs grpc++ grpc`
THIRD_PARTY_LIB2 := -lprotobuf
THIRD_PARTY_LIB3 := -lpthread
THIRD_PARTY_LIB4 := -ldl
THIRD_PARTY_LIB5 := -lssl
THIRD_PARTY_LIB6 := -lgrpc++_reflection

# 列出所有的源文件
SRCS_MAIN := main.cpp
SRCS_SERVER := Service/hello.cpp 
SRCS_PEOFILE := Profile/hello.grpc.pb.cc Profile/hello.pb.cc

# 根据源文件生成目标文件的名字(替换.cpp为.o)
OBJS_MAIN := $(SRCS_MAIN:.cpp=.o)
OBJS_SERVER := $(SRCS_SERVER:.cpp=.o)
OBJS_PEOFILE =  $(SRCS_PEOFILE:.cc=.o)

# 目标可执行文件名
TARGET := prog

# 编译规则
all: $(TARGET)

$(TARGET): $(OBJS_MAIN) $(OBJS_SERVER) $(OBJS_PEOFILE)  #链接  
	$(CXX) $(CXXFLAGS) -o $@ $^ $(THIRD_PARTY_LIB1) $(THIRD_PARTY_LIB2) $(THIRD_PARTY_LIB3) $(THIRD_PARTY_LIB4) $(THIRD_PARTY_LIB5) $(THIRD_PARTY_LIB6)

%.o: %.cpp  #编译
	$(CXX) $(CXXFLAGS)  -o $@ -g -c $<

# 清理生成的文件
clean:
	rm -f $(OBJS_MAIN) $(OBJS_SERVER) $(OBJS_PEOFILE) 

3.2 客户端
1 编写proto文件
//文件位置:Client-gRPC-c++/Profile/hello.proto
syntax = "proto3";
package HServer;
service HelloServer{     //服务
    rpc SayHello(HelloRequest) returns (HelloReply){}
    rpc GetMsg(HelloRequest) returns (HelloMessages){}
}
message HelloRequest{
    string name = 1;
}
message HelloReply{
    string message = 1;
}
message HelloMessages{
    string msg = 1;
}
2 生成.h .cc文件

在Client-gRPC-c++/Profile/hello.proto中运行如下脚本

protoc --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` hello.proto

运行后将在Client-gRPC-c++/Profile中生成hello.grpc.pb.cc、hello.grpc.pb.h、hello.pb.cc、hello.pb.h文件

3 客户端
//文件位置:Client-gRPC-c++/main.cpp
#include <iostream>
#include <memory>
#include <string>
#include <grpcpp/grpcpp.h>
#include"Profile/hello.pb.h"
#include "Profile/hello.grpc.pb.h"

using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using HServer::HelloRequest;
using HServer::HelloReply;
using HServer::HelloMessages;
using HServer::HelloServer;

class HelloWorldClient {
public:
  HelloWorldClient(std::shared_ptr<Channel> channel)
    : stub_(HelloServer::NewStub(channel)) {}

  std::string SayHello(const std::string& name) {
    HelloRequest request;
    request.set_name(name);
    HelloReply reply;
    ClientContext context;
    Status status = stub_->SayHello(&context, request, &reply);
    if (status.ok()) {
      return reply.message();
    } else {
      std::cout << "RPC failed: " << status.error_message() << std::endl;
      return "RPC failed";
    }
  }

    std::string GetMsg(const std::string& name) {
    HelloRequest request;
    request.set_name(name);
    HelloMessages reply;
    ClientContext context;
    Status status = stub_->GetMsg(&context, request, &reply);
    if (status.ok()) {
      return reply.msg();
    } else {
      std::cout << "RPC failed: " << status.error_message() << std::endl;
      return "RPC failed";
    }
  }

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

int main() {
  HelloWorldClient client(grpc::CreateChannel("localhost:7777", grpc::InsecureChannelCredentials()));
  std::string user("world");
  std::string reply = client.SayHello(user);
  std::cout << "Received: " << reply << std::endl;
  return 0;
}
4 编译(makefile)
# 根目录的Makefile

# 定义编译器和编译选项
CXX := g++
CXXFLAGS := -std=c++11 -Wl,--no-as-needed -Wl,--as-needed


# 定义第三方库的头文件和库文件路径
THIRD_PARTY_LIB1 := -L/usr/local/lib `pkg-config --libs grpc++ grpc`
THIRD_PARTY_LIB2 := -lprotobuf
THIRD_PARTY_LIB3 := -lpthread
THIRD_PARTY_LIB4 := -ldl
THIRD_PARTY_LIB5 := -lssl
THIRD_PARTY_LIB6 := -lgrpc++_reflection


# 列出所有的源文件
SRCS_MAIN := main.cpp
SRCS_PEOFILE := Profile/hello.grpc.pb.cc Profile/hello.pb.cc

# 根据源文件生成目标文件的名字(替换.cpp为.o)
OBJS_MAIN := $(SRCS_MAIN:.cpp=.o)
OBJS_SERVER := $(SRCS_SERVER:.cpp=.o)
OBJS_PEOFILE =  $(SRCS_PEOFILE:.cc=.o)

# 目标可执行文件名
TARGET := prog

# 编译规则
all: $(TARGET)

$(TARGET): $(OBJS_MAIN) $(OBJS_SERVER) $(OBJS_PEOFILE)  #链接  
	$(CXX) $(CXXFLAGS) -o $@ $^ $(THIRD_PARTY_LIB1) $(THIRD_PARTY_LIB2) $(THIRD_PARTY_LIB3) $(THIRD_PARTY_LIB4) $(THIRD_PARTY_LIB5) $(THIRD_PARTY_LIB6)

%.o: %.cpp  #编译
	$(CXX) $(CXXFLAGS)  -o $@ -g -c $<

# 清理生成的文件
clean:
	rm -f $(OBJS_MAIN) $(OBJS_SERVER) $(OBJS_PEOFILE) 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值