chore: upload current project state
This commit is contained in:
@@ -0,0 +1,278 @@
|
||||
package portmanager
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"FireLeave_tool/logger"
|
||||
)
|
||||
|
||||
// PortManager 管理端口分配
|
||||
type PortManager struct {
|
||||
mu sync.Mutex
|
||||
allocated map[string]DevicePorts // DeviceUUID 到端口映射的映射
|
||||
portPool []int // 推理端口池(HTTP)
|
||||
available map[int]bool // 可用端口标记
|
||||
}
|
||||
|
||||
// NewPortManager 创建端口管理器
|
||||
func NewPortManager() *PortManager {
|
||||
// 初始化端口池
|
||||
var ports []int
|
||||
for port := BasePortStart; port <= BasePortEnd; port++ {
|
||||
ports = append(ports, port)
|
||||
}
|
||||
|
||||
// 初始化可用端口映射
|
||||
available := make(map[int]bool)
|
||||
for _, port := range ports {
|
||||
available[port] = true
|
||||
}
|
||||
|
||||
return &PortManager{
|
||||
allocated: make(map[string]DevicePorts),
|
||||
portPool: ports,
|
||||
available: available,
|
||||
}
|
||||
}
|
||||
|
||||
// AllocatePort 为设备分配基础端口
|
||||
func (pm *PortManager) AllocatePort(deviceUUID string) (int, error) {
|
||||
pm.mu.Lock()
|
||||
defer pm.mu.Unlock()
|
||||
|
||||
// 检查设备是否已分配端口
|
||||
if ports, exists := pm.allocated[deviceUUID]; exists {
|
||||
logger.Logger.Printf("Device %s already allocated port: %d", deviceUUID, ports.Inference)
|
||||
return ports.Inference, nil
|
||||
}
|
||||
|
||||
// 查找可用端口
|
||||
for _, port := range pm.portPool {
|
||||
if !pm.available[port] {
|
||||
continue // 端口已被分配
|
||||
}
|
||||
|
||||
tempPort := port + TemperaturePortOffset // 温度端口(TCP)
|
||||
|
||||
// 检查推理端口(HTTP)是否可用
|
||||
inferenceLn, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
|
||||
if err != nil {
|
||||
logger.Logger.Printf("Port %d (inference) is not available: %v", port, err)
|
||||
continue
|
||||
}
|
||||
inferenceLn.Close()
|
||||
|
||||
// 检查温度端口(TCP)是否可用
|
||||
tempLn, err := net.Listen("tcp", fmt.Sprintf(":%d", tempPort))
|
||||
if err != nil {
|
||||
logger.Logger.Printf("Port %d (temperature) is not available: %v", tempPort, err)
|
||||
continue
|
||||
}
|
||||
tempLn.Close()
|
||||
|
||||
// 端口可用,记录分配
|
||||
pm.allocated[deviceUUID] = DevicePorts{
|
||||
Inference: port,
|
||||
Temperature: tempPort,
|
||||
}
|
||||
pm.available[port] = false
|
||||
|
||||
logger.Logger.Printf("Port allocated for device %s: inference=%d, temperature=%d",
|
||||
deviceUUID, port, tempPort)
|
||||
return port, nil
|
||||
}
|
||||
|
||||
return 0, errors.New("no available ports for inference and temperature")
|
||||
}
|
||||
|
||||
// AllocateFireCheckPort 为火焰检测程序分配端口
|
||||
func (pm *PortManager) AllocateFireCheckPort(deviceUUID string) (int, error) {
|
||||
pm.mu.Lock()
|
||||
defer pm.mu.Unlock()
|
||||
|
||||
// 检查设备是否已分配端口
|
||||
ports, exists := pm.allocated[deviceUUID]
|
||||
if !exists {
|
||||
// 先分配基础端口
|
||||
_, err := pm.AllocatePort(deviceUUID)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("failed to allocate base port: %v", err)
|
||||
}
|
||||
// 重新获取更新后的端口映射
|
||||
ports = pm.allocated[deviceUUID]
|
||||
}
|
||||
|
||||
// 计算火焰检测端口
|
||||
fireCheckPort := ports.Inference + FireCheckPortOffset
|
||||
|
||||
// 检查火焰检测端口是否可用
|
||||
fireCheckLn, err := net.Listen("tcp", fmt.Sprintf(":%d", fireCheckPort))
|
||||
if err != nil {
|
||||
logger.Logger.Printf("Port %d (fire_check) is not available: %v", fireCheckPort, err)
|
||||
return 0, fmt.Errorf("fire check port %d not available: %v", fireCheckPort, err)
|
||||
}
|
||||
fireCheckLn.Close()
|
||||
|
||||
// 更新端口映射
|
||||
ports.FireCheck = fireCheckPort
|
||||
pm.allocated[deviceUUID] = ports
|
||||
|
||||
logger.Logger.Printf("Fire check port allocated for device %s: %d", deviceUUID, fireCheckPort)
|
||||
return fireCheckPort, nil
|
||||
}
|
||||
|
||||
// ReleasePort 释放设备端口
|
||||
func (pm *PortManager) ReleasePort(deviceUUID string) {
|
||||
pm.mu.Lock()
|
||||
defer pm.mu.Unlock()
|
||||
|
||||
// 删除设备端口映射
|
||||
if ports, exists := pm.allocated[deviceUUID]; exists {
|
||||
delete(pm.allocated, deviceUUID)
|
||||
pm.available[ports.Inference] = true // 标记基础端口为可用
|
||||
logger.Logger.Printf("Port released for device %s: inference=%d, temperature=%d, fire_check=%d",
|
||||
deviceUUID, ports.Inference, ports.Temperature, ports.FireCheck)
|
||||
}
|
||||
}
|
||||
|
||||
// GetPort 获取设备基础端口
|
||||
func (pm *PortManager) GetPort(deviceUUID string) (int, error) {
|
||||
pm.mu.Lock()
|
||||
defer pm.mu.Unlock()
|
||||
|
||||
if ports, exists := pm.allocated[deviceUUID]; exists {
|
||||
return ports.Inference, nil
|
||||
}
|
||||
|
||||
return 0, fmt.Errorf("device %s has no allocated port", deviceUUID)
|
||||
}
|
||||
|
||||
// GetFireCheckPort 获取火焰检测程序端口
|
||||
func (pm *PortManager) GetFireCheckPort(deviceUUID string) (int, error) {
|
||||
pm.mu.Lock()
|
||||
defer pm.mu.Unlock()
|
||||
|
||||
if ports, exists := pm.allocated[deviceUUID]; exists {
|
||||
if ports.FireCheck > 0 {
|
||||
return ports.FireCheck, nil
|
||||
}
|
||||
return 0, fmt.Errorf("device %s has no allocated fire check port", deviceUUID)
|
||||
}
|
||||
|
||||
return 0, fmt.Errorf("device %s has no allocated ports", deviceUUID)
|
||||
}
|
||||
|
||||
// GetTemperaturePort 获取温度程序端口
|
||||
func (pm *PortManager) GetTemperaturePort(deviceUUID string) (int, error) {
|
||||
pm.mu.Lock()
|
||||
defer pm.mu.Unlock()
|
||||
|
||||
if ports, exists := pm.allocated[deviceUUID]; exists {
|
||||
return ports.Temperature, nil
|
||||
}
|
||||
|
||||
return 0, fmt.Errorf("device %s has no allocated ports", deviceUUID)
|
||||
}
|
||||
|
||||
// GetAllocatedPorts 获取所有已分配的端口信息
|
||||
func (pm *PortManager) GetAllocatedPorts() []PortInfo {
|
||||
pm.mu.Lock()
|
||||
defer pm.mu.Unlock()
|
||||
|
||||
var portInfos []PortInfo
|
||||
now := time.Now().Unix()
|
||||
|
||||
for deviceUUID, ports := range pm.allocated {
|
||||
// 基础推理端口
|
||||
portInfos = append(portInfos, PortInfo{
|
||||
DeviceUUID: deviceUUID,
|
||||
PortType: PortTypeInference,
|
||||
Port: ports.Inference,
|
||||
AllocatedAt: now,
|
||||
})
|
||||
|
||||
// 温度端口
|
||||
portInfos = append(portInfos, PortInfo{
|
||||
DeviceUUID: deviceUUID,
|
||||
PortType: PortTypeTemperature,
|
||||
Port: ports.Temperature,
|
||||
AllocatedAt: now,
|
||||
})
|
||||
|
||||
// 火焰检测端口
|
||||
if ports.FireCheck > 0 {
|
||||
portInfos = append(portInfos, PortInfo{
|
||||
DeviceUUID: deviceUUID,
|
||||
PortType: PortTypeFireCheck,
|
||||
Port: ports.FireCheck,
|
||||
AllocatedAt: now,
|
||||
})
|
||||
}
|
||||
|
||||
// 新推理端口
|
||||
if ports.NewInference > 0 {
|
||||
portInfos = append(portInfos, PortInfo{
|
||||
DeviceUUID: deviceUUID,
|
||||
PortType: PortTypeNewInference,
|
||||
Port: ports.NewInference,
|
||||
AllocatedAt: now,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return portInfos
|
||||
}
|
||||
|
||||
// GetDevicePorts 获取设备的所有端口
|
||||
func (pm *PortManager) GetDevicePorts(deviceUUID string) (DevicePorts, error) {
|
||||
pm.mu.Lock()
|
||||
defer pm.mu.Unlock()
|
||||
|
||||
if ports, exists := pm.allocated[deviceUUID]; exists {
|
||||
return ports, nil
|
||||
}
|
||||
|
||||
return DevicePorts{}, fmt.Errorf("device %s has no allocated ports", deviceUUID)
|
||||
}
|
||||
|
||||
// IsPortAvailable 检查端口是否可用
|
||||
func (pm *PortManager) IsPortAvailable(port int) bool {
|
||||
pm.mu.Lock()
|
||||
defer pm.mu.Unlock()
|
||||
|
||||
// 检查是否在端口池中
|
||||
for _, p := range pm.portPool {
|
||||
if p == port {
|
||||
return pm.available[port]
|
||||
}
|
||||
}
|
||||
|
||||
// 对于非端口池中的端口,直接检查可用性
|
||||
ln, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
ln.Close()
|
||||
return true
|
||||
}
|
||||
|
||||
// GetAvailablePortCount 获取可用端口数量
|
||||
func (pm *PortManager) GetAvailablePortCount() int {
|
||||
pm.mu.Lock()
|
||||
defer pm.mu.Unlock()
|
||||
|
||||
count := 0
|
||||
for _, available := range pm.available {
|
||||
if available {
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
// GlobalPortManager 全局端口管理器
|
||||
var GlobalPortManager = NewPortManager()
|
||||
Reference in New Issue
Block a user