From cb05dc82154fea5e23247e38222ce40912f281cf Mon Sep 17 00:00:00 2001 From: zerlei <1445089819@qq.com> Date: Sat, 7 Sep 2024 14:46:08 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E6=88=91=E5=A5=BD=E5=83=8F=E5=9C=A8?= =?UTF-8?q?=E5=88=AB=E7=9A=84=E5=9C=B0=E6=96=B9=E5=86=99=E4=BA=86=E4=B8=80?= =?UTF-8?q?=E7=82=B9=E3=80=82=E3=80=82=E3=80=82=E3=80=82=20=E5=85=88?= =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=B8=8A=E5=8E=BB=E5=90=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Server/Common/Config.cs | 15 +- Server/Common/ConnectPipeline.cs | 15 +- Server/Common/Message.cs | 2 +- .../Controllers/LocalServerController.cs | 20 +- Server/LocalServer/LocalSyncServer.cs | 15 +- Server/LocalServer/LocalSyncServerFactory.cs | 15 +- Server/LocalServer/StateHelper.cs | 27 +- .../Controllers/RemoteServerController.cs | 36 +- Server/RemoteServer/Program.cs | 13 +- Server/RemoteServer/RemoteSyncServer.cs | 129 ++---- .../RemoteServer/RemoteSyncServerFactory.cs | 29 +- Server/RemoteServer/StateHelper.cs | 395 ++---------------- Server/RemoteServer/appsettings.json | 8 +- 13 files changed, 202 insertions(+), 517 deletions(-) diff --git a/Server/Common/Config.cs b/Server/Common/Config.cs index 7fddd56..d7e195a 100644 --- a/Server/Common/Config.cs +++ b/Server/Common/Config.cs @@ -16,7 +16,7 @@ public class DirFileConfig /// 除此外全部忽略,最高优先级,若有值,ExcludeFiles 将被忽略,它是根目录的相对路径 /// public List? CherryPicks { get; set; } - public Dir? LocalDirInfo { get; set; } + public Dir? DirInfo { get; set; } } public class Config @@ -26,24 +26,28 @@ public class Config /// public required string Name { get; set; } + public Guid Id { get; set; } = Guid.NewGuid(); + /// /// 远程Url /// public required string RemoteUrl { get; set; } + /// /// 链接到远程的密码 /// - public required string RemotePwd {get;set;} + public required string RemotePwd { get; set; } /// /// 是否发布数据库 /// - public required bool IsDeployDb {get;set;} + public required bool IsDeployDb { get; set; } /// /// 源数据库连接字符串(ip地址相对LocalServer) /// public required string SrcDbConnection { get; set; } + /// /// 目标数据库连接字符串(ip地址相对RemoteServer) /// @@ -52,12 +56,13 @@ public class Config /// /// 同步的表 /// - public required List? SyncDataTables {get;set;} + public required List? SyncDataTables { get; set; } /// /// 是否发布项目 /// - public required bool IsDeployProject {get;set;} + public required bool IsDeployProject { get; set; } + /// /// 项目的绝对路径 空字符串表示不发布,不为空LocalRootPath将是发布路径。 /// diff --git a/Server/Common/ConnectPipeline.cs b/Server/Common/ConnectPipeline.cs index 26f3b63..a834ee9 100644 --- a/Server/Common/ConnectPipeline.cs +++ b/Server/Common/ConnectPipeline.cs @@ -4,7 +4,7 @@ using System.Text.Json; namespace Common; -public abstract class AbsPipeLine +public abstract class AbsPipeLine(bool isAES) { public abstract IAsyncEnumerable Work(Func receiveCb, string addr = ""); protected Func ReceiveMsg = (byte[] a) => @@ -26,17 +26,16 @@ public abstract class AbsPipeLine /// /// public abstract Task SendMsg(SyncMsg msg); + + protected readonly bool IsAES = isAES; } -public class WebSocPipeLine(TSocket socket) : AbsPipeLine +public class WebSocPipeLine(TSocket socket, bool isAES) : AbsPipeLine(isAES) where TSocket : WebSocket { public readonly TSocket Socket = socket; - public override async IAsyncEnumerable Work( - Func receiveCb, - string addr = "" - ) + public override async IAsyncEnumerable Work(Func receiveCb, string addr = "") { if (Socket is ClientWebSocket CSocket) { @@ -94,7 +93,9 @@ public class WebSocPipeLine(TSocket socket) : AbsPipeLine { string msgStr = JsonSerializer.Serialize(msg); await Socket.SendAsync( - new ArraySegment(Encoding.UTF8.GetBytes(msgStr)), + IsAES + ? AESHelper.EncryptStringToBytes_Aes(msgStr) + : new ArraySegment(Encoding.UTF8.GetBytes(msgStr)), WebSocketMessageType.Text, true, CancellationToken.None diff --git a/Server/Common/Message.cs b/Server/Common/Message.cs index e2c14aa..62047eb 100644 --- a/Server/Common/Message.cs +++ b/Server/Common/Message.cs @@ -13,7 +13,7 @@ public enum SyncProcessStep DeployProject = 2, DiffFileAndPack = 3, PackSqlServer = 4, - Upload = 5, + UploadAndUnpack = 5, Publish = 6 } public class SyncMsg(SyncMsgType msgType, SyncProcessStep step, string body) diff --git a/Server/LocalServer/Controllers/LocalServerController.cs b/Server/LocalServer/Controllers/LocalServerController.cs index 99d15b7..1e9be38 100644 --- a/Server/LocalServer/Controllers/LocalServerController.cs +++ b/Server/LocalServer/Controllers/LocalServerController.cs @@ -1,8 +1,9 @@ using System.Net.NetworkInformation; -using System.Text; -using Microsoft.AspNetCore.Mvc; -using Common; using System.Net.WebSockets; +using System.Text; +using Common; +using Microsoft.AspNetCore.Mvc; + namespace LocalServer.Controllers { public class LocalServerController(LocalSyncServerFactory factory) : ControllerBase @@ -16,9 +17,16 @@ namespace LocalServer.Controllers { try { - var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync(); - var pipeLine = new WebSocPipeLine(webSocket); - Factory.CreateLocalSyncServer(pipeLine, Name); + if (Factory.GetServerByName(Name) == null) + { + var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync(); + var pipeLine = new WebSocPipeLine(webSocket,false); + Factory.CreateLocalSyncServer(pipeLine, Name); + } + else + { + throw new Exception("LocalServer: 已经存在同名的发布正在进行!"); + } } catch (Exception e) { diff --git a/Server/LocalServer/LocalSyncServer.cs b/Server/LocalServer/LocalSyncServer.cs index 1bcf3ad..cc967ba 100644 --- a/Server/LocalServer/LocalSyncServer.cs +++ b/Server/LocalServer/LocalSyncServer.cs @@ -1,6 +1,4 @@ using System.Net.WebSockets; -using System.Text; -using System.Text.Json; using Common; namespace LocalServer; @@ -26,30 +24,27 @@ public class LocalSyncServer } } + public string Name; + /// /// 发布源连接 /// public readonly AbsPipeLine LocalPipe; public readonly AbsPipeLine RemotePipe = new WebSocPipeLine( - new ClientWebSocket() + new ClientWebSocket(),false ); - /// - /// 发布名称 - /// - public readonly string Name; - /// /// 父工程,用于释放资源 /// public readonly LocalSyncServerFactory Factory; - public LocalSyncServer(AbsPipeLine pipe, string name, LocalSyncServerFactory factory) + public LocalSyncServer(AbsPipeLine pipe, LocalSyncServerFactory factory,string name) { LocalPipe = pipe; - Name = name; Factory = factory; StateHelper = new ConnectAuthorityHelper(this); + Name = name; Task.Run(async () => { diff --git a/Server/LocalServer/LocalSyncServerFactory.cs b/Server/LocalServer/LocalSyncServerFactory.cs index 1d5435d..9fd81e9 100644 --- a/Server/LocalServer/LocalSyncServerFactory.cs +++ b/Server/LocalServer/LocalSyncServerFactory.cs @@ -1,4 +1,3 @@ -using System.Net.WebSockets; using Common; namespace LocalServer; @@ -6,13 +5,9 @@ public class LocalSyncServerFactory { private readonly object Lock = new(); - public void CreateLocalSyncServer(AbsPipeLine pipeLine, string name) + public void CreateLocalSyncServer(AbsPipeLine pipeLine,string name) { - if (Servers.Select(x => x.Name == name).Any()) - { - throw new Exception("LocalServer:存在同名发布源!"); - } - var server = new LocalSyncServer(pipeLine, name, this); + var server = new LocalSyncServer(pipeLine, this,name); lock (Lock) { Servers.Add(server); @@ -28,4 +23,10 @@ public class LocalSyncServerFactory Servers.Remove(server); } } + + public LocalSyncServer? GetServerByName(string name) + { + var it = Servers.Where(x=>x.Name== name).FirstOrDefault(); + return it; + } } diff --git a/Server/LocalServer/StateHelper.cs b/Server/LocalServer/StateHelper.cs index 758e84b..79629fa 100644 --- a/Server/LocalServer/StateHelper.cs +++ b/Server/LocalServer/StateHelper.cs @@ -56,7 +56,7 @@ public abstract class StateHelpBase( { throw new Exception("Sync step error!"); } - HandleLocalMsg(syncMsg); + HandleRemoteMsg(syncMsg); return true; } @@ -95,7 +95,7 @@ public class ConnectAuthorityHelper(LocalSyncServer context) { return Context.StateHelper.ReceiveRemoteMsg(b); }, - Context.NotNullSyncConfig.RemoteUrl + "/websoc" + Context.NotNullSyncConfig.RemoteUrl + "/websoc?Name=" + Context.Name ); await foreach (var r in rs) { @@ -135,7 +135,7 @@ public class DeployHelper(LocalSyncServer context) { FileName = "cmd.exe", // The command to execute (can be any command line tool) Arguments = - $"msdeploy.exe -verb:sync -source:contentPath={Context.NotNullSyncConfig.LocalProjectAbsolutePath} -dest:contentPath={Context.NotNullSyncConfig.LocalRootPath} -disablerule:BackupRule", + $" msdeploy.exe -verb:sync -source:contentPath={Context.NotNullSyncConfig.LocalProjectAbsolutePath} -dest:contentPath={Context.NotNullSyncConfig.LocalRootPath} -disablerule:BackupRule", // The arguments to pass to the command (e.g., list directory contents) RedirectStandardOutput = true, // Redirect the standard output to a string UseShellExecute = false, // Do not use the shell to execute the command @@ -184,8 +184,8 @@ public class DiffFileAndPackHelper(LocalSyncServer context) //提取本地文件的信息 Context.NotNullSyncConfig.DirFileConfigs.ForEach(e => { - e.LocalDirInfo = new Dir(Context.NotNullSyncConfig.LocalRootPath + e.DirPath); - e.LocalDirInfo.ExtractInfo(e.CherryPicks, e.Excludes); + e.DirInfo = new Dir(Context.NotNullSyncConfig.LocalRootPath + e.DirPath); + e.DirInfo.ExtractInfo(e.CherryPicks, e.Excludes); }); //将配置信息发送到remoteServer Context @@ -195,7 +195,22 @@ public class DiffFileAndPackHelper(LocalSyncServer context) protected override void HandleLocalMsg(SyncMsg msg) { } - protected override void HandleRemoteMsg(SyncMsg msg) { } + protected override void HandleRemoteMsg(SyncMsg msg) + { + Context.NotNullSyncConfig.DirFileConfigs = + JsonSerializer.Deserialize>(msg.Body) + ?? throw new Exception("LocalServer: DirFile为空!"); + + var PackOp = new FileDirOpForPack( + Context.NotNullSyncConfig.LocalRootPath, + Context.NotNullSyncConfig.RemoteRootPath + + "/" + + Context.NotNullSyncConfig.Id.ToString(), + Context.NotNullSyncConfig.Id.ToString() + ); + + + } } // /// diff --git a/Server/RemoteServer/Controllers/RemoteServerController.cs b/Server/RemoteServer/Controllers/RemoteServerController.cs index ec4bf61..0e6ba2a 100644 --- a/Server/RemoteServer/Controllers/RemoteServerController.cs +++ b/Server/RemoteServer/Controllers/RemoteServerController.cs @@ -1,34 +1,46 @@ +using System.Net.WebSockets; +using System.Text; +using Common; using Microsoft.AspNetCore.Mvc; using RemoteServer.Models; -using System.Text; + namespace RemoteServer.Controllers; -public class SyncFilesController(RemoteSyncServerFactory factory, SqliteDbContext db) : ControllerBase +public class SyncFilesController(RemoteSyncServerFactory factory, SqliteDbContext db) + : ControllerBase { private readonly SqliteDbContext _db = db; private readonly RemoteSyncServerFactory Factory = factory; - [Route("/websoc")] - public async Task WebsocketConnection(string Name) + [Route("/websoc")] + public async Task WebsocketConnection(string Name) + { + if (HttpContext.WebSockets.IsWebSocketRequest) { - if (HttpContext.WebSockets.IsWebSocketRequest) + try { - try + if (Factory.GetServerByName(Name) == null) { var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync(); - Factory.CreateLocalSyncServer(webSocket, Name); + var pipeLine = new WebSocPipeLine(webSocket,true); + Factory.CreateRemoteSyncServer(pipeLine, Name); } - catch (Exception e) + else { - HttpContext.Response.Body = new MemoryStream(Encoding.UTF8.GetBytes(e.Message)); - HttpContext.Response.StatusCode = StatusCodes.Status406NotAcceptable; + throw new Exception("RemoteServer: 存在相同名称的发布正在进行!"); } } - else + catch (Exception e) { - HttpContext.Response.StatusCode = StatusCodes.Status400BadRequest; + HttpContext.Response.Body = new MemoryStream(Encoding.UTF8.GetBytes(e.Message)); + HttpContext.Response.StatusCode = StatusCodes.Status406NotAcceptable; } } + else + { + HttpContext.Response.StatusCode = StatusCodes.Status400BadRequest; + } + } [HttpGet("/GetSyncFilesLogs")] public IActionResult GetSyncFilesLogs( diff --git a/Server/RemoteServer/Program.cs b/Server/RemoteServer/Program.cs index 4848d0f..c619e3f 100644 --- a/Server/RemoteServer/Program.cs +++ b/Server/RemoteServer/Program.cs @@ -9,14 +9,10 @@ ConfigurationBuilder configurationBuilder = new(); // Add services to the container. //添加配置文件路径 -configurationBuilder - .SetBasePath(Directory.GetCurrentDirectory()) - .AddJsonFile("appsettings.json"); - -//加载文件 -IConfiguration _configuration = configurationBuilder.Build(); -RemoteSyncServer.TempRootFile = _configuration["TempDir"] ?? "C:/TempPack"; -; +RemoteSyncServerFactory.NamePwd = [.. ( + builder.Configuration.GetSection("NamePwds").Get[]>() ?? [] +)]; +RemoteSyncServer.TempRootFile = builder.Configuration["TempDir"] ?? "C:/TempPack"; builder.Services.AddControllers(); builder.Services.AddDbContext(opions => { @@ -26,6 +22,7 @@ builder.Services.AddDbContext(opions => // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); +builder.Services.AddSingleton(); var app = builder.Build(); // Configure the HTTP request pipeline. diff --git a/Server/RemoteServer/RemoteSyncServer.cs b/Server/RemoteServer/RemoteSyncServer.cs index efb8e1e..4beb2f6 100644 --- a/Server/RemoteServer/RemoteSyncServer.cs +++ b/Server/RemoteServer/RemoteSyncServer.cs @@ -1,5 +1,5 @@ + using System.Net.WebSockets; -using System.Text.Json; using Common; namespace RemoteServer; @@ -9,121 +9,68 @@ public class RemoteSyncServer #pragma warning disable CA2211 // Non-constant fields should not be visible public static string TempRootFile = "C:/TempPack"; #pragma warning restore CA2211 // Non-constant fields should not be visible - // public StateHelpBase StateHelper; + public StateHelpBase StateHelper; public Config? SyncConfig; - public Config NotNullSyncConfig {get { - if (SyncConfig == null) + public Config NotNullSyncConfig + { + get { - throw new ArgumentNullException("SyncConfig"); + if (SyncConfig == null) + { + throw new ArgumentNullException("SyncConfig"); + } + return SyncConfig; } - return SyncConfig; - }} + } /// - /// remote server + /// 发布源连接 /// - public readonly WebSocket RemoteSocket; - - /// - /// 发布开始时间 - /// - private readonly DateTime StartTime = DateTime.Now; - - /// - /// 发布名称 - /// - public readonly string Name; - + public readonly AbsPipeLine Pipe; /// /// 父工程,用于释放资源 /// public readonly RemoteSyncServerFactory Factory; + + public string Name; - public RemoteSyncServer(WebSocket socket, string name, RemoteSyncServerFactory factory) + public string Pwd; + + public RemoteSyncServer(AbsPipeLine pipe, RemoteSyncServerFactory factory,string name,string pwd) { - RemoteSocket = socket; - Name = name; + Pipe = pipe; Factory = factory; - // StateHelper = new ConnectAuthorityHelper(this); - } + Name = name; + Pwd = pwd; + StateHelper = new ConnectAuthorityHelper(this); - - public async Task RemoteSocketListen() - { - string CloseMsg = "任务结束关闭"; - try + Task.Run(async () => { - //最大1MB!= - var buffer = new byte[1024 * 1024]; - - while (RemoteSocket.State == WebSocketState.Open) + var rs = Pipe.Work( + (byte[] b) => + { + return StateHelper.ReceiveMsg(b); + } + ); + try { - var receiveResult = await RemoteSocket.ReceiveAsync( - new ArraySegment(buffer), - CancellationToken.None - ); - - if (receiveResult.MessageType == WebSocketMessageType.Close) - { - Close(receiveResult.CloseStatusDescription); - } - else - { - // StateHelper.ReceiveLocalMsg( - // Encoding.UTF8.GetString(buffer, 0, receiveResult.Count) - // ); - } + await foreach (var r in rs) { } } - } - catch (Exception e) - { - CloseMsg = e.Message; - } - finally - { - Close(CloseMsg); - } + catch (Exception e) + { + Close(e.Message); + } + }); } - public async Task RemoteSocketSendMsg(object msgOb) - { - string msg = JsonSerializer.Serialize(msgOb); - var buffer = AESHelper.EncryptStringToBytes_Aes(msg); - await RemoteSocket.SendAsync( - buffer, - WebSocketMessageType.Text, - true, - CancellationToken.None - ); - } public void Close(string? CloseReason) { try { - if (RemoteSocket.State == WebSocketState.Open) - { - RemoteSocket - .CloseAsync( - WebSocketCloseStatus.NormalClosure, - CloseReason, - CancellationToken.None - ) - .Wait(60 * 1000); - } - - if (RemoteSocket.State == WebSocketState.Open) - { - RemoteSocket - .CloseAsync( - WebSocketCloseStatus.NormalClosure, - CloseReason, - CancellationToken.None - ) - .Wait(60 * 1000); - } + Pipe.Close(CloseReason); } catch (Exception e) { @@ -132,7 +79,7 @@ public class RemoteSyncServer } finally { - Factory.RemoveLocalSyncServer(this); + Factory.RemoveSyncServer(this); } } } diff --git a/Server/RemoteServer/RemoteSyncServerFactory.cs b/Server/RemoteServer/RemoteSyncServerFactory.cs index 371f5fb..378236e 100644 --- a/Server/RemoteServer/RemoteSyncServerFactory.cs +++ b/Server/RemoteServer/RemoteSyncServerFactory.cs @@ -1,4 +1,4 @@ -using System.Net.WebSockets; +using Common; namespace RemoteServer; @@ -6,30 +6,35 @@ public class RemoteSyncServerFactory { private readonly object Lock = new(); - public void CreateLocalSyncServer(WebSocket socket, string name) +#pragma warning disable CA2211 // Non-constant fields should not be visible + public static List> NamePwd = []; +#pragma warning restore CA2211 // Non-constant fields should not be visible + + public void CreateRemoteSyncServer(AbsPipeLine pipeLine, string Name) { - if (Servers.Select(x => x.Name == name).Any()) - { - throw new Exception("RemoteServer:存在同名发布源!"); - } - var server = new RemoteSyncServer(socket, name, this); + var pwd = + NamePwd.Where(x => x.Item1 == Name).FirstOrDefault() + ?? throw new Exception("RemoteServer: 不被允许的发布名称!"); + var server = new RemoteSyncServer(pipeLine, this, Name, pwd.Item2); lock (Lock) { Servers.Add(server); } - //脱离当前函数栈 - Task.Run(async ()=>{ - await server.RemoteSocketListen(); - }); } private readonly List Servers = []; - public void RemoveLocalSyncServer(RemoteSyncServer server) + public void RemoveSyncServer(RemoteSyncServer server) { lock (Lock) { Servers.Remove(server); } } + + public RemoteSyncServer? GetServerByName(string name) + { + var it = Servers.Where(x => x.Name == name).FirstOrDefault(); + return it; + } } diff --git a/Server/RemoteServer/StateHelper.cs b/Server/RemoteServer/StateHelper.cs index 48c0364..d991c48 100644 --- a/Server/RemoteServer/StateHelper.cs +++ b/Server/RemoteServer/StateHelper.cs @@ -14,11 +14,11 @@ namespace RemoteServer; // } public abstract class StateHelpBase( - LocalSyncServer context, + RemoteSyncServer context, SyncProcessStep step = SyncProcessStep.Connect ) { - protected readonly LocalSyncServer Context = context; + protected readonly RemoteSyncServer Context = context; protected readonly SyncProcessStep Step = step; @@ -32,19 +32,7 @@ public abstract class StateHelpBase( return new SyncMsg(type, Step, body); } - public void ReceiveLocalMsg(string msg) - { - var syncMsg = - JsonSerializer.Deserialize(msg) - ?? throw new NullReferenceException("msg is null"); - if (syncMsg.Step != Step) - { - throw new Exception("Sync step error!"); - } - HandleLocalMsg(syncMsg); - } - - public void ReceiveRemoteMsg(byte[] bytes) + public bool ReceiveMsg(byte[] bytes) { var msg = AESHelper.DecryptStringFromBytes_Aes(bytes); @@ -55,361 +43,68 @@ public abstract class StateHelpBase( { throw new Exception("Sync step error!"); } - HandleLocalMsg(syncMsg); + HandleMsg(syncMsg); + return true; } - protected abstract void HandleRemoteMsg(SyncMsg msg); - - protected abstract void HandleLocalMsg(SyncMsg msg); + protected abstract void HandleMsg(SyncMsg msg); } /// /// 0. 链接验证 /// /// -public class ConnectAuthorityHelper(LocalSyncServer context) +public class ConnectAuthorityHelper(RemoteSyncServer context) : StateHelpBase(context, SyncProcessStep.Connect) { - // 如果密码错误,那么就直接关闭连接,不会进入这个方法 - protected override void HandleRemoteMsg(SyncMsg msg) + protected override void HandleMsg(SyncMsg msg) { - //将remote的消息传递到前端界面 - Context.LocalSocketSendMsg(msg).Wait(); - //下一步 - var deployHelper = new DeployHelper(Context); - Context.StateHelper = deployHelper; - deployHelper.DeployProcess(); - } - - protected override void HandleLocalMsg(SyncMsg msg) - { - //收到配置文件 - var config = JsonSerializer.Deserialize(msg.Body); - Context.SyncConfig = config; - Context.RemoteSocketConnect().Wait(60 * 1000); - Task.Run(async () => + if (msg.Body == Context.Pwd) { - if (Context.SyncConfig != null) - { - await Context.RemoteSocketSendMsg(CreateMsg(Context.SyncConfig.RemotePwd)); - } - else - { - throw new NullReferenceException("Config is null!"); - } - await Context.RemoteSocketLiten(); - }); - } -} - -/// -/// 1. 执行发布步骤 -/// -/// -public class DeployHelper(LocalSyncServer context) - : StateHelpBase(context, SyncProcessStep.DeployProject) -{ - public void DeployProcess() - { - if (Context.NotNullSyncConfig.IsDeployProject == false) - { - Context.LocalSocketSendMsg(CreateMsg("配置为不发布跳过此步骤")).Wait(); - var h = new DiffFileAndPackHelper(Context); - Context.StateHelper = h; - h.DiffProcess(); + Context.Pipe.SendMsg(CreateMsg("RemoteServer: 密码验证成功!")); } else { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + throw new Exception("密码错误!"); + } + } +} + +public class DiffFileHelper(RemoteSyncServer context) + : StateHelpBase(context, SyncProcessStep.DiffFileAndPack) +{ + protected override void HandleMsg(SyncMsg msg) + { + Context.SyncConfig = JsonSerializer.Deserialize(msg.Body); + //文件对比 + Context.NotNullSyncConfig.DirFileConfigs.ForEach(e => + { + if (e.DirInfo == null) { - ProcessStartInfo startInfo = - new() - { - FileName = "cmd.exe", // The command to execute (can be any command line tool) - Arguments = - $"msdeploy.exe -verb:sync -source:contentPath={Context.NotNullSyncConfig.LocalProjectAbsolutePath} -dest:contentPath={Context.NotNullSyncConfig.LocalRootPath} -disablerule:BackupRule", - // The arguments to pass to the command (e.g., list directory contents) - RedirectStandardOutput = true, // Redirect the standard output to a string - UseShellExecute = false, // Do not use the shell to execute the command - CreateNoWindow = true // Do not create a new window for the command - }; - using Process process = new() { StartInfo = startInfo }; - // Start the process - process.Start(); - - // Read the output from the process - string output = process.StandardOutput.ReadToEnd(); - - // Wait for the process to exit - process.WaitForExit(); - - if (process.ExitCode == 0) - { - Context.LocalSocketSendMsg(CreateMsg("发布成功!")).Wait(); - var h = new DiffFileAndPackHelper(Context); - Context.StateHelper = h; - h.DiffProcess(); - } - else - { - Context.LocalSocketSendMsg(CreateErrMsg(output)).Wait(); - throw new Exception("执行发布错误,错误信息参考上一条消息!"); - } + throw new NullReferenceException("RemoteServer: 发布的文件为空!--这个异常应该永远不会发生~"); } else { - throw new NotSupportedException("只支持windows!"); + var nd = e.DirInfo.Clone(); + nd.ResetRootPath( + Context.NotNullSyncConfig.LocalRootPath, + Context.NotNullSyncConfig.RemoteRootPath + ); + nd.ExtractInfo(e.CherryPicks, e.Excludes); + var diff = e.DirInfo.Diff(nd); + e.DirInfo = diff; } - } - } - - protected override void HandleRemoteMsg(SyncMsg msg) { } - - protected override void HandleLocalMsg(SyncMsg msg) { } -} - -public class DiffFileAndPackHelper(LocalSyncServer context) - : StateHelpBase(context, SyncProcessStep.DiffFileAndPack) -{ - public void DiffProcess() - { - //提取本地文件的信息 - Context.NotNullSyncConfig.DirFileConfigs.ForEach(e => - { - e.LocalDirInfo = new Dir(Context.NotNullSyncConfig.LocalRootPath + e.DirPath); - e.LocalDirInfo.ExtractInfo(e.CherryPicks, e.Excludes); }); - //将配置信息发送到remoteServer - Context - .RemoteSocketSendMsg(CreateMsg(JsonSerializer.Serialize(Context.NotNullSyncConfig))) - .Wait(); - } - - protected override void HandleLocalMsg(SyncMsg msg) { } - - protected override void HandleRemoteMsg(SyncMsg msg) { - - - + //将对比结果发送到Local + Context.Pipe.SendMsg( + CreateMsg(JsonSerializer.Serialize(Context.NotNullSyncConfig.DirFileConfigs)) + ); } } - -// /// -// /// 0. 发布源验证密码 -// /// -// /// -// public class LocalAuthorityState(LocalSyncServer context) : StateHelpBase(context) -// { -// public override void HandleRemoteMsg(SyncMsg? msg) -// { -// throw new NotImplementedException("error usage!"); -// } - -// public override void HandleLocalMsg(SyncMsg? msg) -// { -// if (msg == null) -// { -// return; -// } -// else -// { -// string Pwd = msg.Body; -// if (Pwd == "Xfs1%$@_fdYU.>>") -// { -// Context.LocalSocketSendMsg(new SyncMsg(SyncMsgType.Success, "源服务密码校验成功!")); -// Context.StateHelper = new WaitingConfigInfoState(Context); -// } -// else -// { -// throw new UnauthorizedAccessException("pwd error!"); -// } -// } -// } -// } - -// /// -// /// 1. 获取配置信息,它包含目标的服务器的配置信息 -// /// -// /// -// public class WaitingConfigInfoState(LocalSyncServer context) : StateHelpBase(context) -// { -// public override void HandleRemoteMsg(SyncMsg? msg) { } - -// public override void HandleLocalMsg(SyncMsg? msg) -// { -// if (msg == null) -// { -// return; -// } -// else -// { -// string ConfigInfo = msg.Body; -// Context.SyncConfig = -// JsonSerializer.Deserialize(ConfigInfo) -// ?? throw new NullReferenceException("ConfigInfo is null"); -// var task = Context.RemoteSocket.ConnectAsync( -// new Uri(Context.SyncConfig.RemoteUrl), -// CancellationToken.None -// ); -// if (task.Wait(10000)) -// { -// if (Context.RemoteSocket.State == WebSocketState.Open) -// { -// var state = new RemoteAuthorityState(Context); -// state.SendPwdToRemoteServer(); -// Context.StateHelper = state; -// } -// else -// { -// throw new Exception("connect remote server failed!"); -// } -// } -// else -// { -// throw new TimeoutException("connect remote server timeout"); -// } -// } -// } -// } - -// /// -// /// 2. 目标服务器权限校验 -// /// -// /// -// public class RemoteAuthorityState(LocalSyncServer context) : StateHelpBase(context) -// { -// public override void HandleRemoteMsg(SyncMsg? msg) -// { -// if (msg == null) -// { -// return; -// } -// else -// { -// if (msg.Type == SyncMsgType.Success) -// { -// Context.LocalSocketSendMsg(new SyncMsg(SyncMsgType.Success, "远程服务器校验成功!")); -// var diffState = new DirFilesDiffState(Context); -// diffState.SendSyncConfigToRemote(); -// Context.StateHelper = diffState; -// } -// else -// { -// throw new Exception("远程服务器权限校验失败,请检查Local Server 的Mac地址是否在 Remote Server 的允许列表内!"); -// } -// } -// } - -// public override void HandleLocalMsg(SyncMsg? msg) { } - -// public void SendPwdToRemoteServer() -// { -// var authorityInfo = new -// { -// Pwd = "xfs@#123hd??1>>|12#4", -// MacAdr = new LocalServer.Controllers.LocalServerController( -// Context.Factory -// ).GetMacAddress() -// }; -// Context.RemoteSocketSendMsg(authorityInfo); -// } -// } - -// /// -// /// 3. 文件比较 -// /// -// /// -// public class DirFilesDiffState(LocalSyncServer context) : StateHelpBase(context) -// { -// public override void HandleRemoteMsg(SyncMsg? msg) -// { -// if (msg == null) -// { -// return; -// } -// else -// { -// if (msg.IsSuccess) -// { -// var state = new LocalPackAndUploadState(Context); -// state.PackDiffDir(msg); -// Context.StateHelper = state; -// } -// else -// { -// throw new Exception(msg.Body); -// } -// } -// } - -// public override void HandleLocalMsg(SyncMsg? msg) { } - -// public void SendSyncConfigToRemote() -// { -// Context.RemoteSocketSendMsg( -// Context.SyncConfig -// ?? throw new NullReferenceException("SyncConfig should't be null here!") -// ); -// } -// } - -// /// -// /// 4. 本地打包并上传 -// /// -// /// -// public class LocalPackAndUploadState(LocalSyncServer context) : StateHelpBase(context) -// { -// public override void HandleRemoteMsg(SyncMsg? msg) -// { -// if (msg == null) -// { -// return; -// } -// else { } -// } - -// public override void HandleLocalMsg(SyncMsg? msg) { } - -// /// -// /// 打包文件 -// /// -// /// -// /// -// public void PackDiffDir(SyncMsg msg) -// { -// if (msg.IsSuccess) -// { -// var diff = JsonSerializer.Deserialize(msg.Body); - -// Context.LocalSocketSendMsg(new SyncMsg(SyncMsgType.Success, "文件打包完成!")); -// Context.LocalSocketSendMsg(new SyncMsg(SyncMsgType.Success, "文件上传完成!")); -// } -// else -// { -// throw new Exception(msg.Body); -// } -// } - -// private void UploadPackedFiles(string absolutePath) -// { -// //TODO 传递上传进度到前端。 -// } -// } - -// /// -// /// 5. 目标服务器解包并发布 -// /// -// /// -// public class RemoteUnPackAndReleaseState(LocalSyncServer context) : StateHelpBase(context) -// { -// public override void HandleRemoteMsg(SyncMsg? msg) -// { -// if (msg == null) -// { -// return; -// } -// else { } -// } - -// public override void HandleLocalMsg(SyncMsg? msg) { } -// } +public class UnPackFilesHelper(RemoteSyncServer context):StateHelpBase(context,SyncProcessStep.UploadAndUnpack) +{ + protected override void HandleMsg(SyncMsg msg) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/Server/RemoteServer/appsettings.json b/Server/RemoteServer/appsettings.json index dd1402f..39282a4 100644 --- a/Server/RemoteServer/appsettings.json +++ b/Server/RemoteServer/appsettings.json @@ -8,5 +8,9 @@ "Microsoft.AspNetCore": "Warning" } }, - "AllowedHosts": "*" -} \ No newline at end of file + "AllowedHosts": "*", + "TempDir":"D:/TempPack2", + "NamePwds":[ + ["test","testpwd"] + ] +}