mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-05 03:49:35 +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:
@@ -1,8 +1,9 @@
|
||||
import { useCallback } from 'react';
|
||||
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 {
|
||||
BarChartOutlined,
|
||||
ClockCircleOutlined,
|
||||
FileTextOutlined,
|
||||
ReloadOutlined,
|
||||
SettingOutlined,
|
||||
@@ -54,6 +55,20 @@ export default function BasicsTab({
|
||||
[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() {
|
||||
modal.confirm({
|
||||
title: t('pages.settings.resetDefaultConfig'),
|
||||
@@ -72,6 +87,7 @@ export default function BasicsTab({
|
||||
const routingStrategy = templateSettings?.routing?.domainStrategy ?? 'AsIs';
|
||||
const log = (templateSettings?.log || {}) as Record<string, unknown>;
|
||||
const policy = (templateSettings?.policy?.system || {}) as Record<string, boolean>;
|
||||
const level0 = (templateSettings?.policy?.levels?.['0'] || {}) as Record<string, unknown>;
|
||||
|
||||
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',
|
||||
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(),
|
||||
policy: z.object({
|
||||
system: z.record(z.string(), z.boolean()).optional(),
|
||||
levels: z.record(z.string(), z.record(z.string(), z.unknown())).optional(),
|
||||
}).loose().optional(),
|
||||
observatory: z.unknown().optional(),
|
||||
burstObservatory: z.unknown().optional(),
|
||||
|
||||
@@ -1201,6 +1201,14 @@
|
||||
"statsOutboundUplinkDesc": "Enables the statistics collection for upstream traffic of all outbound proxies.",
|
||||
"statsOutboundDownlink": "Outbound Download Statistics",
|
||||
"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": {
|
||||
"first": "First",
|
||||
"last": "Last",
|
||||
|
||||
@@ -1201,6 +1201,14 @@
|
||||
"statsOutboundUplinkDesc": "جمعآوری آمار برای ترافیک بالارو (آپلود) تمام پروکسیهای خروجی را فعال میکند.",
|
||||
"statsOutboundDownlink": "آمار دانلود خروجی",
|
||||
"statsOutboundDownlinkDesc": "جمعآوری آمار برای ترافیک پایینرو (دانلود) تمام پروکسیهای خروجی را فعال میکند.",
|
||||
"connectionLimits": "محدودیت اتصال",
|
||||
"connectionLimitsDesc": "سیاستهای سطح اتصال برای کاربرانِ سطح ۰. هر فیلد را خالی بگذارید تا مقدار پیشفرض Xray استفاده شود.",
|
||||
"connIdle": "مهلت بیکاری",
|
||||
"connIdleDesc": "اتصال را پس از این تعداد ثانیه بیکار ماندن میبندد. کمکردن آن، روی سرورهای شلوغ حافظه و file descriptor را زودتر آزاد میکند (پیشفرض Xray: ۳۰۰).",
|
||||
"bufferSize": "اندازهٔ بافر",
|
||||
"bufferSizeDesc": "اندازهٔ بافر داخلی هر اتصال بر حسب کیلوبایت. برای کمکردن مصرف حافظه روی سرورهای کمرم روی ۰ بگذارید (پیشفرض Xray به پلتفرم بستگی دارد).",
|
||||
"bufferSizePlaceholder": "خودکار",
|
||||
"seconds": "ثانیه",
|
||||
"rules": {
|
||||
"first": "اولین",
|
||||
"last": "آخرین",
|
||||
|
||||
Reference in New Issue
Block a user