mirror of
https://github.com/yaobiao131/downkyicore.git
synced 2025-08-10 00:52:31 +00:00
272 lines
9.3 KiB
C#
272 lines
9.3 KiB
C#
using System.Diagnostics;
|
||
using System.Text;
|
||
using DownKyi.Core.Aria2cNet.Client;
|
||
using DownKyi.Core.Logging;
|
||
using DownKyi.Core.Storage;
|
||
using Console = DownKyi.Core.Utils.Debugging.Console;
|
||
|
||
namespace DownKyi.Core.Aria2cNet.Server
|
||
{
|
||
public static class AriaServer
|
||
{
|
||
public static int ListenPort; // 服务器端口
|
||
private static Process Server;
|
||
|
||
/// <summary>
|
||
/// 启动aria2c服务器
|
||
/// </summary>
|
||
/// <param name="config"></param>
|
||
/// <param name="action"></param>
|
||
/// <returns></returns>
|
||
public static async Task<bool> StartServerAsync(AriaConfig config, Action<string> action)
|
||
{
|
||
// aria端口
|
||
ListenPort = config.ListenPort;
|
||
// aria目录
|
||
// var ariaDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "aria");
|
||
var ariaDir = StorageManager.GetAriaDir();
|
||
// 会话文件
|
||
#if DEBUG
|
||
var sessionFile = Path.Combine(ariaDir, "aira.session");
|
||
|
||
#else
|
||
var sessionFile = Path.Combine(ariaDir, "aira.session.gz");
|
||
#endif
|
||
// 日志文件
|
||
var logFile = Path.Combine(ariaDir, "aira.log");
|
||
// 自动保存会话文件的时间间隔
|
||
var saveSessionInterval = 30;
|
||
|
||
// --enable-rpc --rpc-listen-all=true --rpc-allow-origin-all=true --continue=true
|
||
await Task.Run(() =>
|
||
{
|
||
// 创建目录和文件
|
||
if (!Directory.Exists(ariaDir))
|
||
{
|
||
Directory.CreateDirectory(ariaDir);
|
||
}
|
||
|
||
if (!File.Exists(sessionFile))
|
||
{
|
||
var stream = File.Create(sessionFile);
|
||
stream.Close();
|
||
}
|
||
|
||
if (!File.Exists(logFile))
|
||
{
|
||
var stream = File.Create(logFile);
|
||
stream.Close();
|
||
}
|
||
else
|
||
{
|
||
// 日志文件存在,如果大于100M,则删除
|
||
try
|
||
{
|
||
var stream = File.Open(logFile, FileMode.Open);
|
||
if (stream.Length >= 10 * 1024 * 1024L)
|
||
{
|
||
stream.SetLength(0);
|
||
}
|
||
|
||
stream.Close();
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Console.PrintLine("StartServerAsync()发生其他异常: {0}", e);
|
||
LogManager.Error("AriaServer", e);
|
||
}
|
||
}
|
||
|
||
// header 解析
|
||
var headers = string.Empty;
|
||
if (config.Headers != null)
|
||
{
|
||
headers = config.Headers.Aggregate(headers,
|
||
(current, header) => current + $"--header=\"{header}\" ");
|
||
}
|
||
|
||
var executeName = "aria2c";
|
||
|
||
if (OperatingSystem.IsWindows())
|
||
{
|
||
executeName += ".exe";
|
||
}
|
||
|
||
ExecuteProcess($"aria2/{executeName}",
|
||
$"--enable-rpc --rpc-listen-all=true --rpc-allow-origin-all=true " +
|
||
$"--check-certificate=false " + // 解决问题 SSL/TLS handshake failure
|
||
$"--rpc-listen-port={config.ListenPort} " +
|
||
$"--rpc-secret={config.Token} " +
|
||
$"--input-file=\"{sessionFile}\" --save-session=\"{sessionFile}\" " +
|
||
$"--save-session-interval={saveSessionInterval} " +
|
||
$"--log=\"{logFile}\" --log-level={config.LogLevel.ToString("G").ToLower()} " + // log-level: 'debug' 'info' 'notice' 'warn' 'error'
|
||
$"--max-concurrent-downloads={config.MaxConcurrentDownloads} " + // 最大同时下载数(任务数)
|
||
$"--max-connection-per-server={config.MaxConnectionPerServer} " + // 同服务器连接数
|
||
$"--split={config.Split} " + // 单文件最大线程数
|
||
//$"--max-tries={config.MaxTries} retry-wait=3 " + // 尝试重连次数
|
||
$"--min-split-size={config.MinSplitSize}M " + // 最小文件分片大小, 下载线程数上限取决于能分出多少片, 对于小文件重要
|
||
$"--max-overall-download-limit={config.MaxOverallDownloadLimit} " + // 下载速度限制
|
||
$"--max-download-limit={config.MaxDownloadLimit} " + // 下载单文件速度限制
|
||
$"--continue={config.ContinueDownload.ToString().ToLower()} " + // 断点续传
|
||
$"--allow-overwrite=true " + // 允许复写文件
|
||
$"--auto-file-renaming=false " +
|
||
$"--file-allocation={config.FileAllocation.ToString("G").ToLower()} " + // 文件预分配, none prealloc
|
||
$"{headers}" + // header
|
||
"",
|
||
null, (s, e) =>
|
||
{
|
||
if (string.IsNullOrEmpty(e.Data) || e.Data.Replace(" ", "") == "")
|
||
{
|
||
return;
|
||
}
|
||
|
||
Console.PrintLine(e.Data);
|
||
LogManager.Debug("AriaServer", e.Data);
|
||
|
||
action.Invoke(e.Data);
|
||
});
|
||
});
|
||
|
||
return true;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 关闭aria2c服务器,异步方法
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public static async Task<bool> CloseServerAsync()
|
||
{
|
||
await AriaClient.ShutdownAsync();
|
||
// 等待进程结束
|
||
await Task.Run(() =>
|
||
{
|
||
Server.WaitForExit(30000);
|
||
try
|
||
{
|
||
Server.Kill();
|
||
}
|
||
catch (Exception)
|
||
{
|
||
}
|
||
});
|
||
return true;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 强制关闭aria2c服务器,异步方法
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public static async Task<bool> ForceCloseServerAsync()
|
||
{
|
||
//await Task.Run(() =>
|
||
//{
|
||
// if (Server == null) { return; }
|
||
|
||
// Server.Kill();
|
||
// Server = null; // 将Server指向null
|
||
//});
|
||
//return true;
|
||
await AriaClient.ForceShutdownAsync();
|
||
return true;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 关闭aria2c服务器
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public static bool CloseServer()
|
||
{
|
||
var task = AriaClient.ShutdownAsync();
|
||
if (task.Result != null && task.Result.Result != null && task.Result.Result == "OK")
|
||
{
|
||
// 等待进程结束
|
||
Server.WaitForExit(30000);
|
||
try
|
||
{
|
||
Server.Kill();
|
||
}
|
||
catch (Exception)
|
||
{
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 强制关闭aria2c服务器
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public static bool ForceCloseServer()
|
||
{
|
||
var task = AriaClient.ForceShutdownAsync();
|
||
if (task.Result != null && task.Result.Result != null && task.Result.Result == "OK")
|
||
{
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 杀死Aria进程
|
||
/// </summary>
|
||
/// <param name="processName"></param>
|
||
/// <returns></returns>
|
||
public static bool KillServer(string processName = "aria2c")
|
||
{
|
||
Process[] processes = Process.GetProcessesByName(processName);
|
||
foreach (var process in processes)
|
||
{
|
||
try
|
||
{
|
||
process.Kill();
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Console.PrintLine("KillServer()发生异常: {0}", e);
|
||
LogManager.Error("AriaServer", e);
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
|
||
private static void ExecuteProcess(string exe, string arg, string? workingDirectory,
|
||
DataReceivedEventHandler output)
|
||
{
|
||
var p = new Process();
|
||
Server = p;
|
||
|
||
p.StartInfo.FileName = exe;
|
||
p.StartInfo.Arguments = arg;
|
||
|
||
// 工作目录
|
||
if (workingDirectory != null)
|
||
{
|
||
p.StartInfo.WorkingDirectory = workingDirectory;
|
||
}
|
||
|
||
// 输出信息重定向
|
||
p.StartInfo.UseShellExecute = false;
|
||
p.StartInfo.CreateNoWindow = true;
|
||
p.StartInfo.RedirectStandardError = true;
|
||
p.StartInfo.RedirectStandardOutput = true;
|
||
|
||
// 将 StandardErrorEncoding 改为 UTF-8 才不会出现中文乱码
|
||
p.StartInfo.StandardOutputEncoding = Encoding.UTF8;
|
||
p.StartInfo.StandardErrorEncoding = Encoding.UTF8;
|
||
|
||
p.OutputDataReceived += output;
|
||
p.ErrorDataReceived += output;
|
||
|
||
// 启动线程
|
||
p.Start();
|
||
p.BeginOutputReadLine();
|
||
p.BeginErrorReadLine();
|
||
}
|
||
}
|
||
} |