| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 | 
							- package libbox
 
- import (
 
- 	"encoding/binary"
 
- 	"net"
 
- 	"runtime"
 
- 	"time"
 
- 	"github.com/sagernet/sing-box/common/conntrack"
 
- 	"github.com/sagernet/sing-box/experimental/clashapi"
 
- 	E "github.com/sagernet/sing/common/exceptions"
 
- 	"github.com/sagernet/sing/common/memory"
 
- )
 
- type StatusMessage struct {
 
- 	Memory           int64
 
- 	Goroutines       int32
 
- 	ConnectionsIn    int32
 
- 	ConnectionsOut   int32
 
- 	TrafficAvailable bool
 
- 	Uplink           int64
 
- 	Downlink         int64
 
- 	UplinkTotal      int64
 
- 	DownlinkTotal    int64
 
- }
 
- func (s *CommandServer) readStatus() StatusMessage {
 
- 	var message StatusMessage
 
- 	message.Memory = int64(memory.Inuse())
 
- 	message.Goroutines = int32(runtime.NumGoroutine())
 
- 	message.ConnectionsOut = int32(conntrack.Count())
 
- 	if s.service != nil {
 
- 		message.TrafficAvailable = true
 
- 		trafficManager := s.service.clashServer.(*clashapi.Server).TrafficManager()
 
- 		message.UplinkTotal, message.DownlinkTotal = trafficManager.Total()
 
- 		message.ConnectionsIn = int32(trafficManager.ConnectionsLen())
 
- 	}
 
- 	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)
 
- 	status := s.readStatus()
 
- 	uploadTotal := status.UplinkTotal
 
- 	downloadTotal := status.DownlinkTotal
 
- 	for {
 
- 		err = binary.Write(conn, binary.BigEndian, status)
 
- 		if err != nil {
 
- 			return err
 
- 		}
 
- 		select {
 
- 		case <-ctx.Done():
 
- 			return ctx.Err()
 
- 		case <-ticker.C:
 
- 		}
 
- 		status = s.readStatus()
 
- 		upload := status.UplinkTotal - uploadTotal
 
- 		download := status.DownlinkTotal - downloadTotal
 
- 		uploadTotal = status.UplinkTotal
 
- 		downloadTotal = status.DownlinkTotal
 
- 		status.Uplink = upload
 
- 		status.Downlink = download
 
- 	}
 
- }
 
- 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)
 
- 	}
 
- }
 
 
  |