add xray core leastPing support

This commit is contained in:
DHR60 2025-03-28 21:08:51 +08:00
parent 6ad0762731
commit dc3200f0a6
6 changed files with 146 additions and 18 deletions

View file

@ -0,0 +1,10 @@
namespace ServiceLib.Enums
{
public enum EMultipleLoad
{
Random,
RoundRobin,
LeastPing,
LeastLoad
}
}

View file

@ -1005,12 +1005,33 @@ namespace ServiceLib.Handler
return 0;
}
public static async Task<RetResult> AddCustomServer4Multiple(Config config, List<ProfileItem> selecteds, ECoreType coreType)
public static async Task<RetResult> AddCustomServer4Multiple(Config config, List<ProfileItem> selecteds, EMultipleLoad multipleLoad)
{
var indexId = Utils.GetMd5(Global.CoreMultipleLoadConfigFileName);
var configPath = Utils.GetConfigPath(Global.CoreMultipleLoadConfigFileName);
var result = await CoreConfigHandler.GenerateClientMultipleLoadConfig(config, configPath, selecteds, coreType);
var coreType = AppHandler.Instance.Config.CoreTypeItem?.FirstOrDefault(it => it.ConfigType == EConfigType.Custom)?.CoreType ?? ECoreType.Xray;
if (multipleLoad == EMultipleLoad.LeastPing && coreType == ECoreType.Xray)
{
var support = selecteds.All(it => it.ConfigType is
EConfigType.VMess or
EConfigType.VLESS or
EConfigType.Trojan or
EConfigType.Shadowsocks or
EConfigType.SOCKS or
EConfigType.HTTP or
EConfigType.WireGuard);
if (!support)
{
coreType = ECoreType.sing_box;
}
}
else if (multipleLoad == EMultipleLoad.RoundRobin)
{
coreType = ECoreType.Xray;
}
var result = await CoreConfigHandler.GenerateClientMultipleLoadConfig(config, configPath, selecteds, coreType, multipleLoad);
if (result.Success != true)
{
return result;

View file

@ -1,3 +1,7 @@
using DynamicData;
using ServiceLib.Enums;
using ServiceLib.Models;
namespace ServiceLib.Handler
{
/// <summary>
@ -133,16 +137,23 @@ namespace ServiceLib.Handler
return result;
}
public static async Task<RetResult> GenerateClientMultipleLoadConfig(Config config, string fileName, List<ProfileItem> selecteds, ECoreType coreType)
public static async Task<RetResult> GenerateClientMultipleLoadConfig(Config config, string fileName, List<ProfileItem> selecteds, ECoreType coreType, EMultipleLoad multipleLoad)
{
var result = new RetResult();
if (multipleLoad == EMultipleLoad.RoundRobin)
{
result = await new CoreConfigV2rayService(config).GenerateClientMultipleRoundRobinConfig(selecteds);
}
else
{
if (coreType == ECoreType.sing_box)
{
result = await new CoreConfigSingboxService(config).GenerateClientMultipleLoadConfig(selecteds);
}
else if (coreType == ECoreType.Xray)
{
result = await new CoreConfigV2rayService(config).GenerateClientMultipleLoadConfig(selecteds);
result = await new CoreConfigV2rayService(config).GenerateClientMultipleLeastPingConfig(selecteds);
}
}
if (result.Success != true)

View file

@ -12,6 +12,8 @@ namespace ServiceLib.Models
public Metrics4Ray? metrics { get; set; }
public Policy4Ray? policy { get; set; }
public Stats4Ray? stats { get; set; }
public Observatory4Ray? observatory { get; set; }
public BurstObservatory4Ray? burstObservatory { get; set; }
public string? remarks { get; set; }
}
@ -232,6 +234,46 @@ namespace ServiceLib.Models
public class BalancersStrategy4Ray
{
public string? type { get; set; }
public BalancersStrategySettings4Ray? settings { get; set; }
}
public class BalancersStrategySettings4Ray
{
public int? expected { get; set; }
public string? maxRTT { get; set; }
public float? tolerance { get; set; }
public List<string>? baselines { get; set; }
public List<BalancersStrategySettingsCosts4Ray>? costs { get; set; }
}
public class BalancersStrategySettingsCosts4Ray
{
public bool? regexp { get; set; }
public string? match { get; set; }
public float? value { get; set; }
}
public class Observatory4Ray
{
public List<string>? subjectSelector { get; set; }
public string? probeUrl { get; set; }
public string? probeInterval { get; set; }
public bool? enableConcurrency { get; set; }
}
public class BurstObservatory4Ray
{
public List<string>? subjectSelector { get; set; }
public BurstObservatoryPingConfig4Ray? pingConfig { get; set; }
}
public class BurstObservatoryPingConfig4Ray
{
public string? destination { get; set; }
public string? connectivity { get; set; }
public string? interval { get; set; }
public int? sampling { get; set; }
public string? timeout { get; set; }
}
public class StreamSettings4Ray

View file

@ -77,7 +77,17 @@ namespace ServiceLib.Services.CoreConfig
}
}
public async Task<RetResult> GenerateClientMultipleLoadConfig(List<ProfileItem> selecteds)
public async Task<RetResult> GenerateClientMultipleRoundRobinConfig(List<ProfileItem> selecteds)
{
return await GenerateClientMultipleLoadConfig(selecteds, EMultipleLoad.RoundRobin);
}
public async Task<RetResult> GenerateClientMultipleLeastPingConfig(List<ProfileItem> selecteds)
{
return await GenerateClientMultipleLoadConfig(selecteds, EMultipleLoad.LeastPing);
}
public async Task<RetResult> GenerateClientMultipleLoadConfig(List<ProfileItem> selecteds, EMultipleLoad multipleLoad)
{
var ret = new RetResult();
@ -164,13 +174,16 @@ namespace ServiceLib.Services.CoreConfig
}
//add balancers
var balancer = new BalancersItem4Ray
if (multipleLoad == EMultipleLoad.RoundRobin)
{
selector = [Global.ProxyTag],
strategy = new() { type = "roundRobin" },
tag = $"{Global.ProxyTag}-round",
};
v2rayConfig.routing.balancers = [balancer];
await GenRoundRobinBalancer(v2rayConfig);
}
else
{
await GenLeastPingBalancer(v2rayConfig);
}
var balancer = v2rayConfig.routing.balancers.First();
//add rule
var rules = v2rayConfig.routing.rules.Where(t => t.outboundTag == Global.ProxyTag).ToList();
@ -1316,6 +1329,37 @@ namespace ServiceLib.Services.CoreConfig
return 0;
}
private async Task<int> GenRoundRobinBalancer(V2rayConfig v2rayConfig)
{
var balancer = new BalancersItem4Ray
{
selector = [Global.ProxyTag],
strategy = new() { type = "roundRobin" },
tag = $"{Global.ProxyTag}-round",
};
v2rayConfig.routing.balancers = [balancer];
return await Task.FromResult(0);
}
private async Task<int> GenLeastPingBalancer(V2rayConfig v2rayConfig)
{
var observatory = new Observatory4Ray
{
subjectSelector = [Global.ProxyTag],
probeUrl = AppHandler.Instance.Config.SpeedTestItem.SpeedPingTestUrl,
probeInterval = "3m"
};
var balancer = new BalancersItem4Ray
{
selector = [Global.ProxyTag],
strategy = new() { type = "leastPing" },
tag = $"{Global.ProxyTag}-round",
};
v2rayConfig.routing.balancers = [balancer];
v2rayConfig.observatory = observatory;
return await Task.FromResult(0);
}
#endregion private gen function
}
}

