|
@@ -1,11 +1,12 @@
|
|
package stc
|
|
package stc
|
|
|
|
|
|
import (
|
|
import (
|
|
|
|
+ "context"
|
|
"fmt"
|
|
"fmt"
|
|
"net"
|
|
"net"
|
|
- "pbx-api-gin/internal/app/ami/action"
|
|
|
|
"pbx-api-gin/internal/app/stc/broadcast"
|
|
"pbx-api-gin/internal/app/stc/broadcast"
|
|
msgdata "pbx-api-gin/internal/app/stc/data"
|
|
msgdata "pbx-api-gin/internal/app/stc/data"
|
|
|
|
+ "pbx-api-gin/internal/app/stc/socket"
|
|
"pbx-api-gin/pkg/lfshook"
|
|
"pbx-api-gin/pkg/lfshook"
|
|
"sync"
|
|
"sync"
|
|
"syscall"
|
|
"syscall"
|
|
@@ -22,38 +23,56 @@ const RemoteAddr = "10.0.11.11"
|
|
|
|
|
|
func StartStcConnection(conn net.Conn) {
|
|
func StartStcConnection(conn net.Conn) {
|
|
//var conn net.Conn
|
|
//var conn net.Conn
|
|
- var wg sync.WaitGroup
|
|
|
|
- var err error
|
|
|
|
|
|
+ //var wg sync.WaitGroup
|
|
|
|
+ var connMux sync.Mutex // 保护 conn 的读写
|
|
|
|
+ //var err error
|
|
for {
|
|
for {
|
|
// 尝试建立连接
|
|
// 尝试建立连接
|
|
- conn, err = CreateConnection()
|
|
|
|
|
|
+ conn1, err := CreateConnection()
|
|
if err != nil {
|
|
if err != nil {
|
|
time.Sleep(2 * time.Second)
|
|
time.Sleep(2 * time.Second)
|
|
continue
|
|
continue
|
|
}
|
|
}
|
|
|
|
+ connMux.Lock()
|
|
|
|
+ oldConn := conn
|
|
|
|
+ socket.Conn = conn1
|
|
|
|
+ connMux.Unlock()
|
|
|
|
+
|
|
|
|
+ // 关闭旧连接(如果存在)
|
|
|
|
+ if oldConn != nil {
|
|
|
|
+ oldConn.Close()
|
|
|
|
+ lfshook.NewLogger().Logger.Infof("Closed previous connection")
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 使用 context 控制所有协程的生命周期
|
|
|
|
+ ctx, cancel := context.WithCancel(context.Background())
|
|
lfshook.NewLogger().Logger.Infof("Connect success :%s:%d", RemoteAddr, RemotePort)
|
|
lfshook.NewLogger().Logger.Infof("Connect success :%s:%d", RemoteAddr, RemotePort)
|
|
// 启动消息处理和心跳协程
|
|
// 启动消息处理和心跳协程
|
|
- wg.Add(2)
|
|
|
|
|
|
+ // 启动消息处理
|
|
go func() {
|
|
go func() {
|
|
- defer wg.Done()
|
|
|
|
- broadcast.HandleStcCmd(conn) // 处理消息
|
|
|
|
|
|
+ defer func() {
|
|
|
|
+ cancel() // 一旦任一协程退出,取消所有
|
|
|
|
+ }()
|
|
|
|
+ broadcast.HandleStcCmd(ctx, conn1) // 改造 HandleStcCmd 接收 ctx
|
|
}()
|
|
}()
|
|
|
|
+
|
|
|
|
+ // 启动心跳
|
|
go func() {
|
|
go func() {
|
|
- defer wg.Done()
|
|
|
|
- Sendheartbeat(conn) // 发送心跳
|
|
|
|
|
|
+ defer func() {
|
|
|
|
+ cancel()
|
|
|
|
+ }()
|
|
|
|
+ Sendheartbeat(ctx, conn1) // 改造 Sendheartbeat 接收 ctx
|
|
}()
|
|
}()
|
|
|
|
|
|
- //start AMI
|
|
|
|
- go action.StartAMI(func() {
|
|
|
|
- lfshook.NewLogger().Info("ami callback")
|
|
|
|
- // 首次连接才进行初始化
|
|
|
|
- }, []func(event map[string]string){}, conn)
|
|
|
|
-
|
|
|
|
- // 等待连接断开
|
|
|
|
- wg.Wait()
|
|
|
|
- fmt.Println("Start Reconnect ...")
|
|
|
|
- conn.Close() // 显式关闭旧连接
|
|
|
|
- time.Sleep(time.Second * 1) // 可选:断开后等待1秒再重试
|
|
|
|
|
|
+ // 等待连接断开(监听连接状态)
|
|
|
|
+ <-ctx.Done()
|
|
|
|
+
|
|
|
|
+ // 连接已断开,清理
|
|
|
|
+ cancel() // 确保所有 cancel 被调用
|
|
|
|
+ conn1.Close()
|
|
|
|
+
|
|
|
|
+ lfshook.NewLogger().Logger.Info("Reconnecting in 1 second...")
|
|
|
|
+ time.Sleep(time.Second) // 重连前等待
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -83,7 +102,7 @@ func controlTCPConn(network, address string, c syscall.RawConn) error {
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
-func Sendheartbeat(conn net.Conn) {
|
|
|
|
|
|
+func Sendheartbeat(ctx context.Context, conn net.Conn) {
|
|
var count uint8
|
|
var count uint8
|
|
protocol := msgdata.NewProtocol()
|
|
protocol := msgdata.NewProtocol()
|
|
// 初始化协议...
|
|
// 初始化协议...
|
|
@@ -92,6 +111,9 @@ func Sendheartbeat(conn net.Conn) {
|
|
|
|
|
|
for {
|
|
for {
|
|
select {
|
|
select {
|
|
|
|
+ case <-ctx.Done():
|
|
|
|
+ return
|
|
|
|
+
|
|
case <-ticker.C:
|
|
case <-ticker.C:
|
|
count++
|
|
count++
|
|
// 编码并发送数据...
|
|
// 编码并发送数据...
|