- ConsoleLogConfig 增加 Meshtastic 字段(默认 true);旧配置自动补齐 - meshtasticFilterHook 增加 packetConsoleLog;OnPublish 中根据开关调用 新的 printMeshtasticRecord 输出可读单行(key=value、按 type 着色), 替代原来的 JSON dump;事件型 printJSON 调用保持不变 - 新增 internal/mqttforward/ClientStats,按 client_id 累计 in/out 报文计数 - meshtasticFilterHook 多挂 OnPacketRead / OnPacketSent / OnDisconnect 事件,用于增减计数;Provides() 同步声明 - AdminMQTTClient JSON 视图删除 RemoteHost/RemotePort,新增 packets_in / packets_out;前端 types.ts、AdminDashboard.vue 同步更新 Co-Authored-By: Claude <noreply@anthropic.com>
75 lines
1.8 KiB
Go
75 lines
1.8 KiB
Go
package mqttforward
|
||
|
||
import "sync"
|
||
|
||
// ClientStats 在内存中维护每个 MQTT 客户端的收/发包数量。
|
||
// key 取自 mqtt.Client.ID(broker 内部唯一标识),客户端断开时由调用方调用 Delete 清除,
|
||
// 重新连接同一 client_id 会拿到一份新的零值计数,符合"断链就清空"。
|
||
type ClientStats struct {
|
||
mu sync.RWMutex
|
||
all map[string]*clientCounter
|
||
}
|
||
|
||
type clientCounter struct {
|
||
In int64 // 客户端 → 服务器(broker 收到的报文数)
|
||
Out int64 // 服务器 → 客户端(broker 发出的报文数)
|
||
}
|
||
|
||
// NewClientStats 返回一个空的统计器。
|
||
func NewClientStats() *ClientStats {
|
||
return &ClientStats{all: make(map[string]*clientCounter)}
|
||
}
|
||
|
||
// IncIn 在 broker 收到客户端报文时调用。clientID 为空直接忽略。
|
||
func (s *ClientStats) IncIn(clientID string) {
|
||
if s == nil || clientID == "" {
|
||
return
|
||
}
|
||
s.mu.Lock()
|
||
c, ok := s.all[clientID]
|
||
if !ok {
|
||
c = &clientCounter{}
|
||
s.all[clientID] = c
|
||
}
|
||
c.In++
|
||
s.mu.Unlock()
|
||
}
|
||
|
||
// IncOut 在 broker 向客户端发出报文时调用。
|
||
func (s *ClientStats) IncOut(clientID string) {
|
||
if s == nil || clientID == "" {
|
||
return
|
||
}
|
||
s.mu.Lock()
|
||
c, ok := s.all[clientID]
|
||
if !ok {
|
||
c = &clientCounter{}
|
||
s.all[clientID] = c
|
||
}
|
||
c.Out++
|
||
s.mu.Unlock()
|
||
}
|
||
|
||
// Get 返回指定 clientID 当前的收/发包数量;不存在时返回 0,0。
|
||
func (s *ClientStats) Get(clientID string) (in, out int64) {
|
||
if s == nil || clientID == "" {
|
||
return 0, 0
|
||
}
|
||
s.mu.RLock()
|
||
defer s.mu.RUnlock()
|
||
if c, ok := s.all[clientID]; ok {
|
||
return c.In, c.Out
|
||
}
|
||
return 0, 0
|
||
}
|
||
|
||
// Delete 在客户端断开连接时清除其计数。重新连接同一 clientID 会从 0 重新计起。
|
||
func (s *ClientStats) Delete(clientID string) {
|
||
if s == nil || clientID == "" {
|
||
return
|
||
}
|
||
s.mu.Lock()
|
||
delete(s.all, clientID)
|
||
s.mu.Unlock()
|
||
}
|