• golang-grpc-操作,安装


    概念图

    在这里插入图片描述

    grpc使用

    安装

    按照grpc官方文档 https://grpc.io/docs/languages/go/quickstart/来运行

    $ protoc --go_out=. --go_opt=paths=source_relative \
        --go-grpc_out=. --go-grpc_opt=paths=source_relative \
        helloworld/helloworld.proto
    
    • 1
    • 2
    • 3

    This will regenerate the helloworld/helloworld.pb.go and helloworld/helloworld_grpc.pb.go files, which contain:

    Code for populating, serializing, and retrieving HelloRequest and HelloReply message types.
    Generated client and server code
    
    • 1
    • 2

    注:source_relative 会直接在本文件夹生成,而且不同于过往版本只生成一个pb.go
    在prot文件夹指定

    // name 表示生成的go文件所属的报名
    option go_package = "../service";
    
    • 1
    • 2

    然后将source_relative换成import即可
    eg:
    分布图:
    在这里插入图片描述

    D:\WORK\goCode\src\grpc_study\ms-proto\pbfile>protoc 
    --go_out=. --go_opt=paths=import 
    --go-grpc_out=. --go-grpc_opt=paths=import 
    ./product.proto
    
    • 1
    • 2
    • 3
    • 4

    注:./product.proto为目标proto所处地址

    eg

    server

    以product业务为例
    product.proto

    //指定的当前proto语法的版本,有2和3
    syntax = "proto3";
    //option go_package = "path;name" ;path表示生成的go文件的存放地址,会自动生成目录的
    // name 表示生成的go文件所属的报名
    option go_package = "../service";
    //指定等会文件生成出来的package
    package service;
    
    //定义request model
    message ProductRequest{
      int32  prod_id = 1; //1代表顺序
    }
    
    //定义response model
    message  ProductResponse{
      int32  pro_stock = 1; //1代表顺序
    }
    
    //定义服务主体
    service  ProdService{
      //定义方法
      rpc GetProductStock(ProductRequest) returns(ProductResponse);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    product.go
    在这个函数中写自己的业务逻辑,函数名为proto中所引用的函数名

    package service
    
    import (
    	"context"
    	"errors"
    	"fmt"
    	"time"
    )
    
    var ProductService = &productService{}
    
    type productService struct {
    }
    
    func (p *productService) mustEmbedUnimplementedProdServiceServer() {
    	panic(any("implement me"))
    }
    
    func (p *productService) GetProductStock(context context.Context, request *ProductRequest) (*ProductResponse, error) {
    	time.Sleep(2*time.Second)
    	select {
    	case <-context.Done():
    		fmt.Println("server product done")
    		return &ProductResponse{ProStock: 0}, errors.New("time out")
    	default:
    		//实现具体的业务逻辑
    		stock := p.GetStockById(request.ProdId)
    		fmt.Println("success")
    		return &ProductResponse{ProStock: stock}, nil
    	}
    }
    
    func (p *productService) GetStockById(id int32) int32 {
    	return id
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    grpc_server.go

    package main
    
    import (
    	"fmt"
    	"google.golang.org/grpc"
    	"grpc_study/ms-proto/service"
    	"log"
    	"net"
    )
    
    func main()  {
    	rpcServer := grpc.NewServer()
    
    	service.RegisterProdServiceServer(rpcServer,service.ProductService)
    
    	listener,err := net.Listen("tcp",":8002")
    	if err != nil{
    		log.Fatalln("启动监听出错",err)
    	}
    	err = rpcServer.Serve(listener)
    	if err != nil{
    		log.Fatalln("启动服务出错:",err)
    	}
    	fmt.Println("启动grpc服务端成功")
    
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    client

    server端引入grpc server的proto文件并且创建后,可以直接调用函数并支持传入ctx来传达超时和取消

    package main
    
    import (
    	"context"
    	"fmt"
    	"google.golang.org/grpc"
    	"google.golang.org/grpc/credentials/insecure"
    	"grpc_study/ms-proto/service"
    	"log"
    	"time"
    )
    
    func main()  {
    	conn,err := grpc.Dial(":8002",grpc.WithTransportCredentials(insecure.NewCredentials()))
    	if err != nil{
    		log.Fatal("服务端出错,连接失败",err)
    	}
    
    	defer conn.Close()
    
    	prodClient := service.NewProdServiceClient(conn)
    
    	request := &service.ProductRequest{
    		ProdId: 123,
    	}
    
    	ctx := context.Background()
    	proCtx,cancel  := context.WithTimeout(ctx,3*time.Second)
    	stockResponse,err := prodClient.GetProductStock(proCtx,request)
    	if err != nil{
    		log.Fatal("查询库存出错,",err)
    	}
    	defer cancel()
    
    	fmt.Println("查询成功",stockResponse.ProStock)
    	fmt.Println(stockResponse)
    }
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
  • 相关阅读:
    三个统一.
    vi-vim常用命令
    selectTree单选iview+vue
    一文搞懂百度强推的Redis天花板笔记,原来数据库是这样理解的
    SpringBoot+Vue项目实现身体健康诊疗系统
    用最少的代码打造一个Mini版的gRPC框架
    Mybatis架构简介
    css选择器
    ARM硬件断点
    【30. 串联所有单词的子串】
  • 原文地址:https://blog.csdn.net/flowerxxxxx/article/details/126562383