Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/MHSanaei/3x-ui.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/web/job
diff options
context:
space:
mode:
authorlolka1333 <xtrafcyz@gmail.com>2026-01-03 07:26:00 +0300
committerGitHub <noreply@github.com>2026-01-03 07:26:00 +0300
commit313a2acbf66125feb4b145a5636351ed03e666da (patch)
tree6be6fac0ced2d0dce60ba55e2feaa83c257ed720 /web/job
parentb7477302112b43a2ae037b63994c59e85f9c0687 (diff)
feat: Add WebSocket support for real-time updates and enhance VLESS settings (#3605)
* feat: add support for trusted X-Forwarded-For and testseed parameters in VLESS settings * chore: update Xray Core version to 25.12.8 in release workflow * chore: update Xray Core version to 25.12.8 in Docker initialization script * chore: bump version to 2.8.6 and add watcher for security changes in inbound modal * refactor: remove default and random seed buttons from outbound form * refactor: update VLESS form to rename 'Test Seed' to 'Vision Seed' and change button functionality for seed generation * refactor: enhance TLS settings form layout with improved button styling and spacing * feat: integrate WebSocket support for real-time updates on inbounds and Xray service status * chore: downgrade version to 2.8.5 * refactor: translate comments to English * fix: ensure testseed is initialized correctly for VLESS protocol and improve client handling in inbound modal * refactor: simplify VLESS divider condition by removing unnecessary flow checks * fix: add fallback date formatting for cases when IntlUtil is not available * refactor: simplify WebSocket message handling by removing batching and ensuring individual message delivery * refactor: disable WebSocket notifications in inbound and index HTML files * refactor: enhance VLESS testseed initialization and button functionality in inbound modal * fix: * refactor: ensure proper WebSocket URL construction by normalizing basePath * fix: * fix: * fix: * refactor: update testseed methods for improved reactivity and binding in VLESS form * logger info to debug --------- Co-authored-by: lolka1333 <test123@gmail.com>
Diffstat (limited to 'web/job')
-rw-r--r--web/job/ldap_sync_job.go60
-rw-r--r--web/job/xray_traffic_job.go18
2 files changed, 18 insertions, 60 deletions
diff --git a/web/job/ldap_sync_job.go b/web/job/ldap_sync_job.go
index 6642bbcf..a947eb73 100644
--- a/web/job/ldap_sync_job.go
+++ b/web/job/ldap_sync_job.go
@@ -322,66 +322,6 @@ func (j *LdapSyncJob) clientsToJSON(clients []model.Client) string {
return b.String()
}
-// ensureClientExists adds client with defaults to inbound tag if not present
-func (j *LdapSyncJob) ensureClientExists(inboundTag string, email string, defGB int, defExpiryDays int, defLimitIP int) {
- inbounds, err := j.inboundService.GetAllInbounds()
- if err != nil {
- logger.Warning("ensureClientExists: get inbounds failed:", err)
- return
- }
- var target *model.Inbound
- for _, ib := range inbounds {
- if ib.Tag == inboundTag {
- target = ib
- break
- }
- }
- if target == nil {
- logger.Debugf("ensureClientExists: inbound tag %s not found", inboundTag)
- return
- }
- // check if email already exists in this inbound
- clients, err := j.inboundService.GetClients(target)
- if err == nil {
- for _, c := range clients {
- if c.Email == email {
- return
- }
- }
- }
-
- // build new client according to protocol
- newClient := model.Client{
- Email: email,
- Enable: true,
- LimitIP: defLimitIP,
- TotalGB: int64(defGB),
- }
- if defExpiryDays > 0 {
- newClient.ExpiryTime = time.Now().Add(time.Duration(defExpiryDays) * 24 * time.Hour).UnixMilli()
- }
-
- switch target.Protocol {
- case model.Trojan:
- newClient.Password = uuid.NewString()
- case model.Shadowsocks:
- newClient.Password = uuid.NewString()
- default: // VMESS/VLESS and others using ID
- newClient.ID = uuid.NewString()
- }
-
- // prepare inbound payload with only the new client
- payload := &model.Inbound{Id: target.Id}
- payload.Settings = `{"clients":[` + j.clientToJSON(newClient) + `]}`
-
- if _, err := j.inboundService.AddInboundClient(payload); err != nil {
- logger.Warning("ensureClientExists: add client failed:", err)
- } else {
- j.xrayService.SetToNeedRestart()
- logger.Infof("LDAP auto-create: %s in %s", email, inboundTag)
- }
-}
-
// clientToJSON serializes minimal client fields to JSON object string without extra deps
func (j *LdapSyncJob) clientToJSON(c model.Client) string {
// construct minimal JSON manually to avoid importing json for simple case
diff --git a/web/job/xray_traffic_job.go b/web/job/xray_traffic_job.go
index a9affb4b..2f331cd6 100644
--- a/web/job/xray_traffic_job.go
+++ b/web/job/xray_traffic_job.go
@@ -5,6 +5,7 @@ import (
"github.com/mhsanaei/3x-ui/v2/logger"
"github.com/mhsanaei/3x-ui/v2/web/service"
+ "github.com/mhsanaei/3x-ui/v2/web/websocket"
"github.com/mhsanaei/3x-ui/v2/xray"
"github.com/valyala/fasthttp"
@@ -48,6 +49,23 @@ func (j *XrayTrafficJob) Run() {
if needRestart0 || needRestart1 {
j.xrayService.SetToNeedRestart()
}
+
+ // Get online clients and last online map for real-time status updates
+ onlineClients := j.inboundService.GetOnlineClients()
+ lastOnlineMap, err := j.inboundService.GetClientsLastOnline()
+ if err != nil {
+ logger.Warning("get clients last online failed:", err)
+ lastOnlineMap = make(map[string]int64)
+ }
+
+ // Broadcast traffic update via WebSocket
+ trafficUpdate := map[string]interface{}{
+ "traffics": traffics,
+ "clientTraffics": clientTraffics,
+ "onlineClients": onlineClients,
+ "lastOnlineMap": lastOnlineMap,
+ }
+ websocket.BroadcastTraffic(trafficUpdate)
}
func (j *XrayTrafficJob) informTrafficToExternalAPI(inboundTraffics []*xray.Traffic, clientTraffics []*xray.ClientTraffic) {