github.com/sagernet/sing-box@v1.9.0-rc.20/experimental/libbox/command_status.go (about) 1 package libbox 2 3 import ( 4 "encoding/binary" 5 "net" 6 "runtime" 7 "time" 8 9 "github.com/sagernet/sing-box/common/conntrack" 10 "github.com/sagernet/sing-box/experimental/clashapi" 11 E "github.com/sagernet/sing/common/exceptions" 12 "github.com/sagernet/sing/common/memory" 13 ) 14 15 type StatusMessage struct { 16 Memory int64 17 Goroutines int32 18 ConnectionsIn int32 19 ConnectionsOut int32 20 TrafficAvailable bool 21 Uplink int64 22 Downlink int64 23 UplinkTotal int64 24 DownlinkTotal int64 25 } 26 27 func (s *CommandServer) readStatus() StatusMessage { 28 var message StatusMessage 29 message.Memory = int64(memory.Inuse()) 30 message.Goroutines = int32(runtime.NumGoroutine()) 31 message.ConnectionsOut = int32(conntrack.Count()) 32 33 if s.service != nil { 34 if clashServer := s.service.instance.Router().ClashServer(); clashServer != nil { 35 message.TrafficAvailable = true 36 trafficManager := clashServer.(*clashapi.Server).TrafficManager() 37 message.Uplink, message.Downlink = trafficManager.Now() 38 message.UplinkTotal, message.DownlinkTotal = trafficManager.Total() 39 message.ConnectionsIn = int32(trafficManager.Connections()) 40 } 41 } 42 43 return message 44 } 45 46 func (s *CommandServer) handleStatusConn(conn net.Conn) error { 47 var interval int64 48 err := binary.Read(conn, binary.BigEndian, &interval) 49 if err != nil { 50 return E.Cause(err, "read interval") 51 } 52 ticker := time.NewTicker(time.Duration(interval)) 53 defer ticker.Stop() 54 ctx := connKeepAlive(conn) 55 for { 56 err = binary.Write(conn, binary.BigEndian, s.readStatus()) 57 if err != nil { 58 return err 59 } 60 select { 61 case <-ctx.Done(): 62 return ctx.Err() 63 case <-ticker.C: 64 } 65 } 66 } 67 68 func (c *CommandClient) handleStatusConn(conn net.Conn) { 69 for { 70 var message StatusMessage 71 err := binary.Read(conn, binary.BigEndian, &message) 72 if err != nil { 73 c.handler.Disconnected(err.Error()) 74 return 75 } 76 c.handler.WriteStatus(&message) 77 } 78 }