如何在Go中创建通用GRPC服务器启动功能

时间:2019-04-22 21:25:57

标签: go grpc grpc-go

我正在尝试抽象GRPC服务器的启动

原始主要功能如下:

func main() {
    lis, err := net.Listen("tcp", port)
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }

    s := grpc.NewServer()
    pb.RegisterCollectionServer(s, &server.Server{})
    // Register reflection service on gRPC server.
    reflection.Register(s)
    if err := s.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}

我的目标是拥有这样的东西:

func startService(sr func(*grpc.Server, interface{}), srv interface{}) error {
    lis, err := net.Listen("tcp", port)
    if err != nil {
        return err
    }
    s := grpc.NewServer()
    sr(s, srv)
    reflection.Register(s)
    return s.Serve(lis)
}

func main() {
    err := startService(pb.RegisterCollectionServer, &server.Server{})

    if err != nil {
        log.Fatalf("failed to start Service: %v", err)
    }
}

但这给了我以下错误:

cannot use collection_api.RegisterCollectionServer (type func(*grpc.Server, collection_api.CollectionServer)) as type func(*grpc.Server, interface {}) in argument to startServicego

似乎collection_api.CollectionServer不是有效的interface{}类型。

有什么主意要怎么做吗?

1 个答案:

答案 0 :(得分:0)

在您的设置中,collector_api.RegisterCollectionServer的功能签名必须与func(*grpc.Server, interface{})完全匹配,Go中没有其他语言那样的“异类”。

如果要使startService函数独立于collection_api类型,可以在main()中使用匿名函数。如果您知道自己注册的内容始终取决于匿名函数(在本例中为&server.Server {})的实现,则可以将此细节保留在startService的函数签名中,然后放入进入匿名函数:

func startService(sr func(*grpc.Server)) error {
    lis, err := net.Listen("tcp", port)
    if err != nil {
        return err
    }
    s := grpc.NewServer()
    sr(s)
    reflection.Register(s)
    return s.Serve(lis)
}

func main() {
    err := startService(func(grpcServer *grpc.Server) {
            pb.RegisterCollectionServer(grpcServer, &server.Server{})
        }, &server.Server{})

    if err != nil {
        log.Fatalf("failed to start Service: %v", err)
    }
}