我正在使用眼镜蛇实现GRPC客户端。子命令后面有不同的服务调用。
为避免代码重复,我在viper
单例中保留了一个连接和一个客户端。但是我不确定这是正确的方法。
现在,在cmd/root.go::initConfig()
中,我创建连接和客户端并保存它们。
conn, err := grpc.Dial(address, grpc.WithInsecure())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
c := pb.NewCommandClient(conn)
viper.SetDefault("Client", c)
viper.SetDefault("Connection", conn)
在同一文件rootCmd.PersistentPostRun()
中定义的root.go
中关闭了连接。
PersistentPostRun: func(cmd *cobra.Command, args []string) {
conn := viper.Get("Connection").(*grpc.ClientConn)
conn.Close()
},
然后从viper
中检索客户端,并将其用于子命令的Run
文件中,例如
c := viper.Get("Client").(pb.CommandClient)
c.DoSomething() // call the service functions on c
此实现有效,但我不确定这是一个好习惯。具体地
viper
中有意义还是在每个子命令的Run
函数中创建一个新客户端更好?所有源代码都在this repo
中