目录架构
- client目录放置客户端代码,grpc_client.go用来调用服务端提供的服务,也就是某个函数
- pbfile目录放置proto文件,用来生成grpc代码
- service目录保存了生成的grpc代码,product.go实现了接口,也就是具体业务处理
- grpc_server.go是服务端代码,用来提供服务,以便客户端来连接,访问对应的服务
创建product.proto
// 这个就是protobuf的中间文件
// 指定的当前proto语法的版本,有2和3
syntax = "proto3";
option go_package="../service";
// 指定等会文件生成出来的package
package service;
// 定义request model
message ProductRequest{
int32 prod_id = 1; // 1代表顺序
}
// 定义response model
message ProductResponse{
int32 prod_stock = 1; // 1代表顺序
}
// 定义服务主体
service ProdService{
// 定义方法
rpc GetProductStock(ProductRequest) returns(ProductResponse);
}
生成grpc代码
protoc --go_out=plugins=grpc:./ ./product.proto
服务端
//grpc_server.go
package main
import (
"google.golang.org/grpc"
"log"
"net"
"test_grpc/service"
)
func main() {
rpcServer := grpc.NewServer()
service.RegisterProdServiceServer(rpcServer, service.ProductService)
listener, err := net.Listen("tcp", ":8002")
if err != nil {
log.Fatal("服务监听端口失败", err)
}
err = rpcServer.Serve(listener)
if err != nil {
log.Fatal("启动服务失败", err)
}
}
//product.go
package service
import "context"
//全局对象,在服务器端代码中绑定
var ProductService = &productService{}
type productService struct {
}
//业务代码,实现接口
func (p *productService) GetProductStock(context context.Context, request *ProductRequest) (*ProductResponse, error) {
//根据商品id查询商品库存
stock := p.GetStockById(request.ProdId)
return &ProductResponse{ProdStock: stock}, nil
}
func (p *productService) GetStockById(id int32) int32 {
return id
}
客户端
//grpc_client.go
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"log"
"test_grpc/client/service"
)
func main() {
// 1. 新建连接,端口是服务端开放的8002端口
// 没有证书会报错
conn, err := grpc.Dial(":8002", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatal("服务端出错,连接不上", err)
}
// 退出时关闭链接
defer conn.Close()
// 2. 调用Product.pb.go中的NewProdServiceClient方法
prodClient := service.NewProdServiceClient(conn)
// 3. 直接像调用本地方法一样调用GetProductStock方法
request := &service.ProductRequest{
ProdId: 123,
}
stockResponse, err := prodClient.GetProductStock(context.Background(), request)
if err != nil {
panic(err)
}
fmt.Println("调用gRPC方法成功,ProdStock = ", stockResponse.ProdStock)
}