|
|
@@ -1,9 +1,17 @@
|
|
|
package main
|
|
|
|
|
|
import (
|
|
|
+ "bufio"
|
|
|
"context"
|
|
|
"errors"
|
|
|
"fmt"
|
|
|
+ "io"
|
|
|
+ "os"
|
|
|
+ "os/signal"
|
|
|
+ "strings"
|
|
|
+ "sync/atomic"
|
|
|
+ "syscall"
|
|
|
+ "time"
|
|
|
|
|
|
"github.com/google/uuid"
|
|
|
"hnyfkj.com.cn/rtu/linux/baseapp"
|
|
|
@@ -36,11 +44,11 @@ func main() {
|
|
|
}
|
|
|
|
|
|
if err := loadAppConfig(); err != nil {
|
|
|
- fmt.Printf("[%s] 错误: %v!!", MODULE_NAME, err)
|
|
|
+ fmt.Printf("[%s] 错误: %v!!\n", MODULE_NAME, err)
|
|
|
return
|
|
|
}
|
|
|
if CfgServers.MQTTSrv.Address == "" {
|
|
|
- fmt.Printf("[%s] 错误: %v!!", MODULE_NAME, ErrBrokerAddressEmpty)
|
|
|
+ fmt.Printf("[%s] 错误: %v!!\n", MODULE_NAME, ErrBrokerAddressEmpty)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
@@ -57,7 +65,7 @@ func main() {
|
|
|
}
|
|
|
|
|
|
if err := coupler.init2(); err != nil {
|
|
|
- fmt.Printf("[%s] 错误: %v!!", MODULE_NAME, err)
|
|
|
+ fmt.Printf("[%s] 错误: %v\n!!", MODULE_NAME, err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
@@ -73,7 +81,65 @@ func main() {
|
|
|
// 6, 等待返回结果, 打印输出
|
|
|
// 7, 循环等待下次, 直到退出
|
|
|
func term() {
|
|
|
+ var pingState atomic.Bool
|
|
|
+ var executing atomic.Bool
|
|
|
+
|
|
|
+ // -在线-心跳检测
|
|
|
+ heartbeatLoop(&pingState)
|
|
|
+
|
|
|
+ // Ctrl+C中断处理
|
|
|
+ interruptLoop(&executing)
|
|
|
+
|
|
|
+ reader := bufio.NewReader(os.Stdin)
|
|
|
for {
|
|
|
+ if !pingState.Load() {
|
|
|
+ fmt.Printf("[%s] 无法连接目标设备!!\n", MODULE_NAME)
|
|
|
+ break
|
|
|
+ }
|
|
|
+
|
|
|
+ fmt.Print("\033[?25h") // 显示光标
|
|
|
+ fmt.Printf("root@%s:%s# ", coupler.imei, coupler.cwd)
|
|
|
+
|
|
|
+ input, err := reader.ReadString('\n')
|
|
|
+ if err != nil {
|
|
|
+ if err == io.EOF {
|
|
|
+ os.Exit(0)
|
|
|
+ }
|
|
|
+ fmt.Println("读取用户输入失败:", err)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ input = strings.TrimSpace(input)
|
|
|
+ if input == "" {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ switch input {
|
|
|
+ case "quit":
|
|
|
+ _, _ = coupler.quit()
|
|
|
+ os.Exit(0)
|
|
|
+ }
|
|
|
+
|
|
|
+ fmt.Print("\033[?25l") // 隐藏光标
|
|
|
+ executing.Store(true)
|
|
|
+ result, err := coupler.exec(input)
|
|
|
+ executing.Store(false)
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ fmt.Printf("执行错误: %v\n", err)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ if result.Stdout != "" {
|
|
|
+ fmt.Println(result.Stdout)
|
|
|
+ }
|
|
|
+ if result.Stderr != "" {
|
|
|
+ fmt.Fprintln(os.Stderr, result.Stderr)
|
|
|
+ }
|
|
|
+
|
|
|
+ if result.Cwd != "" {
|
|
|
+ coupler.cwd = result.Cwd
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -86,3 +152,31 @@ func help() {
|
|
|
|
|
|
fmt.Println(h)
|
|
|
}
|
|
|
+
|
|
|
+func interruptLoop(executing *atomic.Bool) {
|
|
|
+ sigCh := make(chan os.Signal, 1)
|
|
|
+ signal.Notify(sigCh, syscall.SIGINT)
|
|
|
+ go func() {
|
|
|
+ for range sigCh {
|
|
|
+ if executing.Load() {
|
|
|
+ _, _ = coupler.stop()
|
|
|
+ }
|
|
|
+ fmt.Print("\n^C\n")
|
|
|
+ } // end for
|
|
|
+ }()
|
|
|
+}
|
|
|
+
|
|
|
+func heartbeatLoop(pingState *atomic.Bool) {
|
|
|
+ go func() {
|
|
|
+ ticker := time.NewTicker(1 * time.Second)
|
|
|
+ defer ticker.Stop()
|
|
|
+ for range ticker.C {
|
|
|
+ resp, err := coupler.ping()
|
|
|
+ if err == nil && resp.Error == nil && resp.Result != nil && string(resp.Result) == "pong" {
|
|
|
+ pingState.Store(true)
|
|
|
+ } else {
|
|
|
+ pingState.Store(false)
|
|
|
+ } // end if
|
|
|
+ } // end for
|
|
|
+ }()
|
|
|
+}
|