| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 | package jobimport (	"encoding/json"	"github.com/mhsanaei/3x-ui/v2/logger"	"github.com/mhsanaei/3x-ui/v2/web/service"	"github.com/mhsanaei/3x-ui/v2/xray"	"github.com/valyala/fasthttp")// XrayTrafficJob collects and processes traffic statistics from Xray, updating the database and optionally informing external APIs.type XrayTrafficJob struct {	settingService  service.SettingService	xrayService     service.XrayService	inboundService  service.InboundService	outboundService service.OutboundService}// NewXrayTrafficJob creates a new traffic collection job instance.func NewXrayTrafficJob() *XrayTrafficJob {	return new(XrayTrafficJob)}// Run collects traffic statistics from Xray and updates the database, triggering restart if needed.func (j *XrayTrafficJob) Run() {	if !j.xrayService.IsXrayRunning() {		return	}	traffics, clientTraffics, err := j.xrayService.GetXrayTraffic()	if err != nil {		return	}	err, needRestart0 := j.inboundService.AddTraffic(traffics, clientTraffics)	if err != nil {		logger.Warning("add inbound traffic failed:", err)	}	err, needRestart1 := j.outboundService.AddTraffic(traffics, clientTraffics)	if err != nil {		logger.Warning("add outbound traffic failed:", err)	}	if ExternalTrafficInformEnable, err := j.settingService.GetExternalTrafficInformEnable(); ExternalTrafficInformEnable {		j.informTrafficToExternalAPI(traffics, clientTraffics)	} else if err != nil {		logger.Warning("get ExternalTrafficInformEnable failed:", err)	}	if needRestart0 || needRestart1 {		j.xrayService.SetToNeedRestart()	}}func (j *XrayTrafficJob) informTrafficToExternalAPI(inboundTraffics []*xray.Traffic, clientTraffics []*xray.ClientTraffic) {	informURL, err := j.settingService.GetExternalTrafficInformURI()	if err != nil {		logger.Warning("get ExternalTrafficInformURI failed:", err)		return	}	requestBody, err := json.Marshal(map[string]any{"clientTraffics": clientTraffics, "inboundTraffics": inboundTraffics})	if err != nil {		logger.Warning("parse client/inbound traffic failed:", err)		return	}	request := fasthttp.AcquireRequest()	defer fasthttp.ReleaseRequest(request)	request.Header.SetMethod("POST")	request.Header.SetContentType("application/json; charset=UTF-8")	request.SetBody([]byte(requestBody))	request.SetRequestURI(informURL)	response := fasthttp.AcquireResponse()	defer fasthttp.ReleaseResponse(response)	if err := fasthttp.Do(request, response); err != nil {		logger.Warning("POST ExternalTrafficInformURI failed:", err)	}}
 |