新建服务端项目Stardust.Server,原Stardust作为基础组件,供业务系统引用
This commit is contained in:
parent
72d95820d2
commit
528dc777e7
|
@ -6,7 +6,7 @@
|
|||
<Description>星尘,轻量级服务框架。远程方法调用,服务自动注册和发现,负载均衡,动态伸缩,故障转移,性能监控。</Description>
|
||||
<Copyright>版权所有(C) 新生命开发团队 2019</Copyright>
|
||||
<Company>新生命开发团队</Company>
|
||||
<FileVersion>1.0.2019.0101</FileVersion>
|
||||
<FileVersion>1.0.2019.0320</FileVersion>
|
||||
<AssemblyVersion>1.0.*</AssemblyVersion>
|
||||
<Deterministic>false</Deterministic>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
using System;
|
||||
using System.Net;
|
||||
using NewLife;
|
||||
using NewLife.Agent;
|
||||
using NewLife.Log;
|
||||
using NewLife.Net;
|
||||
using NewLife.Remoting;
|
||||
using NewLife.Threading;
|
||||
using Stardust.Data;
|
||||
|
||||
namespace Stardust.Server
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(String[] args) => new MyService().Main();
|
||||
}
|
||||
|
||||
/// <summary>服务类。名字可以自定义</summary>
|
||||
class MyService : AgentServiceBase<MyService>
|
||||
{
|
||||
/// <summary>是否使用线程池调度。false表示禁用线程池,改用Agent线程</summary>
|
||||
public Boolean Pooling { get; set; } = true;
|
||||
|
||||
public MyService()
|
||||
{
|
||||
ServiceName = "Stardust";
|
||||
|
||||
ThreadPoolX.QueueUserWorkItem(() =>
|
||||
{
|
||||
var n = App.Meta.Count;
|
||||
AppStat.Meta.Session.Dal.Db.ShowSQL = false;
|
||||
|
||||
var set2 = XCode.Setting.Current;
|
||||
if (set2.IsNew)
|
||||
{
|
||||
set2.Debug = true;
|
||||
set2.ShowSQL = false;
|
||||
set2.TraceSQLTime = 3000;
|
||||
set2.SQLiteDbPath = @"..\Data";
|
||||
|
||||
set2.Save();
|
||||
}
|
||||
});
|
||||
|
||||
// 注册菜单,在控制台菜单中按 t 可以执行Test函数,主要用于临时处理数据
|
||||
AddMenu('t', "数据测试", Test);
|
||||
}
|
||||
|
||||
ApiServer _Server;
|
||||
private void Init()
|
||||
{
|
||||
var sc = _Server;
|
||||
if (sc == null)
|
||||
{
|
||||
var set = Setting.Current;
|
||||
|
||||
sc = new ApiServer(set.Port)
|
||||
{
|
||||
Log = XTrace.Log
|
||||
};
|
||||
if (set.Debug)
|
||||
{
|
||||
var ns = sc.EnsureCreate() as NetServer;
|
||||
ns.Log = XTrace.Log;
|
||||
#if DEBUG
|
||||
ns.LogSend = true;
|
||||
ns.LogReceive = true;
|
||||
sc.EncoderLog = XTrace.Log;
|
||||
#endif
|
||||
}
|
||||
|
||||
// 注册服务
|
||||
sc.Register<StarService>();
|
||||
|
||||
StarService.Log = XTrace.Log;
|
||||
StarService.Local = new IPEndPoint(NetHelper.MyIP(), set.Port);
|
||||
|
||||
sc.Start();
|
||||
|
||||
_Server = sc;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>服务启动</summary>
|
||||
/// <remarks>
|
||||
/// 安装Windows服务后,服务启动会执行一次该方法。
|
||||
/// 控制台菜单按5进入循环调试也会执行该方法。
|
||||
/// </remarks>
|
||||
protected override void StartWork(String reason)
|
||||
{
|
||||
Init();
|
||||
|
||||
base.StartWork(reason);
|
||||
}
|
||||
|
||||
/// <summary>服务停止</summary>
|
||||
/// <remarks>
|
||||
/// 安装Windows服务后,服务停止会执行该方法。
|
||||
/// 控制台菜单按5进入循环调试,任意键结束时也会执行该方法。
|
||||
/// </remarks>
|
||||
protected override void StopWork(String reason)
|
||||
{
|
||||
base.StopWork(reason);
|
||||
|
||||
_Server.TryDispose();
|
||||
_Server = null;
|
||||
}
|
||||
|
||||
/// <summary>数据测试,菜单t</summary>
|
||||
public void Test()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using NewLife.Xml;
|
||||
|
||||
namespace Stardust.Server
|
||||
{
|
||||
/// <summary>配置</summary>
|
||||
[XmlConfigFile("Config/Stardust.config", 15000)]
|
||||
public class Setting : XmlConfig<Setting>
|
||||
{
|
||||
#region 属性
|
||||
/// <summary>调试开关。默认true</summary>
|
||||
[Description("调试开关。默认true")]
|
||||
public Boolean Debug { get; set; } = true;
|
||||
|
||||
/// <summary>服务端口。默认6666</summary>
|
||||
[Description("服务端口。默认6666")]
|
||||
public Int32 Port { get; set; } = 6666;
|
||||
#endregion
|
||||
|
||||
#region 构造
|
||||
/// <summary>实例化</summary>
|
||||
public Setting()
|
||||
{
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,195 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using NewLife.Log;
|
||||
using NewLife.Net;
|
||||
using NewLife.Remoting;
|
||||
using Stardust.Data;
|
||||
|
||||
namespace Stardust.Server
|
||||
{
|
||||
[Api(null)]
|
||||
public class StarService : IApi, IActionFilter
|
||||
{
|
||||
#region 属性
|
||||
/// <summary>本地节点</summary>
|
||||
public static EndPoint Local { get; set; }
|
||||
#endregion
|
||||
|
||||
#region 登录
|
||||
public IApiSession Session { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 传入应用名和密钥登陆,
|
||||
/// 返回应用名和应用显示名
|
||||
/// </summary>
|
||||
/// <param name="user">应用名</param>
|
||||
/// <param name="pass"></param>
|
||||
/// <returns></returns>
|
||||
[Api(nameof(Login))]
|
||||
public Object Login(String user, String pass)
|
||||
{
|
||||
if (user.IsNullOrEmpty()) throw new ArgumentNullException(nameof(user));
|
||||
if (pass.IsNullOrEmpty()) throw new ArgumentNullException(nameof(pass));
|
||||
|
||||
var ns = Session as INetSession;
|
||||
var ip = ns.Remote.Host;
|
||||
var ps = ControllerContext.Current.Parameters;
|
||||
|
||||
WriteLog("[{0}]从[{1}]登录", user, ns.Remote);
|
||||
|
||||
// 找应用
|
||||
var app = App.FindByName(user);
|
||||
if (app == null || app.Secret.IsNullOrEmpty())
|
||||
{
|
||||
if (app == null) app = new App();
|
||||
|
||||
if (app.ID == 0)
|
||||
{
|
||||
app.Name = user;
|
||||
//app.Secret = pass;
|
||||
app.CreateIP = ip;
|
||||
app.CreateTime = DateTime.Now;
|
||||
app.Enable = true;
|
||||
}
|
||||
|
||||
var name = ps["name"] + "";
|
||||
if (!name.IsNullOrEmpty()) app.DisplayName = name;
|
||||
|
||||
app.UpdateIP = ip;
|
||||
app.UpdateTime = DateTime.Now;
|
||||
|
||||
app.Save();
|
||||
}
|
||||
|
||||
if (!app.Enable) throw new Exception("已禁用!");
|
||||
|
||||
// 核对密码
|
||||
if (!app.Secret.IsNullOrEmpty())
|
||||
{
|
||||
var pass2 = app.Secret.MD5();
|
||||
if (pass != pass2) throw new Exception("密码错误!");
|
||||
}
|
||||
|
||||
// 应用上线
|
||||
CreateOnline(app, ns, ps);
|
||||
|
||||
app.LastIP = ip;
|
||||
app.LastLogin = DateTime.Now;
|
||||
app.Save();
|
||||
|
||||
// 记录当前用户
|
||||
Session["App"] = app;
|
||||
|
||||
return new
|
||||
{
|
||||
app.Name,
|
||||
app.DisplayName,
|
||||
};
|
||||
}
|
||||
|
||||
void IActionFilter.OnActionExecuting(ControllerContext filterContext)
|
||||
{
|
||||
var act = filterContext.ActionName;
|
||||
if (act == nameof(Login)) return;
|
||||
|
||||
if (Session["App"] is App app)
|
||||
{
|
||||
var online = GetOnline(app, Session as INetSession);
|
||||
online.UpdateTime = DateTime.Now;
|
||||
online.SaveAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
var ns = Session as INetSession;
|
||||
throw new ApiException(401, "{0}未登录!不能执行{1}".F(ns.Remote, act));
|
||||
}
|
||||
}
|
||||
|
||||
void IActionFilter.OnActionExecuted(ControllerContext filterContext)
|
||||
{
|
||||
var ex = filterContext.Exception;
|
||||
if (ex != null && !filterContext.ExceptionHandled)
|
||||
{
|
||||
// 显示错误
|
||||
if (ex is ApiException)
|
||||
XTrace.Log.Error(ex.Message);
|
||||
else
|
||||
XTrace.WriteException(ex);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 业务
|
||||
/// <summary>报告服务列表</summary>
|
||||
/// <param name="services"></param>
|
||||
/// <returns></returns>
|
||||
[Api(nameof(Report))]
|
||||
public Boolean Report(String[] services)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 在线状态
|
||||
AppOnline CreateOnline(IApp app, INetSession ns, IDictionary<String, Object> ps)
|
||||
{
|
||||
var ip = ns.Remote.Host;
|
||||
|
||||
var machine = ps["machine"] + "";
|
||||
var pid = ps["processid"].ToInt();
|
||||
var ver = ps["version"] + "";
|
||||
var compile = ps["compile"].ToDateTime();
|
||||
|
||||
var online = GetOnline(app, ns);
|
||||
|
||||
// 客户端特性
|
||||
online.Client = $"{(ip.IsNullOrEmpty() ? machine : ip)}@{pid}";
|
||||
online.Name = machine;
|
||||
online.Version = ver;
|
||||
online.Compile = compile;
|
||||
|
||||
// 服务器特性
|
||||
pid = Process.GetCurrentProcess().Id;
|
||||
online.Server = Local + "@" + pid;
|
||||
online.Save();
|
||||
|
||||
// 真正的用户
|
||||
Session["AppOnline"] = online;
|
||||
|
||||
// 下线
|
||||
ns.OnDisposed += (s, e) => online.Delete();
|
||||
|
||||
// 版本和编译时间
|
||||
if (app.Version.IsNullOrEmpty() || app.Version.CompareTo(ver) < 0) app.Version = ver;
|
||||
if (app.Compile.Year < 2000 || app.Compile < compile) app.Compile = compile;
|
||||
|
||||
return online;
|
||||
}
|
||||
|
||||
AppOnline GetOnline(IApp app, INetSession ns)
|
||||
{
|
||||
if (Session["AppOnline"] is AppOnline online) return online;
|
||||
|
||||
var ip = ns.Remote.Host;
|
||||
var ins = ns.Remote.EndPoint + "";
|
||||
online = AppOnline.FindBySession(ins) ?? new AppOnline { CreateIP = ip };
|
||||
online.AppID = app.ID;
|
||||
online.Session = ins;
|
||||
|
||||
return online;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 日志
|
||||
/// <summary>日志</summary>
|
||||
public static ILog Log { get; set; }
|
||||
|
||||
/// <summary>写日志</summary>
|
||||
/// <param name="format"></param>
|
||||
/// <param name="args"></param>
|
||||
public static void WriteLog(String format, params Object[] args) => Log?.Info(format, args);
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<AssemblyTitle>星尘</AssemblyTitle>
|
||||
<Description>星尘,轻量级服务框架。远程方法调用,服务自动注册和发现,负载均衡,动态伸缩,故障转移,性能监控。</Description>
|
||||
<Copyright>版权所有(C) 新生命开发团队 2019</Copyright>
|
||||
<Company>新生命开发团队</Company>
|
||||
<FileVersion>1.0.2019.0320</FileVersion>
|
||||
<AssemblyVersion>1.0.*</AssemblyVersion>
|
||||
<Deterministic>false</Deterministic>
|
||||
<OutputPath>..\Bin</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.ServiceProcess.ServiceController" Version="4.5.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Stardust.Data\Stardust.Data.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="NewLife.Agent">
|
||||
<HintPath>..\DLL20\NewLife.Agent.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NewLife.Core">
|
||||
<HintPath>..\DLL20\NewLife.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="XCode">
|
||||
<HintPath>..\DLL20\XCode.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -1,12 +1,5 @@
|
|||
using System;
|
||||
using System.Net;
|
||||
using NewLife;
|
||||
using NewLife.Agent;
|
||||
using NewLife.Log;
|
||||
using NewLife.Net;
|
||||
using NewLife.Remoting;
|
||||
using NewLife.Threading;
|
||||
using Stardust.Data;
|
||||
|
||||
namespace Stardust
|
||||
{
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using NewLife.Log;
|
||||
using NewLife.Net;
|
||||
|
|
|
@ -1,36 +1,24 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<TargetFrameworks>net45;netstandard2.0</TargetFrameworks>
|
||||
<AssemblyTitle>星尘</AssemblyTitle>
|
||||
<Description>星尘,轻量级服务框架。远程方法调用,服务自动注册和发现,负载均衡,动态伸缩,故障转移,性能监控。</Description>
|
||||
<Copyright>版权所有(C) 新生命开发团队 2019</Copyright>
|
||||
<Company>新生命开发团队</Company>
|
||||
<FileVersion>1.0.2019.0101</FileVersion>
|
||||
<FileVersion>1.0.2019.0320</FileVersion>
|
||||
<AssemblyVersion>1.0.*</AssemblyVersion>
|
||||
<Deterministic>false</Deterministic>
|
||||
<OutputPath>..\Bin</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.ServiceProcess.ServiceController" Version="4.5.0" />
|
||||
<Compile Remove="Program.cs" />
|
||||
<Compile Remove="Setting.cs" />
|
||||
<Compile Remove="StarService.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Stardust.Data\Stardust.Data.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="NewLife.Agent">
|
||||
<HintPath>..\DLL20\NewLife.Agent.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NewLife.Core">
|
||||
<HintPath>..\DLL20\NewLife.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="XCode">
|
||||
<HintPath>..\DLL20\XCode.dll</HintPath>
|
||||
</Reference>
|
||||
<PackageReference Include="NewLife.Core" Version="8.1.2019.314" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -4,8 +4,8 @@ using System.Threading;
|
|||
using NewLife.Log;
|
||||
using NewLife.Net;
|
||||
using NewLife.Remoting;
|
||||
using Stardust;
|
||||
using Setting = Stardust.Setting;
|
||||
using Stardust.Server;
|
||||
using Setting = Stardust.Server.Setting;
|
||||
|
||||
namespace Test
|
||||
{
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Stardust.Data\Stardust.Data.csproj" />
|
||||
<ProjectReference Include="..\Stardust.Server\Stardust.Server.csproj" />
|
||||
<ProjectReference Include="..\Stardust\Stardust.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
10
星尘.sln
10
星尘.sln
|
@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.28307.168
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stardust", "Stardust\Stardust.csproj", "{AADBD913-749C-467E-A63F-C118C4C82351}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stardust", "Stardust\Stardust.csproj", "{AADBD913-749C-467E-A63F-C118C4C82351}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stardust.Web", "Stardust.Web\Stardust.Web.csproj", "{25331DEF-FEE3-44D5-A4E9-864078441F71}"
|
||||
EndProject
|
||||
|
@ -16,7 +16,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stardust.Data", "Stardust.D
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stardust.WebFx", "Stardust.WebFx\Stardust.WebFx.csproj", "{A9E0597C-E818-4B33-8AC3-BE134D68B78E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test", "Test\Test.csproj", "{3B87711E-FF90-470B-A429-CFDF3B9B1F5F}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Test", "Test\Test.csproj", "{3B87711E-FF90-470B-A429-CFDF3B9B1F5F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stardust.Server", "Stardust.Server\Stardust.Server.csproj", "{73B28F07-E99F-45A8-B9A0-90E7BAC133A3}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
@ -44,6 +46,10 @@ Global
|
|||
{3B87711E-FF90-470B-A429-CFDF3B9B1F5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3B87711E-FF90-470B-A429-CFDF3B9B1F5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3B87711E-FF90-470B-A429-CFDF3B9B1F5F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{73B28F07-E99F-45A8-B9A0-90E7BAC133A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{73B28F07-E99F-45A8-B9A0-90E7BAC133A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{73B28F07-E99F-45A8-B9A0-90E7BAC133A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{73B28F07-E99F-45A8-B9A0-90E7BAC133A3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
Loading…
Reference in New Issue