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.
		
		
		
		
			
				
					74 lines
				
				2.1 KiB
			
		
		
			
		
	
	
					74 lines
				
				2.1 KiB
			| 
								 
											2 weeks ago
										 
									 | 
							
								package registry
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import (
							 | 
						||
| 
								 | 
							
									"context"
							 | 
						||
| 
								 | 
							
									"encoding/json"
							 | 
						||
| 
								 | 
							
									"log"
							 | 
						||
| 
								 | 
							
									"memobus_relay_server/config" // 替换为你的模块名
							 | 
						||
| 
								 | 
							
									"memobus_relay_server/storage"
							 | 
						||
| 
								 | 
							
									"time"
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// InstanceInfo 定义了要注册到 Redis 的实例信息
							 | 
						||
| 
								 | 
							
								type InstanceInfo struct {
							 | 
						||
| 
								 | 
							
									InstanceID       string `json:"instanceId"`
							 | 
						||
| 
								 | 
							
									PublicAppAddr    string `json:"publicAppAddr"`
							 | 
						||
| 
								 | 
							
									PublicDeviceAddr string `json:"publicDeviceAddr"`
							 | 
						||
| 
								 | 
							
									// 还可以增加负载信息
							 | 
						||
| 
								 | 
							
									ConnectedDevices int       `json:"connectedDevices"`
							 | 
						||
| 
								 | 
							
									LastHeartbeat    time.Time `json:"lastHeartbeat"`
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func StartHeartbeat(getDeviceCount func() int) {
							 | 
						||
| 
								 | 
							
									if storage.RedisClient == nil {
							 | 
						||
| 
								 | 
							
										log.Println("Registry heartbeat is disabled because Redis is not enabled.")
							 | 
						||
| 
								 | 
							
										return
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									interval := time.Duration(config.Cfg.Redis.HeartbeatIntervalSeconds) * time.Second
							 | 
						||
| 
								 | 
							
									ticker := time.NewTicker(interval)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									updateHeartbeat := func() {
							 | 
						||
| 
								 | 
							
										info := InstanceInfo{
							 | 
						||
| 
								 | 
							
											InstanceID:       config.Cfg.Server.InstanceID,
							 | 
						||
| 
								 | 
							
											PublicAppAddr:    config.Cfg.Server.PublicAppAddr,
							 | 
						||
| 
								 | 
							
											PublicDeviceAddr: config.Cfg.Server.PublicDeviceAddr,
							 | 
						||
| 
								 | 
							
											ConnectedDevices: getDeviceCount(),
							 | 
						||
| 
								 | 
							
											LastHeartbeat:    time.Now(),
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										jsonData, _ := json.Marshal(info)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										key := config.Cfg.Redis.InstanceRegistryKey
							 | 
						||
| 
								 | 
							
										instanceID := config.Cfg.Server.InstanceID
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if err := storage.RedisClient.HSet(context.Background(), key, instanceID, jsonData).Err(); err != nil {
							 | 
						||
| 
								 | 
							
											log.Printf("ERROR: Failed to send heartbeat to Redis: %v", err)
							 | 
						||
| 
								 | 
							
										} else {
							 | 
						||
| 
								 | 
							
											log.Printf("Heartbeat sent. Connected devices: %d", info.ConnectedDevices)
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									go func() {
							 | 
						||
| 
								 | 
							
										updateHeartbeat() // 立即执行一次
							 | 
						||
| 
								 | 
							
										for range ticker.C {
							 | 
						||
| 
								 | 
							
											updateHeartbeat()
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}()
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func Unregister() {
							 | 
						||
| 
								 | 
							
									if storage.RedisClient == nil {
							 | 
						||
| 
								 | 
							
										return
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									log.Println("Unregistering instance from Redis...")
							 | 
						||
| 
								 | 
							
									key := config.Cfg.Redis.InstanceRegistryKey
							 | 
						||
| 
								 | 
							
									instanceID := config.Cfg.Server.InstanceID
							 | 
						||
| 
								 | 
							
									if err := storage.RedisClient.HDel(context.Background(), key, instanceID).Err(); err != nil {
							 | 
						||
| 
								 | 
							
										// 如果注销失败,打印一个错误日志
							 | 
						||
| 
								 | 
							
										log.Printf("ERROR: Failed to unregister instance '%s' from Redis: %v", instanceID, err)
							 | 
						||
| 
								 | 
							
									} else {
							 | 
						||
| 
								 | 
							
										// 只有在确认没有错误后,才打印成功日志
							 | 
						||
| 
								 | 
							
										log.Println("Successfully unregistered.")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |