开发服务端
服务端目录结构
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)
}
}