Compare commits

..

No commits in common. "b3df0d0776bf21bca1fa938f69ee3e335e3cc8d7" and "ff5505b0009e0129e34b0ba491edb68c56be5dad" have entirely different histories.

6 changed files with 89 additions and 93 deletions

View file

@ -1,4 +1,4 @@
namespace ServiceLib.Enums namespace ServiceLib.Enums
{ {
public enum EMsgCommand public enum EMsgCommand
{ {
@ -6,6 +6,7 @@ namespace ServiceLib.Enums
SendMsgView, SendMsgView,
SendSnackMsg, SendSnackMsg,
RefreshProfiles, RefreshProfiles,
StopSpeedtest,
AppExit AppExit
} }
} }

View file

@ -1,4 +1,4 @@
using static ServiceLib.Models.ClashProxies; using static ServiceLib.Models.ClashProxies;
namespace ServiceLib.Handler namespace ServiceLib.Handler
{ {
@ -38,63 +38,63 @@ namespace ServiceLib.Handler
public void ClashProxiesDelayTest(bool blAll, List<ClashProxyModel> lstProxy, Action<ClashProxyModel?, string> updateFunc) public void ClashProxiesDelayTest(bool blAll, List<ClashProxyModel> lstProxy, Action<ClashProxyModel?, string> updateFunc)
{ {
Task.Run(() => Task.Run(() =>
{
if (blAll)
{ {
if (blAll) for (int i = 0; i < 5; i++)
{ {
for (var i = 0; i < 5; i++) if (_proxies != null)
{ {
if (_proxies != null) break;
{
break;
}
Task.Delay(5000).Wait();
}
if (_proxies == null)
{
return;
}
lstProxy = new List<ClashProxyModel>();
foreach (KeyValuePair<string, ProxiesItem> kv in _proxies)
{
if (Global.notAllowTestType.Contains(kv.Value.type.ToLower()))
{
continue;
}
lstProxy.Add(new ClashProxyModel()
{
Name = kv.Value.name,
Type = kv.Value.type.ToLower(),
});
} }
Task.Delay(5000).Wait();
} }
if (_proxies == null)
if (lstProxy == null)
{ {
return; return;
} }
var urlBase = $"{GetApiUrl()}/proxies"; lstProxy = new List<ClashProxyModel>();
urlBase += @"/{0}/delay?timeout=10000&url=" + AppHandler.Instance.Config.SpeedTestItem.SpeedPingTestUrl; foreach (KeyValuePair<string, ProxiesItem> kv in _proxies)
var tasks = new List<Task>();
foreach (var it in lstProxy)
{ {
if (Global.notAllowTestType.Contains(it.Type.ToLower())) if (Global.notAllowTestType.Contains(kv.Value.type.ToLower()))
{ {
continue; continue;
} }
var name = it.Name; lstProxy.Add(new ClashProxyModel()
var url = string.Format(urlBase, name);
tasks.Add(Task.Run(async () =>
{ {
var result = await HttpClientHelper.Instance.TryGetAsync(url); Name = kv.Value.name,
updateFunc?.Invoke(it, result); Type = kv.Value.type.ToLower(),
})); });
} }
Task.WaitAll(tasks.ToArray()); }
Task.Delay(1000).Wait(); if (lstProxy == null)
updateFunc?.Invoke(null, ""); {
}); return;
}
var urlBase = $"{GetApiUrl()}/proxies";
urlBase += @"/{0}/delay?timeout=10000&url=" + AppHandler.Instance.Config.SpeedTestItem.SpeedPingTestUrl;
List<Task> tasks = new List<Task>();
foreach (var it in lstProxy)
{
if (Global.notAllowTestType.Contains(it.Type.ToLower()))
{
continue;
}
var name = it.Name;
var url = string.Format(urlBase, name);
tasks.Add(Task.Run(async () =>
{
var result = await HttpClientHelper.Instance.TryGetAsync(url);
updateFunc?.Invoke(it, result);
}));
}
Task.WaitAll(tasks.ToArray());
Task.Delay(1000).Wait();
updateFunc?.Invoke(null, "");
});
} }
public List<ProxiesItem>? GetClashProxyGroups() public List<ProxiesItem>? GetClashProxyGroups()
@ -120,7 +120,7 @@ namespace ServiceLib.Handler
try try
{ {
var url = $"{GetApiUrl()}/proxies/{name}"; var url = $"{GetApiUrl()}/proxies/{name}";
var headers = new Dictionary<string, string>(); Dictionary<string, string> headers = new Dictionary<string, string>();
headers.Add("name", nameNode); headers.Add("name", nameNode);
await HttpClientHelper.Instance.PutAsync(url, headers); await HttpClientHelper.Instance.PutAsync(url, headers);
} }
@ -148,7 +148,7 @@ namespace ServiceLib.Handler
try try
{ {
var url = $"{GetApiUrl()}/configs?force=true"; var url = $"{GetApiUrl()}/configs?force=true";
var headers = new Dictionary<string, string>(); Dictionary<string, string> headers = new Dictionary<string, string>();
headers.Add("path", filePath); headers.Add("path", filePath);
await HttpClientHelper.Instance.PutAsync(url, headers); await HttpClientHelper.Instance.PutAsync(url, headers);
} }
@ -194,4 +194,4 @@ namespace ServiceLib.Handler
return $"{Global.HttpProtocol}{Global.Loopback}:{AppHandler.Instance.StatePort2}"; return $"{Global.HttpProtocol}{Global.Loopback}:{AppHandler.Instance.StatePort2}";
} }
} }
} }

