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; 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 indexId = Utils.GetMd5(Global.CoreMultipleLoadConfigFileName);
var configPath = Utils.GetConfigPath(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) if (result.Success != true)
{ {
return result; return result;

View file

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

View file

@ -12,6 +12,8 @@ namespace ServiceLib.Models
public Metrics4Ray? metrics { get; set; } public Metrics4Ray? metrics { get; set; }
public Policy4Ray? policy { get; set; } public Policy4Ray? policy { get; set; }
public Stats4Ray? stats { get; set; } public Stats4Ray? stats { get; set; }
public Observatory4Ray? observatory { get; set; }
public BurstObservatory4Ray? burstObservatory { get; set; }
public string? remarks { get; set; } public string? remarks { get; set; }
} }
@ -232,6 +234,46 @@ namespace ServiceLib.Models
public class BalancersStrategy4Ray public class BalancersStrategy4Ray
{ {
public string? type { get; set; } 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 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(); var ret = new RetResult();
@ -164,13 +174,16 @@ namespace ServiceLib.Services.CoreConfig
} }
//add balancers //add balancers
var balancer = new BalancersItem4Ray if (multipleLoad == EMultipleLoad.RoundRobin)
{ {
selector = [Global.ProxyTag], await GenRoundRobinBalancer(v2rayConfig);
strategy = new() { type = "roundRobin" }, }
tag = $"{Global.ProxyTag}-round", else
}; {
v2rayConfig.routing.balancers = [balancer]; await GenLeastPingBalancer(v2rayConfig);
}
var balancer = v2rayConfig.routing.balancers.First();
//add rule //add rule
var rules = v2rayConfig.routing.rules.Where(t => t.outboundTag == Global.ProxyTag).ToList(); var rules = v2rayConfig.routing.rules.Where(t => t.outboundTag == Global.ProxyTag).ToList();
@ -1316,6 +1329,37 @@ namespace ServiceLib.Services.CoreConfig
return 0; 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 #endregion private gen function
} }
} }

View file

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