FileSqlServerSync/Server/RemoteServer/StateHelper.cs

216 lines
7 KiB
C#
Raw Normal View History

2024-09-05 01:59:57 +00:00
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
2024-09-05 01:59:57 +00:00
using System.Text.Json;
using Common;
namespace RemoteServer;
// enum StateWhenMsg
// {
// Authority = 0,
// ConfigInfo = 1,
// LocalPackAndUpload = 2,
// RemoteUnPackAndRelease = 3,
// }
public abstract class StateHelpBase(
RemoteSyncServer context,
2024-09-05 01:59:57 +00:00
SyncProcessStep step = SyncProcessStep.Connect
)
{
protected readonly RemoteSyncServer Context = context;
2024-09-05 01:59:57 +00:00
protected readonly SyncProcessStep Step = step;
2024-09-05 01:59:57 +00:00
public SyncMsg CreateErrMsg(string Body)
{
return new SyncMsg
{
Body = Body,
Type = SyncMsgType.Error,
Step = Step
};
2024-09-05 01:59:57 +00:00
}
public SyncMsg CreateMsg(string body, SyncMsgType type = SyncMsgType.General)
{
return new SyncMsg
{
Body = body,
Type = type,
Step = Step
};
2024-09-05 01:59:57 +00:00
}
public bool ReceiveMsg(byte[] bytes)
2024-09-05 01:59:57 +00:00
{
var msg = Encoding.UTF8.GetString(bytes);
2024-09-05 01:59:57 +00:00
var syncMsg =
JsonSerializer.Deserialize<SyncMsg>(msg)
?? throw new NullReferenceException("msg is null");
if (syncMsg.Step != Step)
{
throw new Exception("Sync step error!");
}
HandleMsg(syncMsg);
return true;
2024-09-05 01:59:57 +00:00
}
protected abstract void HandleMsg(SyncMsg msg);
2024-09-05 01:59:57 +00:00
}
/// <summary>
/// 0. 链接验证
/// </summary>
/// <param name="context"></param>
public class ConnectAuthorityHelper(RemoteSyncServer context)
2024-09-05 01:59:57 +00:00
: StateHelpBase(context, SyncProcessStep.Connect)
{
protected override void HandleMsg(SyncMsg msg)
2024-09-05 01:59:57 +00:00
{
if (msg.Body == Context.Pwd)
2024-09-05 01:59:57 +00:00
{
var h = new DiffFileHelper(Context);
Context.StateHelper = h;
Context.Pipe.SendMsg(CreateMsg("RemoteServer: 密码验证成功!"));
}
else
{
throw new Exception("密码错误!");
}
2024-09-05 01:59:57 +00:00
}
}
public class DiffFileHelper(RemoteSyncServer context)
: StateHelpBase(context, SyncProcessStep.DiffFileAndPack)
2024-09-05 01:59:57 +00:00
{
protected override void HandleMsg(SyncMsg msg)
2024-09-05 01:59:57 +00:00
{
Context.SyncConfig = JsonSerializer.Deserialize<Config>(msg.Body);
2024-09-22 05:27:52 +00:00
var diffConfigs = new List<DirFileConfig>();
//文件对比
Context.NotNullSyncConfig.DirFileConfigs.ForEach(e =>
2024-09-05 01:59:57 +00:00
{
if (e.LocalDirInfo == null)
2024-09-05 01:59:57 +00:00
{
throw new NullReferenceException("RemoteServer: 发布的文件为空!--这个异常应该永远不会发生~");
2024-09-05 01:59:57 +00:00
}
else
{
var nd = e.LocalDirInfo.Clone();
nd.ResetRootPath(
Context.NotNullSyncConfig.LocalRootPath,
Context.NotNullSyncConfig.RemoteRootPath
);
nd.ExtractInfo(e.CherryPicks, e.Excludes);
e.DiffDirInfo = nd.Diff(nd);
e.RemoteDirInfo = nd;
diffConfigs.Add(
new DirFileConfig { DiffDirInfo = e.DiffDirInfo, DirPath = e.DirPath }
2024-09-22 05:27:52 +00:00
);
2024-09-05 01:59:57 +00:00
}
});
var h = new UnPackAndReleaseHelper(Context);
Context.StateHelper = h;
//将对比结果发送到Local
Context.Pipe.SendMsg(CreateMsg(JsonSerializer.Serialize(diffConfigs)));
2024-09-22 05:27:52 +00:00
}
}
public class UnPackAndReleaseHelper(RemoteSyncServer context)
: StateHelpBase(context, SyncProcessStep.UploadAndUnpack)
{
public void UnPack()
{
FileDirOpForUnpack.FirstUnComparess(
Path.Combine(RemoteSyncServer.TempRootFile, Context.NotNullSyncConfig.Id.ToString()),
Context.NotNullSyncConfig.Id.ToString()
);
2024-09-22 05:27:52 +00:00
Context.Pipe.SendMsg(CreateMsg("解压完成!")).Wait();
var h = new FinallyPublishHelper(Context);
Context.StateHelper = h;
h.FinallyPublish();
2024-09-05 01:59:57 +00:00
}
2024-09-22 05:27:52 +00:00
protected override void HandleMsg(SyncMsg msg) { }
2024-09-05 01:59:57 +00:00
}
2024-09-22 05:27:52 +00:00
public class FinallyPublishHelper(RemoteSyncServer context)
: StateHelpBase(context, SyncProcessStep.Publish)
2024-09-05 01:59:57 +00:00
{
2024-09-22 05:27:52 +00:00
public void FinallyPublish()
2024-09-05 01:59:57 +00:00
{
2024-09-22 05:27:52 +00:00
// 发布数据库
if (Context.NotNullSyncConfig.IsDeployDb)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
var arguments =
$"/Action:Publish /SourceFile: {RemoteSyncServer.TempRootFile}/{Context.NotNullSyncConfig.Id}/{Context.NotNullSyncConfig.Id}.dacpac "
2024-09-22 05:27:52 +00:00
+ $"/TargetServerName:{Context.NotNullSyncConfig.DstDb.ServerName} /TargetDatabaseName:{Context.NotNullSyncConfig.DstDb.DatebaseName}"
+ $" /TargetUser:{Context.NotNullSyncConfig.DstDb.User} /TargetPassword:{Context.NotNullSyncConfig.DstDb.Password} /TargetTrustServerCertificate:True ";
ProcessStartInfo startInfo =
new()
{
FileName = "SqlPackage", // The command to execute (can be any command line tool)
2024-09-22 05:27:52 +00:00
Arguments = arguments,
// 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.Pipe.SendMsg(CreateMsg("数据库发布成功!")).Wait();
}
else
{
Context.Pipe.SendMsg(CreateErrMsg(output)).Wait();
throw new Exception("执行发布错误,错误信息参考上一条消息!");
}
}
else
{
throw new NotSupportedException("只支持windows!");
}
}
else
{
Context.Pipe.SendMsg(CreateMsg("跳过数据库发布!")).Wait();
}
var DirFileOp = new FileDirOpForUnpack(
Path.Combine(
RemoteSyncServer.TempRootFile,
Context.NotNullSyncConfig.Id.ToString(),
Context.NotNullSyncConfig.Id.ToString()
),
Context.NotNullSyncConfig.RemoteRootPath
);
Context.NotNullSyncConfig.DirFileConfigs.ForEach(e =>
2024-09-22 05:27:52 +00:00
{
if (e.RemoteDirInfo != null && e.DiffDirInfo != null)
{
e.RemoteDirInfo.Combine(DirFileOp, e.DiffDirInfo,false,true);
}
});
2024-09-22 05:27:52 +00:00
Context.Pipe.SendMsg(CreateMsg("发布完成!")).Wait();
2024-09-05 01:59:57 +00:00
}
2024-09-22 05:27:52 +00:00
protected override void HandleMsg(SyncMsg msg) { }
}