开发服务端

服务端目录结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TmwDwGrM-1645623191843)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/ed647f5c-0853-4e34-a03f-02555f71992d/Untitled.png)]

a. 服务端处理函数

// service.go

package main

import (
	"context"
	"github.com/gofrs/uuid"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	pb "productinfo/service/ecommerce"
)

// 用来实现ecommerce/product_info 的服务器
type server struct {
	productMap map[string]*pb.Product
}

/*
Context 对象包含一些元数据,比如终端用户授权令牌的标识和请求的截止时间,
这些元数据会在请求的生命周期内一直存在
*/

// AddProduct 实现ecommerce.AddProduct的AddProduct方法
func (s *server) AddProduct(ctx context.Context, in *pb.Product) (*pb.ProductID, error) {
	out, err := uuid.NewV4() //生成商品的UID
	if err != nil {
		return nil, status.Errorf(codes.Internal, "Error while generating Product ID", err)
	}
	in.Id = out.String()
	// 初始化服务,如果服务未初始化
	if s.productMap == nil {
		s.productMap = make(map[string]*pb.Product)
	}
	s.productMap[in.Id] = in
	return &pb.ProductID{Value: in.Id}, status.New(codes.OK, "").Err()
}

// GetProduct 实现ecommerce.GetProduct的GetProduct方法
func (s *server) GetProduct(ctx context.Context, in *pb.ProductID) (*pb.Product, error) {
	value, exists := s.productMap[in.Value]
	if exists {
		return value, status.New(codes.OK, "").Err()
	}
	return nil, status.Errorf(codes.NotFound, "Product does not exits")
}

b.服务端主函数

// main.go
package main

import (
	"google.golang.org/grpc"
	"log"
	"net"
	pb "productinfo/service/ecommerce"
)

const (
	port = ":50051"
)

func main() {
	lis, err := net.Listen("tcp", port) //在50051端口上创建gRPC服务
	if err != nil {
		log.Fatalf("failed to listen:%v", err)
	}
	s := grpc.NewServer()                      //创建新的gRPC实例
	pb.RegisterProductInfoServer(s, &server{}) //将生成的服务注册到注册到新的gRPC上
	log.Printf("Starting gRPC listener on port:%s", port)
	// 在指定端口上开始监听传入的消息
	if err := s.Serve(lis); err != nil {
		log.Fatalf("failed to serve %v", err)
	}
}