command_status.go 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. //go:build darwin
  2. package libbox
  3. import (
  4. "encoding/binary"
  5. "net"
  6. "runtime"
  7. "time"
  8. E "github.com/sagernet/sing/common/exceptions"
  9. )
  10. type StatusMessage struct {
  11. Memory int64
  12. Goroutines int32
  13. }
  14. func readStatus() StatusMessage {
  15. var memStats runtime.MemStats
  16. runtime.ReadMemStats(&memStats)
  17. var message StatusMessage
  18. message.Memory = int64(memStats.Sys - memStats.HeapReleased)
  19. message.Goroutines = int32(runtime.NumGoroutine())
  20. return message
  21. }
  22. func (s *CommandServer) handleStatusConn(conn net.Conn) error {
  23. var interval int64
  24. err := binary.Read(conn, binary.BigEndian, &interval)
  25. if err != nil {
  26. return E.Cause(err, "read interval")
  27. }
  28. ticker := time.NewTicker(time.Duration(interval))
  29. defer ticker.Stop()
  30. ctx := connKeepAlive(conn)
  31. for {
  32. err = binary.Write(conn, binary.BigEndian, readStatus())
  33. if err != nil {
  34. return err
  35. }
  36. select {
  37. case <-ctx.Done():
  38. return nil
  39. case <-ticker.C:
  40. }
  41. }
  42. }
  43. func (c *CommandClient) handleStatusConn(conn net.Conn) {
  44. for {
  45. var message StatusMessage
  46. err := binary.Read(conn, binary.BigEndian, &message)
  47. if err != nil {
  48. c.handler.Disconnected(err.Error())
  49. return
  50. }
  51. c.handler.WriteStatus(&message)
  52. }
  53. }