mtproto_job.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package job
  2. import (
  3. "github.com/mhsanaei/3x-ui/v3/internal/logger"
  4. "github.com/mhsanaei/3x-ui/v3/internal/mtproto"
  5. "github.com/mhsanaei/3x-ui/v3/internal/web/service"
  6. "github.com/mhsanaei/3x-ui/v3/internal/xray"
  7. )
  8. // MtprotoJob reconciles the running mtg sidecar processes against the enabled
  9. // mtproto inbounds in the database, restarts any that crashed, and folds the
  10. // per-client traffic scraped from each mtg /stats endpoint into the usual client
  11. // and inbound traffic accounting.
  12. type MtprotoJob struct {
  13. inboundService service.InboundService
  14. }
  15. // NewMtprotoJob creates a new mtproto reconcile/traffic job instance.
  16. func NewMtprotoJob() *MtprotoJob {
  17. return new(MtprotoJob)
  18. }
  19. // Run reconciles desired mtproto inbounds with running mtg processes and records
  20. // per-client traffic deltas and online status.
  21. func (j *MtprotoJob) Run() {
  22. desired, err := j.inboundService.DesiredMtprotoInstances()
  23. if err != nil {
  24. logger.Warning("mtproto job: get desired instances failed:", err)
  25. return
  26. }
  27. routedTags := make(map[string]bool)
  28. activeTags := make([]string, 0, len(desired))
  29. for _, inst := range desired {
  30. activeTags = append(activeTags, inst.Tag)
  31. if inst.RouteThroughXray {
  32. routedTags[inst.Tag] = true
  33. }
  34. }
  35. mgr := mtproto.GetManager()
  36. mgr.Reconcile(desired)
  37. deltas, onlineEmails := mgr.CollectTraffic()
  38. // A routed inbound's total is already metered through the Xray bridge by
  39. // xray_traffic_job, so only non-routed inbounds are rolled up here; per-client
  40. // deltas are always kept, since the bridge cannot tell mtproto users apart.
  41. clientTraffics := make([]*xray.ClientTraffic, 0, len(deltas))
  42. inboundUp := make(map[string]int64)
  43. inboundDown := make(map[string]int64)
  44. for _, d := range deltas {
  45. clientTraffics = append(clientTraffics, &xray.ClientTraffic{
  46. Email: d.Email,
  47. Up: d.Up,
  48. Down: d.Down,
  49. })
  50. if !routedTags[d.Tag] {
  51. inboundUp[d.Tag] += d.Up
  52. inboundDown[d.Tag] += d.Down
  53. }
  54. }
  55. traffics := make([]*xray.Traffic, 0, len(inboundUp))
  56. for tag, up := range inboundUp {
  57. traffics = append(traffics, &xray.Traffic{
  58. IsInbound: true,
  59. Tag: tag,
  60. Up: up,
  61. Down: inboundDown[tag],
  62. })
  63. }
  64. if len(traffics) > 0 || len(clientTraffics) > 0 {
  65. if _, _, err := j.inboundService.AddTraffic(traffics, clientTraffics); err != nil {
  66. logger.Warning("mtproto job: add traffic failed:", err)
  67. }
  68. }
  69. j.inboundService.RefreshLocalOnlineClients(onlineEmails, activeTags)
  70. }