View file

@ -1,47 +1,34 @@
using System.Collections.Concurrent;
using System.Diagnostics; using System.Diagnostics;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using ReactiveUI;
namespace ServiceLib.Services namespace ServiceLib.Services
{ {
public class SpeedtestService public class SpeedtestService
{ {
private static readonly string _tag = "SpeedtestService";
private Config? _config; private Config? _config;
private Action<SpeedTestResult>? _updateFunc; private Action<SpeedTestResult>? _updateFunc;
private static readonly ConcurrentBag<string> _lstExitLoop = new();
public SpeedtestService(Config config, Action<SpeedTestResult> updateFunc) private bool _exitLoop = false;
private static readonly string _tag = "SpeedtestService";
public SpeedtestService(Config config, ESpeedActionType actionType, List<ProfileItem> selecteds, Action<SpeedTestResult> updateFunc)
{ {
_config = config; _config = config;
_updateFunc = updateFunc; _updateFunc = updateFunc;
}
public void RunLoop(ESpeedActionType actionType, List<ProfileItem> selecteds) MessageBus.Current.Listen<string>(EMsgCommand.StopSpeedtest.ToString()).Subscribe(ExitLoop);
{
Task.Run(async () => Task.Run(async () =>
{ {
var exitLoopKey = Utils.GetGuid(false);
_lstExitLoop.Add(exitLoopKey);
var lstSelected = GetClearItem(actionType, selecteds); var lstSelected = GetClearItem(actionType, selecteds);
await RunAsync(actionType, lstSelected, exitLoopKey); await RunAsync(actionType, lstSelected);
UpdateFunc("", ResUI.SpeedtestingCompleted); UpdateFunc("", ResUI.SpeedtestingCompleted);
}); });
} }
public void ExitLoop() private async Task RunAsync(ESpeedActionType actionType, List<ServerTestItem> lstSelected, int pageSize = 0)
{
if (_lstExitLoop.Count > 0)
{
UpdateFunc("", ResUI.SpeedtestingStop);
_lstExitLoop.Clear();
}
}
private async Task RunAsync(ESpeedActionType actionType, List<ServerTestItem> lstSelected, string exitLoopKey, int pageSize = 0)
{ {
if (actionType == ESpeedActionType.Tcping) if (actionType == ESpeedActionType.Tcping)
{ {
@ -60,9 +47,9 @@ namespace ServiceLib.Services
{ {
var ret = actionType switch var ret = actionType switch
{ {
ESpeedActionType.Realping => await RunRealPingAsync(lst, exitLoopKey), ESpeedActionType.Realping => await RunRealPingAsync(lst),
ESpeedActionType.Speedtest => await RunSpeedTestAsync(lst, exitLoopKey), ESpeedActionType.Speedtest => await RunSpeedTestAsync(lst),
ESpeedActionType.Mixedtest => await RunMixedTestAsync(lst, exitLoopKey), ESpeedActionType.Mixedtest => await RunMixedTestAsync(lst),
_ => true _ => true
}; };
if (ret == false) if (ret == false)
@ -76,14 +63,14 @@ namespace ServiceLib.Services
var pageSizeNext = pageSize / 2; var pageSizeNext = pageSize / 2;
if (lstFailed.Count > 0 && pageSizeNext > 0) if (lstFailed.Count > 0 && pageSizeNext > 0)
{ {
if (_lstExitLoop.Any(p => p == exitLoopKey) == false) if (_exitLoop)
{ {
UpdateFunc("", ResUI.SpeedtestingSkip); UpdateFunc("", ResUI.SpeedtestingSkip);
return; return;
} }
UpdateFunc("", string.Format(ResUI.SpeedtestingTestFailedPart, lstFailed.Count)); UpdateFunc("", string.Format(ResUI.SpeedtestingTestFailedPart, lstFailed.Count));
await RunAsync(actionType, lstFailed, exitLoopKey, pageSizeNext); await RunAsync(actionType, lstFailed, pageSizeNext);
} }
} }
@ -156,6 +143,14 @@ namespace ServiceLib.Services
return lstTest; return lstTest;
} }
private void ExitLoop(string x)
{
if (_exitLoop)
return;
_exitLoop = true;
UpdateFunc("", ResUI.SpeedtestingStop);
}
private async Task RunTcpingAsync(List<ServerTestItem> selecteds) private async Task RunTcpingAsync(List<ServerTestItem> selecteds)
{ {
try try
@ -195,7 +190,7 @@ namespace ServiceLib.Services
} }
} }
private async Task<bool> RunRealPingAsync(List<ServerTestItem> selecteds, string exitLoopKey) private async Task<bool> RunRealPingAsync(List<ServerTestItem> selecteds)
{ {
var pid = -1; var pid = -1;
try try
@ -254,7 +249,7 @@ namespace ServiceLib.Services
return true; return true;
} }
private async Task<bool> RunSpeedTestAsync(List<ServerTestItem> selecteds, string exitLoopKey) private async Task<bool> RunSpeedTestAsync(List<ServerTestItem> selecteds)
{ {
var pid = -1; var pid = -1;
pid = await CoreHandler.Instance.LoadCoreConfigSpeedtest(selecteds); pid = await CoreHandler.Instance.LoadCoreConfigSpeedtest(selecteds);
@ -270,12 +265,11 @@ namespace ServiceLib.Services
foreach (var it in selecteds) foreach (var it in selecteds)
{ {
if (_lstExitLoop.Any(p => p == exitLoopKey) == false) if (_exitLoop)
{ {
UpdateFunc(it.IndexId, "", ResUI.SpeedtestingSkip); UpdateFunc(it.IndexId, "", ResUI.SpeedtestingSkip);
continue; continue;
} }
if (!it.AllowTest) if (!it.AllowTest)
{ {
continue; continue;
@ -317,7 +311,7 @@ namespace ServiceLib.Services
return true; return true;
} }
private async Task<bool> RunSpeedTestMultiAsync(List<ServerTestItem> selecteds, string exitLoopKey) private async Task<bool> RunSpeedTestMulti(List<ServerTestItem> selecteds)
{ {
var pid = -1; var pid = -1;
pid = await CoreHandler.Instance.LoadCoreConfigSpeedtest(selecteds); pid = await CoreHandler.Instance.LoadCoreConfigSpeedtest(selecteds);
@ -333,7 +327,7 @@ namespace ServiceLib.Services
foreach (var it in selecteds) foreach (var it in selecteds)
{ {
if (_lstExitLoop.Any(p => p == exitLoopKey) == false) if (_exitLoop)
{ {
UpdateFunc(it.IndexId, "", ResUI.SpeedtestingSkip); UpdateFunc(it.IndexId, "", ResUI.SpeedtestingSkip);
continue; continue;
@ -382,9 +376,9 @@ namespace ServiceLib.Services
return true; return true;
} }
private async Task<bool> RunMixedTestAsync(List<ServerTestItem> selecteds, string exitLoopKey) private async Task<bool> RunMixedTestAsync(List<ServerTestItem> selecteds)
{ {
var ret = await RunRealPingAsync(selecteds, exitLoopKey); var ret = await RunRealPingAsync(selecteds);
if (ret == false) if (ret == false)
{ {
return false; return false;
@ -392,7 +386,7 @@ namespace ServiceLib.Services
await Task.Delay(1000); await Task.Delay(1000);
var ret2 = await RunSpeedTestMultiAsync(selecteds, exitLoopKey); var ret2 = await RunSpeedTestMulti(selecteds);
if (ret2 == false) if (ret2 == false)
{ {
return false; return false;

View file

@ -21,7 +21,7 @@ namespace ServiceLib.Services.Statistics
Task.Run(Run); Task.Run(Run);
} }
private async Task Init() private async void Init()
{ {
await Task.Delay(5000); await Task.Delay(5000);
@ -53,9 +53,9 @@ namespace ServiceLib.Services.Statistics
} }
} }
private async Task Run() private async void Run()
{ {
await Init(); Init();
while (!_exitFlag) while (!_exitFlag)
{ {
@ -73,7 +73,7 @@ namespace ServiceLib.Services.Statistics
{ {
webSocket.Abort(); webSocket.Abort();
webSocket = null; webSocket = null;
await Init(); Init();
continue; continue;
} }

View file

@ -23,7 +23,7 @@ namespace ServiceLib.Services.Statistics
_exitFlag = true; _exitFlag = true;
} }
private async Task Run() private async void Run()
{ {
while (!_exitFlag) while (!_exitFlag)
{ {

View file

@ -16,7 +16,6 @@ namespace ServiceLib.ViewModels
private List<ProfileItem> _lstProfile; private List<ProfileItem> _lstProfile;
private string _serverFilter = string.Empty; private string _serverFilter = string.Empty;
private Dictionary<string, bool> _dicHeaderSort = new(); private Dictionary<string, bool> _dicHeaderSort = new();
private SpeedtestService? _speedtestService;
#endregion private prop #endregion private prop
@ -723,13 +722,15 @@ namespace ServiceLib.ViewModels
return; return;
} }
_speedtestService ??= new SpeedtestService(_config, (SpeedTestResult result) => _updateView?.Invoke(EViewAction.DispatcherSpeedTest, result)); _ = new SpeedtestService(_config, actionType, lstSelecteds, (SpeedTestResult result) =>
_speedtestService?.RunLoop(actionType, lstSelecteds); {
_updateView?.Invoke(EViewAction.DispatcherSpeedTest, result);
});
} }
public void ServerSpeedtestStop() public void ServerSpeedtestStop()
{ {
_speedtestService?.ExitLoop(); MessageBus.Current.SendMessage("", EMsgCommand.StopSpeedtest.ToString());
} }
private async Task Export2ClientConfigAsync(bool blClipboard) private async Task Export2ClientConfigAsync(bool blClipboard)