|
@@ -8,29 +8,27 @@ import (
|
|
|
msgdata "pbx-api-gin/internal/app/stc/data"
|
|
|
"pbx-api-gin/pkg/lfshook"
|
|
|
"sync"
|
|
|
-
|
|
|
"syscall"
|
|
|
+
|
|
|
"time"
|
|
|
)
|
|
|
|
|
|
+const RemotePort = 10100
|
|
|
+const LocalPort = 10201
|
|
|
+const RemoteAddr = "10.0.11.11"
|
|
|
+
|
|
|
func StartStcConnection(conn net.Conn) {
|
|
|
//var conn net.Conn
|
|
|
var wg sync.WaitGroup
|
|
|
- ServerAddr := "10.0.11.11"
|
|
|
- Port := 10100
|
|
|
|
|
|
for {
|
|
|
// 尝试建立连接
|
|
|
- conn, err := CreateConnection(ServerAddr, Port)
|
|
|
+ conn, err := CreateConnection()
|
|
|
if err != nil {
|
|
|
- fmt.Printf("连接失败 %s:%d,将在5秒后重试...\n", ServerAddr, Port)
|
|
|
- time.Sleep(5 * time.Second)
|
|
|
- lfshook.NewLogger().Logger.Infof("reconnect err %+v", err)
|
|
|
+ time.Sleep(2 * time.Second)
|
|
|
continue
|
|
|
}
|
|
|
-
|
|
|
- fmt.Printf("成功连接到 %s:%d\n", ServerAddr, Port)
|
|
|
-
|
|
|
+ lfshook.NewLogger().Logger.Infof("Connect success :%s:%d", RemoteAddr, RemotePort)
|
|
|
// 启动消息处理和心跳协程
|
|
|
wg.Add(2)
|
|
|
go func() {
|
|
@@ -50,30 +48,38 @@ func StartStcConnection(conn net.Conn) {
|
|
|
|
|
|
// 等待连接断开
|
|
|
wg.Wait()
|
|
|
- fmt.Println("检测到连接断开,准备重新连接...")
|
|
|
+ fmt.Println("Start Reconnect ...")
|
|
|
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,
|
|
|
- })
|
|
|
+func CreateConnection() (net.Conn, error) {
|
|
|
+ lfshook.NewLogger().Logger.Infof("========Connect server IP:%s :Port:%d", RemoteAddr, RemotePort)
|
|
|
+ // 创建 Dialer
|
|
|
+ dialer := &net.Dialer{
|
|
|
+ LocalAddr: &net.TCPAddr{IP: net.ParseIP("0.0.0.0"), Port: LocalPort}, // 固定本地端口
|
|
|
+ Control: controlTCPConn,
|
|
|
+ }
|
|
|
+
|
|
|
+ DialAddr := fmt.Sprintf("%s:%d", RemoteAddr, RemotePort)
|
|
|
+ conn, err := dialer.Dial("tcp", DialAddr)
|
|
|
if err != nil {
|
|
|
+ lfshook.NewLogger().Logger.Infof("========Connect server err :%+v", err)
|
|
|
return nil, err
|
|
|
}
|
|
|
- fileDesc, _ := conn.File()
|
|
|
- fd := fileDesc.Fd()
|
|
|
- syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
|
|
|
+
|
|
|
return conn, nil
|
|
|
}
|
|
|
+
|
|
|
+func controlTCPConn(network, address string, c syscall.RawConn) error {
|
|
|
+ return c.Control(func(fd uintptr) {
|
|
|
+ syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
|
|
|
+ // 注意:SO_REUSEPORT 在某些系统可用(如 Linux),但非标准
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
func Sendheartbeat(conn net.Conn) {
|
|
|
var count uint8
|
|
|
protocol := msgdata.NewProtocol()
|
|
@@ -88,13 +94,16 @@ func Sendheartbeat(conn net.Conn) {
|
|
|
// 编码并发送数据...
|
|
|
encoded, err := protocol.Encode()
|
|
|
if err != nil {
|
|
|
- fmt.Printf("编码失败: %v\n", err)
|
|
|
+ fmt.Printf("encode err : %v\n", err)
|
|
|
return
|
|
|
}
|
|
|
- _, err = conn.Write(encoded)
|
|
|
- if err != nil {
|
|
|
- fmt.Printf("发送心跳失败: %v\n", err)
|
|
|
- return // 触发重连
|
|
|
+ if conn != nil {
|
|
|
+ _, err = conn.Write(encoded)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Printf("Send hearbeat err: %v\n", err)
|
|
|
+ conn.Close()
|
|
|
+ return // 触发重连
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|