Skip to content

Commit

Permalink
feat: 服务器连接质量测试
Browse files Browse the repository at this point in the history
  • Loading branch information
Redmomn committed Nov 28, 2024
1 parent da2c1ae commit 5f3e287
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 4 deletions.
56 changes: 52 additions & 4 deletions client/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/LagrangeDev/LagrangeGo/client/internal/network"
"github.com/LagrangeDev/LagrangeGo/client/internal/oicq"
"github.com/LagrangeDev/LagrangeGo/message"
"github.com/LagrangeDev/LagrangeGo/utils"
"github.com/pkg/errors"
)

Expand All @@ -23,16 +24,51 @@ type ConnectionQualityInfo struct {
ChatServerLatency int64
// ChatServerPacketLoss 聊天服务器ICMP丢包数
ChatServerPacketLoss int
// LongMessageServerLatency 长消息服务器延迟. 涉及长消息以及合并转发消息下载
LongMessageServerLatency int64
// LongMessageServerResponseLatency 长消息服务器返回延迟
LongMessageServerResponseLatency int64
// SrvServerLatency Highway服务器延迟. 涉及媒体以及群文件上传
SrvServerLatency int64
// SrvServerPacketLoss Highway服务器ICMP丢包数.
SrvServerPacketLoss int
}

func (c *QQClient) ConnectionQualityTest() *ConnectionQualityInfo {
if !c.Online.Load() {
return nil
}
r := &ConnectionQualityInfo{}
wg := sync.WaitGroup{}
wg.Add(2)

currentServerAddr := c.servers[c.currServerIndex].String()
go func() {
defer wg.Done()
var err error

if r.ChatServerLatency, err = qualityTest(currentServerAddr); err != nil {
c.error("test chat server latency error: %v", err)
r.ChatServerLatency = 9999
}

_ = c.ensureHighwayServers()
if c.highwaySession.AddrLength() > 0 {
if r.SrvServerLatency, err = qualityTest(c.highwaySession.SsoAddr[0].String()); err != nil {
c.error("test srv server latency error: %v", err)
r.SrvServerLatency = 9999
}
}
}()
go func() {
defer wg.Done()
res := utils.RunTCPPingLoop(currentServerAddr, 10)
r.ChatServerPacketLoss = res.PacketsLoss
if c.highwaySession.AddrLength() > 0 {
res = utils.RunTCPPingLoop(c.highwaySession.SsoAddr[0].String(), 10)
r.SrvServerPacketLoss = res.PacketsLoss
}
}()
wg.Wait()
return r
}

func (c *QQClient) initServers() {
adds, err := net.LookupIP("msfwifi.3g.qq.com") // host servers
if err == nil && len(adds) > 0 {
Expand Down Expand Up @@ -95,14 +131,26 @@ func (c *QQClient) connect() error {
return err
}
c.once.Do(func() {
c.SelfGroupMessageEvent.Subscribe(func(_ *QQClient, _ *message.GroupMessage) {
c.stat.MessageReceived.Add(1)
c.stat.LastMessageTime.Store(time.Now().Unix())
})
c.GroupMessageEvent.Subscribe(func(_ *QQClient, _ *message.GroupMessage) {
c.stat.MessageReceived.Add(1)
c.stat.LastMessageTime.Store(time.Now().Unix())
})
c.SelfPrivateMessageEvent.Subscribe(func(_ *QQClient, _ *message.PrivateMessage) {
c.stat.MessageReceived.Add(1)
c.stat.LastMessageTime.Store(time.Now().Unix())
})
c.PrivateMessageEvent.Subscribe(func(_ *QQClient, _ *message.PrivateMessage) {
c.stat.MessageReceived.Add(1)
c.stat.LastMessageTime.Store(time.Now().Unix())
})
c.SelfTempMessageEvent.Subscribe(func(_ *QQClient, _ *message.TempMessage) {
c.stat.MessageReceived.Add(1)
c.stat.LastMessageTime.Store(time.Now().Unix())
})
c.TempMessageEvent.Subscribe(func(_ *QQClient, _ *message.TempMessage) {
c.stat.MessageReceived.Add(1)
c.stat.LastMessageTime.Store(time.Now().Unix())
Expand Down
57 changes: 57 additions & 0 deletions utils/tcping.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package utils

import (
"net"
"time"
)

// ref https://github.com/Mrs4s/MiraiGo/blob/54bdd873e3fed9fe1c944918924674dacec5ac76/utils/tcping.go

type ICMPPingResult struct {
PacketsSent int
PacketsLoss int
AvgTimeMill int64
}

// RunTCPPingLoop 使用 tcp 进行 ping
func RunTCPPingLoop(ipport string, count int) (r ICMPPingResult) {
r = ICMPPingResult{
PacketsSent: count,
PacketsLoss: count,
AvgTimeMill: 9999,
}
if count <= 0 {
return
}
durs := make([]int64, 0, count)
for i := 0; i < count; i++ {
d, err := tcping(ipport)
if err == nil {
r.PacketsLoss--
durs = append(durs, d)
}
time.Sleep(time.Millisecond * 100)
}

if len(durs) > 0 {
r.AvgTimeMill = 0
for _, d := range durs {
r.AvgTimeMill += d
}
if len(durs) > 1 {
r.AvgTimeMill /= int64(len(durs))
}
}

return
}

func tcping(ipport string) (int64, error) {
t := time.Now().UnixMilli()
conn, err := net.DialTimeout("tcp", ipport, time.Second*10)
if err != nil {
return 9999, err
}
_ = conn.Close()
return time.Now().UnixMilli() - t, nil
}

0 comments on commit 5f3e287

Please sign in to comment.