package stc import ( "fmt" "net" "pbx-api-gin/internal/app/stc/broadcast" msgdata "pbx-api-gin/internal/app/stc/data" "sync" "syscall" "time" ) func StartStcConnection(ServerAddr string, Port int) { //var conn net.Conn var wg sync.WaitGroup for { // 尝试建立连接 conn, err := CreateConnection(ServerAddr, Port) if err != nil { fmt.Printf("连接失败 %s:%d,将在5秒后重试...\n", ServerAddr, Port) time.Sleep(5 * time.Second) continue } fmt.Printf("成功连接到 %s:%d\n", ServerAddr, Port) // 启动消息处理和心跳协程 wg.Add(2) go func() { defer wg.Done() broadcast.HandleStcCmd(conn) // 处理消息 }() go func() { defer wg.Done() Sendheartbeat(conn) // 发送心跳 }() // 等待连接断开 wg.Wait() fmt.Println("检测到连接断开,准备重新连接...") conn.Close() // 显式关闭旧连接 time.Sleep(time.Second * 1) // 可选:断开后等待1秒再重试 } } // 返回错误而不是终止程序 func CreateConnection(ServerAddr string, Port int) (net.Conn, error) { fmt.Println("========== conn server ==========") conn, err := net.DialTCP("tcp", &net.TCPAddr{ IP: net.ParseIP("0.0.0.0"), Port: 10201, }, &net.TCPAddr{ IP: net.ParseIP(ServerAddr), Port: Port, }) if err != nil { return nil, err } fileDesc, _ := conn.File() fd := fileDesc.Fd() syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1) return conn, nil } func Sendheartbeat(conn net.Conn) { var count uint8 protocol := msgdata.NewProtocol() // 初始化协议... ticker := time.NewTicker(2 * time.Second) defer ticker.Stop() for { select { case <-ticker.C: count++ // 编码并发送数据... encoded, err := protocol.Encode() if err != nil { fmt.Printf("编码失败: %v\n", err) return } _, err = conn.Write(encoded) if err != nil { fmt.Printf("发送心跳失败: %v\n", err) return // 触发重连 } } } } // 检查PA server是主状态还是从状态 func CheckMaster(conn net.Conn) bool { // var count uint8 //init heartbeat data protocol := msgdata.NewProtocol() protocol.SourceID = 0x02 protocol.DestinationID = 0x01 protocol.MessageID = 0x21 protocol.DataLength = 0x04 return false }