我正在使用 cobra 实现 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
?
所有源代码都在这个 repo中