You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							79 lines
						
					
					
						
							2.7 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							79 lines
						
					
					
						
							2.7 KiB
						
					
					
				
								package config
							 | 
						|
								
							 | 
						|
								import (
							 | 
						|
									"github.com/google/uuid"
							 | 
						|
									"github.com/spf13/viper"
							 | 
						|
									"log"
							 | 
						|
									"strings"
							 | 
						|
								)
							 | 
						|
								
							 | 
						|
								// Config 结构体必须与 config.yml 的结构完全对应
							 | 
						|
								// 使用 `mapstructure` tag 来帮助 Viper 正确映射 YAML 键名到 Go 结构体字段
							 | 
						|
								type Config struct {
							 | 
						|
									Server ServerConfig `mapstructure:"server"`
							 | 
						|
									Auth   AuthConfig   `mapstructure:"auth"`
							 | 
						|
									Redis  RedisConfig  `mapstructure:"redis"`
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								type ServerConfig struct {
							 | 
						|
									AppListenPort    string `mapstructure:"app_listen_port"`
							 | 
						|
									DeviceListenPort string `mapstructure:"device_listen_port"`
							 | 
						|
								
							 | 
						|
									// [新增]
							 | 
						|
									InstanceID        string `mapstructure:"instance_id"`
							 | 
						|
									GrpcListenAddr    string `mapstructure:"grpc_listen_addr"`
							 | 
						|
									GrpcAdvertiseAddr string `mapstructure:"grpc_advertise_addr"`
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								type AuthConfig struct {
							 | 
						|
									AppAccessSecret   string `mapstructure:"app_access_secret"`
							 | 
						|
									DeviceRelaySecret string `mapstructure:"device_relay_secret"`
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								type RedisConfig struct {
							 | 
						|
									Enabled           bool   `mapstructure:"enabled"`
							 | 
						|
									Addr              string `mapstructure:"addr"`
							 | 
						|
									Password          string `mapstructure:"password"`
							 | 
						|
									DB                int    `mapstructure:"db"`
							 | 
						|
									SessionTTLSeconds int    `mapstructure:"session_ttl_seconds"` // 确保有这个字段
							 | 
						|
								
							 | 
						|
									// [新增]
							 | 
						|
									InstanceRegistryKey string `mapstructure:"instance_registry_key"`
							 | 
						|
									InstanceTTLSeconds  int    `mapstructure:"instance_ttl_seconds"`
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// Cfg 是一个全局变量,用于在项目的任何地方访问配置
							 | 
						|
								var Cfg *Config
							 | 
						|
								
							 | 
						|
								// LoadConfig 是初始化函数,负责读取和解析配置文件
							 | 
						|
								func LoadConfig() {
							 | 
						|
									viper.SetConfigName("config")   // 配置文件名 (不带扩展名)
							 | 
						|
									viper.SetConfigType("yml")      // 配置文件类型
							 | 
						|
									viper.AddConfigPath(".")        // 在当前工作目录查找配置文件
							 | 
						|
									viper.AddConfigPath("./config") // 也在 config 目录查找
							 | 
						|
								
							 | 
						|
									// [关键] 开启环境变量支持
							 | 
						|
									// 这允许你通过环境变量覆盖配置文件中的值
							 | 
						|
									// 例如:SERVER_APP_LISTEN_ADDR=":9000" 会覆盖文件中的设置
							 | 
						|
									viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
							 | 
						|
									viper.AutomaticEnv()
							 | 
						|
								
							 | 
						|
									// 读取配置文件
							 | 
						|
									if err := viper.ReadInConfig(); err != nil {
							 | 
						|
										// 如果配置文件没找到,也没关系,可能完全通过环境变量配置
							 | 
						|
										if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
							 | 
						|
											log.Fatalf("Fatal error reading config file: %v", err)
							 | 
						|
										}
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									// 将读取到的配置反序列化到 Cfg 结构体中
							 | 
						|
									if err := viper.Unmarshal(&Cfg); err != nil {
							 | 
						|
										log.Fatalf("Unable to decode config into struct: %v", err)
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									// [新增] 如果 instance_id 未配置,则自动生成
							 | 
						|
									if Cfg.Server.InstanceID == "" {
							 | 
						|
										Cfg.Server.InstanceID = uuid.New().String()
							 | 
						|
									}
							 | 
						|
									log.Printf("Configuration loaded. Server Instance ID: %s", Cfg.Server.InstanceID)
							 | 
						|
								}
							 | 
						|
								
							 |