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>
This commit is contained in:
lolka1333
2026-01-03 05:26:00 +01:00
committed by GitHub
parent b747730211
commit 313a2acbf6
40 changed files with 1329 additions and 109 deletions

View File

@@ -1102,6 +1102,20 @@
});
fileInput.click();
},
startPolling() {
// Fallback polling mechanism
const pollInterval = setInterval(async () => {
if (window.wsClient && window.wsClient.isConnected) {
clearInterval(pollInterval);
return;
}
try {
await this.getStatus();
} catch (e) {
console.error(e);
}
}, 2000);
},
},
async mounted() {
if (window.location.protocol !== "https:") {
@@ -1113,13 +1127,57 @@
this.ipLimitEnable = msg.obj.ipLimitEnable;
}
while (true) {
try {
await this.getStatus();
} catch (e) {
console.error(e);
}
await PromiseUtil.sleep(2000);
// Initial status fetch
await this.getStatus();
// Setup WebSocket for real-time updates
if (window.wsClient) {
window.wsClient.connect();
// Listen for status updates
window.wsClient.on('status', (payload) => {
this.setStatus(payload);
});
// Listen for Xray state changes
window.wsClient.on('xray_state', (payload) => {
if (this.status && this.status.xray) {
this.status.xray.state = payload.state;
this.status.xray.errorMsg = payload.errorMsg || '';
switch (payload.state) {
case 'running':
this.status.xray.color = "green";
this.status.xray.stateMsg = '{{ i18n "pages.index.xrayStatusRunning" }}';
break;
case 'stop':
this.status.xray.color = "orange";
this.status.xray.stateMsg = '{{ i18n "pages.index.xrayStatusStop" }}';
break;
case 'error':
this.status.xray.color = "red";
this.status.xray.stateMsg = '{{ i18n "pages.index.xrayStatusError" }}';
break;
}
}
});
// Notifications disabled - white notifications are not needed
// Fallback to polling if WebSocket fails
window.wsClient.on('error', () => {
console.warn('WebSocket connection failed, falling back to polling');
this.startPolling();
});
window.wsClient.on('disconnected', () => {
if (window.wsClient.reconnectAttempts >= window.wsClient.maxReconnectAttempts) {
console.warn('WebSocket reconnection failed, falling back to polling');
this.startPolling();
}
});
} else {
// Fallback to polling if WebSocket is not available
this.startPolling();
}
},
});