Files
go-utils/utils/net.go
陈兔子 eaaac7b20a v1.7.0
2025-09-12 02:33:18 +08:00

86 lines
1.5 KiB
Go

package utils
import (
"net"
"sync"
"time"
"github.com/spf13/cast"
)
// Net - 网络
var Net *NetClass
type NetClass struct {}
func (this *NetClass) Tcping(host any, opts ...map[string]any) (ok bool, detail []map[string]any) {
if len(opts) == 0 {
opts = append(opts, map[string]any{
"count": 4,
"timeout": 5,
})
}
opt := opts[0]
count := cast.ToInt(opt["count"])
timeout := cast.ToDuration(opt["timeout"]) * time.Second
// 读写锁 - 防止并发写入
type wrLock struct {
Lock *sync.RWMutex
Data []map[string]any
}
wr := wrLock{
Data: make([]map[string]any, 0),
Lock: &sync.RWMutex{},
}
wg := sync.WaitGroup{}
wg.Add(count)
for i := 0; i < count; i++ {
go func() {
defer wg.Done()
// 加锁
wr.Lock.Lock()
// 解锁
defer wr.Lock.Unlock()
start := time.Now()
_, err := net.DialTimeout("tcp", cast.ToString(host), timeout)
if err != nil {
wr.Data = append(wr.Data, map[string]any{
"host": host,
"status": false,
"waist": time.Now().Sub(start).Milliseconds(),
"message": "Site unreachable, error: " + err.Error(),
})
return
}
wr.Data = append(wr.Data, map[string]any{
"host": host,
"status": true,
"waist": time.Now().Sub(start).Milliseconds(),
"message": "tcp server is ok",
})
}()
}
wg.Wait()
// 只要有一个 ping 成功就返回 true
for _, val := range wr.Data {
if cast.ToBool(val["status"]) {
return true, wr.Data
}
}
return false, wr.Data
}