mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-05 20:54:14 +00:00
feat(xray): add connIdle and bufferSize policy controls
Expose level-0 connection policies in the panel's Basics tab: idle timeout (connIdle) and per-connection buffer size (bufferSize). Empty fields delete the key so Xray falls back to its own defaults. Adds en-US/fa-IR strings and types policy.levels in the Zod schema.
This commit is contained in:
parent
1a64d7e9de
commit
ceef413dc4
4 changed files with 78 additions and 1 deletions
|
|
@ -1,8 +1,9 @@
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Alert, Button, Input, Modal, Select, Space, Switch, Tabs } from 'antd';
|
import { Alert, Button, Input, InputNumber, Modal, Select, Space, Switch, Tabs } from 'antd';
|
||||||
import {
|
import {
|
||||||
BarChartOutlined,
|
BarChartOutlined,
|
||||||
|
ClockCircleOutlined,
|
||||||
FileTextOutlined,
|
FileTextOutlined,
|
||||||
ReloadOutlined,
|
ReloadOutlined,
|
||||||
SettingOutlined,
|
SettingOutlined,
|
||||||
|
|
@ -54,6 +55,20 @@ export default function BasicsTab({
|
||||||
[setTemplateSettings],
|
[setTemplateSettings],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const setLevel0 = useCallback(
|
||||||
|
(field: string, value: number | null) => mutate((tt) => {
|
||||||
|
if (!tt.policy) tt.policy = {};
|
||||||
|
if (!tt.policy.levels) tt.policy.levels = {};
|
||||||
|
if (!tt.policy.levels['0']) tt.policy.levels['0'] = {};
|
||||||
|
if (value === null || value === undefined) {
|
||||||
|
delete tt.policy.levels['0'][field];
|
||||||
|
} else {
|
||||||
|
tt.policy.levels['0'][field] = value;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
[mutate],
|
||||||
|
);
|
||||||
|
|
||||||
function confirmResetDefault() {
|
function confirmResetDefault() {
|
||||||
modal.confirm({
|
modal.confirm({
|
||||||
title: t('pages.settings.resetDefaultConfig'),
|
title: t('pages.settings.resetDefaultConfig'),
|
||||||
|
|
@ -72,6 +87,7 @@ export default function BasicsTab({
|
||||||
const routingStrategy = templateSettings?.routing?.domainStrategy ?? 'AsIs';
|
const routingStrategy = templateSettings?.routing?.domainStrategy ?? 'AsIs';
|
||||||
const log = (templateSettings?.log || {}) as Record<string, unknown>;
|
const log = (templateSettings?.log || {}) as Record<string, unknown>;
|
||||||
const policy = (templateSettings?.policy?.system || {}) as Record<string, boolean>;
|
const policy = (templateSettings?.policy?.system || {}) as Record<string, boolean>;
|
||||||
|
const level0 = (templateSettings?.policy?.levels?.['0'] || {}) as Record<string, unknown>;
|
||||||
|
|
||||||
const items = [
|
const items = [
|
||||||
{
|
{
|
||||||
|
|
@ -168,6 +184,50 @@ export default function BasicsTab({
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: 'connection',
|
||||||
|
label: catTabLabel(<ClockCircleOutlined />, t('pages.xray.connectionLimits'), isMobile),
|
||||||
|
children: (
|
||||||
|
<>
|
||||||
|
<Alert
|
||||||
|
type="warning"
|
||||||
|
showIcon
|
||||||
|
className="mb-12 hint-alert"
|
||||||
|
title={t('pages.xray.connectionLimitsDesc')}
|
||||||
|
/>
|
||||||
|
<SettingListItem
|
||||||
|
title={t('pages.xray.connIdle')}
|
||||||
|
description={t('pages.xray.connIdleDesc')}
|
||||||
|
paddings="small"
|
||||||
|
control={
|
||||||
|
<InputNumber
|
||||||
|
value={typeof level0.connIdle === 'number' ? level0.connIdle : undefined}
|
||||||
|
min={0}
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
placeholder="300"
|
||||||
|
addonAfter={t('pages.xray.seconds')}
|
||||||
|
onChange={(v) => setLevel0('connIdle', v as number | null)}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<SettingListItem
|
||||||
|
title={t('pages.xray.bufferSize')}
|
||||||
|
description={t('pages.xray.bufferSizeDesc')}
|
||||||
|
paddings="small"
|
||||||
|
control={
|
||||||
|
<InputNumber
|
||||||
|
value={typeof level0.bufferSize === 'number' ? level0.bufferSize : undefined}
|
||||||
|
min={0}
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
placeholder={t('pages.xray.bufferSizePlaceholder')}
|
||||||
|
addonAfter="KB"
|
||||||
|
onChange={(v) => setLevel0('bufferSize', v as number | null)}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: '3',
|
key: '3',
|
||||||
label: catTabLabel(<FileTextOutlined />, t('pages.xray.logConfigs'), isMobile),
|
label: catTabLabel(<FileTextOutlined />, t('pages.xray.logConfigs'), isMobile),
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ export const XraySettingsValueSchema = z.object({
|
||||||
log: z.record(z.string(), z.unknown()).optional(),
|
log: z.record(z.string(), z.unknown()).optional(),
|
||||||
policy: z.object({
|
policy: z.object({
|
||||||
system: z.record(z.string(), z.boolean()).optional(),
|
system: z.record(z.string(), z.boolean()).optional(),
|
||||||
|
levels: z.record(z.string(), z.record(z.string(), z.unknown())).optional(),
|
||||||
}).loose().optional(),
|
}).loose().optional(),
|
||||||
observatory: z.unknown().optional(),
|
observatory: z.unknown().optional(),
|
||||||
burstObservatory: z.unknown().optional(),
|
burstObservatory: z.unknown().optional(),
|
||||||
|
|
|
||||||
|
|
@ -1201,6 +1201,14 @@
|
||||||
"statsOutboundUplinkDesc": "Enables the statistics collection for upstream traffic of all outbound proxies.",
|
"statsOutboundUplinkDesc": "Enables the statistics collection for upstream traffic of all outbound proxies.",
|
||||||
"statsOutboundDownlink": "Outbound Download Statistics",
|
"statsOutboundDownlink": "Outbound Download Statistics",
|
||||||
"statsOutboundDownlinkDesc": "Enables the statistics collection for downstream traffic of all outbound proxies.",
|
"statsOutboundDownlinkDesc": "Enables the statistics collection for downstream traffic of all outbound proxies.",
|
||||||
|
"connectionLimits": "Connection Limits",
|
||||||
|
"connectionLimitsDesc": "Connection-level policies for user level 0. Leave a field empty to use Xray's default.",
|
||||||
|
"connIdle": "Idle Timeout",
|
||||||
|
"connIdleDesc": "Closes a connection after it stays idle for this many seconds. Lowering it frees memory and file descriptors faster on busy servers (Xray default: 300).",
|
||||||
|
"bufferSize": "Buffer Size",
|
||||||
|
"bufferSizeDesc": "Per-connection internal buffer size in KB. Set to 0 to minimize memory usage on low-RAM servers (Xray default depends on the platform).",
|
||||||
|
"bufferSizePlaceholder": "auto",
|
||||||
|
"seconds": "seconds",
|
||||||
"rules": {
|
"rules": {
|
||||||
"first": "First",
|
"first": "First",
|
||||||
"last": "Last",
|
"last": "Last",
|
||||||
|
|
|
||||||
|
|
@ -1201,6 +1201,14 @@
|
||||||
"statsOutboundUplinkDesc": "جمعآوری آمار برای ترافیک بالارو (آپلود) تمام پروکسیهای خروجی را فعال میکند.",
|
"statsOutboundUplinkDesc": "جمعآوری آمار برای ترافیک بالارو (آپلود) تمام پروکسیهای خروجی را فعال میکند.",
|
||||||
"statsOutboundDownlink": "آمار دانلود خروجی",
|
"statsOutboundDownlink": "آمار دانلود خروجی",
|
||||||
"statsOutboundDownlinkDesc": "جمعآوری آمار برای ترافیک پایینرو (دانلود) تمام پروکسیهای خروجی را فعال میکند.",
|
"statsOutboundDownlinkDesc": "جمعآوری آمار برای ترافیک پایینرو (دانلود) تمام پروکسیهای خروجی را فعال میکند.",
|
||||||
|
"connectionLimits": "محدودیت اتصال",
|
||||||
|
"connectionLimitsDesc": "سیاستهای سطح اتصال برای کاربرانِ سطح ۰. هر فیلد را خالی بگذارید تا مقدار پیشفرض Xray استفاده شود.",
|
||||||
|
"connIdle": "مهلت بیکاری",
|
||||||
|
"connIdleDesc": "اتصال را پس از این تعداد ثانیه بیکار ماندن میبندد. کمکردن آن، روی سرورهای شلوغ حافظه و file descriptor را زودتر آزاد میکند (پیشفرض Xray: ۳۰۰).",
|
||||||
|
"bufferSize": "اندازهٔ بافر",
|
||||||
|
"bufferSizeDesc": "اندازهٔ بافر داخلی هر اتصال بر حسب کیلوبایت. برای کمکردن مصرف حافظه روی سرورهای کمرم روی ۰ بگذارید (پیشفرض Xray به پلتفرم بستگی دارد).",
|
||||||
|
"bufferSizePlaceholder": "خودکار",
|
||||||
|
"seconds": "ثانیه",
|
||||||
"rules": {
|
"rules": {
|
||||||
"first": "اولین",
|
"first": "اولین",
|
||||||
"last": "آخرین",
|
"last": "آخرین",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue