xray_traffic_job.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. package job
  2. import (
  3. "encoding/json"
  4. "github.com/mhsanaei/3x-ui/v2/logger"
  5. "github.com/mhsanaei/3x-ui/v2/web/service"
  6. "github.com/mhsanaei/3x-ui/v2/xray"
  7. "github.com/valyala/fasthttp"
  8. )
  9. // XrayTrafficJob collects and processes traffic statistics from Xray, updating the database and optionally informing external APIs.
  10. type XrayTrafficJob struct {
  11. settingService service.SettingService
  12. xrayService service.XrayService
  13. inboundService service.InboundService
  14. outboundService service.OutboundService
  15. }
  16. // NewXrayTrafficJob creates a new traffic collection job instance.
  17. func NewXrayTrafficJob() *XrayTrafficJob {
  18. return new(XrayTrafficJob)
  19. }
  20. // Run collects traffic statistics from Xray and updates the database, triggering restart if needed.
  21. func (j *XrayTrafficJob) Run() {
  22. if !j.xrayService.IsXrayRunning() {
  23. return
  24. }
  25. traffics, clientTraffics, err := j.xrayService.GetXrayTraffic()
  26. if err != nil {
  27. return
  28. }
  29. err, needRestart0 := j.inboundService.AddTraffic(traffics, clientTraffics)
  30. if err != nil {
  31. logger.Warning("add inbound traffic failed:", err)
  32. }
  33. err, needRestart1 := j.outboundService.AddTraffic(traffics, clientTraffics)
  34. if err != nil {
  35. logger.Warning("add outbound traffic failed:", err)
  36. }
  37. if ExternalTrafficInformEnable, err := j.settingService.GetExternalTrafficInformEnable(); ExternalTrafficInformEnable {
  38. j.informTrafficToExternalAPI(traffics, clientTraffics)
  39. } else if err != nil {
  40. logger.Warning("get ExternalTrafficInformEnable failed:", err)
  41. }
  42. if needRestart0 || needRestart1 {
  43. j.xrayService.SetToNeedRestart()
  44. }
  45. }
  46. func (j *XrayTrafficJob) informTrafficToExternalAPI(inboundTraffics []*xray.Traffic, clientTraffics []*xray.ClientTraffic) {
  47. informURL, err := j.settingService.GetExternalTrafficInformURI()
  48. if err != nil {
  49. logger.Warning("get ExternalTrafficInformURI failed:", err)
  50. return
  51. }
  52. requestBody, err := json.Marshal(map[string]any{"clientTraffics": clientTraffics, "inboundTraffics": inboundTraffics})
  53. if err != nil {
  54. logger.Warning("parse client/inbound traffic failed:", err)
  55. return
  56. }
  57. request := fasthttp.AcquireRequest()
  58. defer fasthttp.ReleaseRequest(request)
  59. request.Header.SetMethod("POST")
  60. request.Header.SetContentType("application/json; charset=UTF-8")
  61. request.SetBody([]byte(requestBody))
  62. request.SetRequestURI(informURL)
  63. response := fasthttp.AcquireResponse()
  64. defer fasthttp.ReleaseResponse(response)
  65. if err := fasthttp.Do(request, response); err != nil {
  66. logger.Warning("POST ExternalTrafficInformURI failed:", err)
  67. }
  68. }