package libbox import ( "encoding/binary" "net" "runtime" "time" "github.com/sagernet/sing-box/common/dialer/conntrack" E "github.com/sagernet/sing/common/exceptions" ) type StatusMessage struct { Memory int64 Goroutines int32 Connections int32 } func readStatus() StatusMessage { var memStats runtime.MemStats runtime.ReadMemStats(&memStats) var message StatusMessage message.Memory = int64(memStats.StackInuse + memStats.HeapInuse + memStats.HeapIdle - memStats.HeapReleased) message.Goroutines = int32(runtime.NumGoroutine()) message.Connections = int32(conntrack.Count()) return message } func (s *CommandServer) handleStatusConn(conn net.Conn) error { var interval int64 err := binary.Read(conn, binary.BigEndian, &interval) if err != nil { return E.Cause(err, "read interval") } ticker := time.NewTicker(time.Duration(interval)) defer ticker.Stop() ctx := connKeepAlive(conn) for { err = binary.Write(conn, binary.BigEndian, readStatus()) if err != nil { return err } select { case <-ctx.Done(): return nil case <-ticker.C: } } } func (c *CommandClient) handleStatusConn(conn net.Conn) { for { var message StatusMessage err := binary.Read(conn, binary.BigEndian, &message) if err != nil { c.handler.Disconnected(err.Error()) return } c.handler.WriteStatus(&message) } }