View file

@ -152,11 +152,11 @@ namespace ServiceLib.ViewModels
}, canEditRemove);
SetDefaultMultipleServerCmd = ReactiveCommand.CreateFromTask(async () =>
{
await SetDefaultMultipleServer(ECoreType.sing_box);
await SetDefaultMultipleServer(EMultipleLoad.LeastPing);
}, canEditRemove);
SetDefaultLoadBalanceServerCmd = ReactiveCommand.CreateFromTask(async () =>
{
await SetDefaultMultipleServer(ECoreType.Xray);
await SetDefaultMultipleServer(EMultipleLoad.RoundRobin);
}, canEditRemove);
//servers move
@ -621,7 +621,7 @@ namespace ServiceLib.ViewModels
await _updateView?.Invoke(EViewAction.ShareServer, url);
}
private async Task SetDefaultMultipleServer(ECoreType coreType)
private async Task SetDefaultMultipleServer(EMultipleLoad multipleLoad)
{
var lstSelected = await GetProfileItems(true);
if (lstSelected == null)
@ -629,7 +629,7 @@ namespace ServiceLib.ViewModels
return;
}
var ret = await ConfigHandler.AddCustomServer4Multiple(_config, lstSelected, coreType);
var ret = await ConfigHandler.AddCustomServer4Multiple(_config, lstSelected, multipleLoad);
if (ret.Success != true)
{
NoticeHandler.Instance.Enqueue(ResUI.OperationFailed);