Stardust/StarAgent/StarService.cs

262 lines
7.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using NewLife;
using NewLife.Agent;
using NewLife.Log;
using NewLife.Model;
using NewLife.Net;
using NewLife.Remoting;
using NewLife.Serialization;
using NewLife.Threading;
using Stardust;
using Stardust.Managers;
using Stardust.Models;
namespace StarAgent;
[Api(null)]
public class StarService : DisposeBase, IApi
{
#region
/// <summary>
/// 网络会话
/// </summary>
public IApiSession Session { get; set; }
///// <summary>服务对象</summary>
//public ServiceBase Service { get; set; }
///// <summary>服务主机</summary>
//public IHost Host { get; set; }
/// <summary>应用服务管理</summary>
public ServiceManager Manager { get; set; }
/// <summary>服务提供者</summary>
public IServiceProvider Provider { get; set; }
///// <summary>插件管理</summary>
//public PluginManager PluginManager { get; set; }
/// <summary>星尘设置</summary>
public StarSetting StarSetting { get; set; }
/// <summary>星尘代理设置</summary>
public StarAgentSetting AgentSetting { get; set; }
private AgentInfo _agentInfo;
private TimerX _timer;
#endregion
#region
public StarService()
{
// 获取本地进程名比较慢平均200ms有时候超过500ms
//Task.Run(() =>
//{
// _agentInfo = AgentInfo.GetLocal(true);
//});
_timer = new TimerX(DoRefreshLocal, null, 100, 5_000) { Async = true };
}
/// <summary>销毁</summary>
/// <param name="disposing"></param>
protected override void Dispose(Boolean disposing)
{
base.Dispose(disposing);
_timer.TryDispose();
}
#endregion
#region
/// <summary>信息</summary>
/// <returns></returns>
[Api(nameof(Info))]
public AgentInfo Info(AgentInfo info)
{
XTrace.WriteLine("Info<={0}", info.ToJson());
var set = StarSetting;
var ai = _agentInfo ??= AgentInfo.GetLocal(true);
ai.Server = set.Server;
ai.Services = Manager?.Services.Select(e => e.Name).ToArray();
ai.Code = AgentSetting.Code;
// 返回插件服务器地址
var core = NewLife.Setting.Current;
if (!core.PluginServer.IsNullOrEmpty() && !core.PluginServer.Contains("x.newlifex.com"))
{
ai.PluginServer = core.PluginServer;
}
return ai;
}
public PingResponse Ping(AppInfo appInfo)
{
return null;
}
/// <summary>设置星尘服务端地址</summary>
/// <returns></returns>
[Api(nameof(SetServer))]
public String SetServer(String server)
{
var set = StarSetting;
if (set.Server.IsNullOrEmpty() && !server.IsNullOrEmpty())
{
set.Server = server;
set.Save();
XTrace.WriteLine("StarAgent使用[{0}]送过来的星尘服务端地址:{1}", Session, server);
if (Provider?.GetService<ServiceBase>() is MyService svc)
{
ThreadPool.QueueUserWorkItem(s =>
{
Thread.Sleep(1000);
svc.StartFactory();
svc.StartClient();
});
}
}
return set.Server;
}
private void DoRefreshLocal(Object state)
{
var ai = AgentInfo.GetLocal(true);
if (ai != null)
{
//XTrace.WriteLine("IP: {0}", ai.IP);
_agentInfo = ai;
// 如果未取得本机IP则在较短时间内重新获取
if (_timer != null)
_timer.Period = ai.IP.IsNullOrEmpty() ? 5_000 : 60_000;
}
}
private void CheckLocal()
{
if (Session is INetSession ns && !ns.Remote.Address.IsLocal()) throw new InvalidOperationException("禁止非本机操作!");
}
///// <summary>杀死并启动进程</summary>
///// <param name="processId">进程</param>
///// <param name="delay">延迟结束的秒数</param>
///// <param name="fileName">文件名</param>
///// <param name="arguments">参数</param>
///// <param name="workingDirectory">工作目录</param>
///// <returns></returns>
//[Api(nameof(KillAndStart))]
//public Object KillAndStart(Int32 processId, Int32 delay, String fileName, String arguments, String workingDirectory)
//{
// CheckLocal();
// var p = Process.GetProcessById(processId);
// if (p == null) throw new InvalidOperationException($"无效进程Id[{processId}]");
// var name = p.ProcessName;
// var pid = 0;
// ThreadPool.QueueUserWorkItem(s =>
// {
// WriteLog("杀死进程 {0}/{1},等待 {2}秒", processId, p.ProcessName, delay);
// if (delay > 0) Thread.Sleep(delay * 1000);
// try
// {
// if (!p.HasExited)
// {
// p.Kill();
// p.WaitForExit(5_000);
// }
// }
// catch (Exception ex)
// {
// XTrace.WriteException(ex);
// }
// // 启动进程
// if (!fileName.IsNullOrEmpty())
// {
// WriteLog("启动进程:{0} {1} {2}", fileName, arguments, workingDirectory);
// var si = new ProcessStartInfo
// {
// FileName = fileName,
// Arguments = arguments,
// WorkingDirectory = workingDirectory,
// // false时目前控制台合并到当前控制台一起退出
// // true时目标控制台独立窗口不会一起退出
// UseShellExecute = true,
// };
// var p2 = Process.Start(si);
// pid = p2.Id;
// WriteLog("应用[{0}]启动成功 PID={1}", p2.ProcessName, p2.Id);
// }
// });
// return new { name, pid };
//}
///// <summary>安装应用服务(星尘代理守护)</summary>
///// <param name="service"></param>
///// <returns></returns>
//[Api(nameof(Install))]
//public ProcessInfo Install(ServiceInfo service)
//{
// XTrace.WriteLine("Install<={0}", service.ToJson());
// CheckLocal();
// var rs = Manager.Install(service);
// if (rs != null)
// {
// var set = Setting.Current;
// set.Services = Manager.Services;
// set.Save();
// }
// return rs;
//}
///// <summary>卸载应用服务</summary>
///// <param name="serviceName"></param>
///// <returns></returns>
//[Api(nameof(Uninstall))]
//public Boolean Uninstall(String serviceName)
//{
// XTrace.WriteLine("Uninstall<={0}", serviceName);
// CheckLocal();
// var rs = Manager.Uninstall(serviceName, "ServiceUninstall");
// if (rs)
// {
// var set = Setting.Current;
// set.Services = Manager.Services;
// set.Save();
// }
// return rs;
//}
#endregion
#region
/// <summary>日志</summary>
public ILog Log { get; set; }
/// <summary>写日志</summary>
/// <param name="format"></param>
/// <param name="args"></param>
public void WriteLog(String format, params Object[] args) => Log?.Info(format, args);
#endregion
}