From ca6795d31f43574b2cc2d44ff9de26c095d3982d Mon Sep 17 00:00:00 2001
From: zerlei <1445089819@qq.com>
Date: Sat, 12 Oct 2024 14:30:56 +0800
Subject: [PATCH] =?UTF-8?q?style:=20=E4=BF=AE=E6=94=B9=E4=BA=86=E4=BB=A3?=
=?UTF-8?q?=E7=A0=81=E6=A0=BC=E5=BC=8F=EF=BC=8C=E5=88=A0=E6=8E=89=E4=BA=86?=
=?UTF-8?q?=E4=B8=80=E4=BA=9B=E6=97=A0=E7=94=A8=E7=9A=84=E4=BB=A3=E7=A0=81?=
=?UTF-8?q?=EF=BC=8C=E6=B7=BB=E5=8A=A0=E4=BA=86=E4=B8=80=E4=BA=9B=E6=B3=A8?=
=?UTF-8?q?=E9=87=8A?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Server/Common/Config.cs | 15 +-
Server/Common/ConnectPipeline.cs | 58 +-
Server/Common/DirExtension.cs | 297 ++-----
Server/Common/FileDirBase.cs | 30 +-
Server/Common/FileDirOp.cs | 732 +++++++++---------
.../Controllers/LocalServerController.cs | 63 +-
Server/LocalServer/LocalSyncServer.cs | 103 ++-
Server/LocalServer/StateHelper.cs | 323 +-------
.../Controllers/RemoteServerController.cs | 248 +++---
Server/RemoteServer/Program.cs | 4 -
.../RemoteServer/RemoteSyncServerFactory.cs | 4 +
Server/RemoteServer/StateHelper.cs | 14 -
Server/ServerTest/PipeTest.cs | 126 +--
Server/ServerTest/TestPipe.cs | 4 +-
14 files changed, 815 insertions(+), 1206 deletions(-)
diff --git a/Server/Common/Config.cs b/Server/Common/Config.cs
index a206c47..040ee29 100644
--- a/Server/Common/Config.cs
+++ b/Server/Common/Config.cs
@@ -3,7 +3,7 @@ namespace Common;
public class DirFileConfig
{
///
- /// 相对路径
+ /// 相对路径,与根路径拼成一个完整的路径,注意 "/" 不要缺少
///
public required string DirPath { get; set; }
@@ -17,9 +17,17 @@ public class DirFileConfig
///
public List? CherryPicks { get; set; }
- ///
+ ///
+ /// 本地文件信息,也是即将发布的文件信息,通常是最新的版本
+ ///
public Dir? LocalDirInfo { get; set; }
+ ///
+ /// 差异文件信息
+ ///
public Dir? DiffDirInfo { get; set; }
+ ///
+ /// 远程文件信息,通常是较旧的版本
+ ///
public Dir? RemoteDirInfo { get; set; }
}
@@ -63,6 +71,9 @@ public class Config
///
public required string Name { get; set; }
+ ///
+ /// 本次发布的唯一id
+ ///
public Guid Id { get; set; } = Guid.NewGuid();
///
diff --git a/Server/Common/ConnectPipeline.cs b/Server/Common/ConnectPipeline.cs
index 144c0a2..7c3626b 100644
--- a/Server/Common/ConnectPipeline.cs
+++ b/Server/Common/ConnectPipeline.cs
@@ -6,28 +6,52 @@ namespace Common;
public abstract class AbsPipeLine(bool isAES)
{
+
+ ///
+ /// pipeLine工作函数,生效期间永久阻塞
+ ///
+ /// 回调函数,从pipeline接收到的消息
+ /// 连接的远程地址
+ /// 第一次返回连接信息,第二次当pipeline 被断开时返回,此时可能是正常完成断开,或异常发生断开
public abstract IAsyncEnumerable Work(Func receiveCb, string addr = "");
protected Func ReceiveMsg = (byte[] a) =>
{
return true;
};
+ ///
+ /// 监听pipeline 消息,由Work 函数调用
+ ///
+ /// 消息回调
+ ///
protected abstract Task Listen(Func receiveCb);
///
/// 关闭连接
///
- ///
+ /// 关闭原因
///
public abstract Task Close(string? CloseReason);
///
- /// 发送消息
+ /// 向管道中发送消息
///
///
///
public abstract Task SendMsg(SyncMsg msg);
+ ///
+ /// 打包文件上传
+ ///
+ /// 上传地址
+ /// 上传的文件路径
+ /// 上传进度回调(现在没有回调)
+ /// 上传完成时返回/
public abstract Task UploadFile(string url, string filePath, Func progressCb);
+
+
+ ///
+ /// 管道消息是否使用AES加密
+ ///
protected readonly bool IsAES = isAES;
}
@@ -42,16 +66,16 @@ public class WebSocPipeLine(TSocket socket, bool isAES) : AbsPipeLine(i
Func progressCb
)
{
- //throw new Exception("sdfsdf");
using var client = new HttpClient();
using var content = new MultipartFormDataContent();
using var fileStream = new FileStream(filePath, FileMode.Open);
- var progress = new Progress(
- (current) =>
- {
- progressCb(current);
- }
- );
+ // TODO 上传进度回调
+ // var progress = new Progress(
+ // (current) =>
+ // {
+ // progressCb(current);
+ // }
+ // );
//var fileContent = new ProgressStreamContent(fileStream, progress);
content.Add(new StreamContent(fileStream), "file", Path.GetFileName(filePath));
var it = await client.PostAsync("http://" + url + "/UploadFile", content);
@@ -80,7 +104,7 @@ public class WebSocPipeLine(TSocket socket, bool isAES) : AbsPipeLine(i
protected override async Task Listen(Func receiveCb)
{
- //最大1MB!=
+ //warning 最大支持1MB,这由需要同步的文件数量大小决定 UTF-8 每个字符,汉字视为4个字节,数字1个 ,英文字母2个。1MB=256KB*4,25万个字符能描述就行
var buffer = new byte[1024 * 1024];
while (Socket.State == WebSocketState.Open)
@@ -100,8 +124,6 @@ public class WebSocPipeLine(TSocket socket, bool isAES) : AbsPipeLine(i
System.Buffer.BlockCopy(buffer, 0, nbuffer, 0, receiveResult.Count);
if (IsAES)
{
- //var msg1 = Encoding.UTF8.GetString(nbuffer);
- //var n1Buffler = Encoding.UTF8.GetBytes(msg1);
var nnbuffer = AESHelper.DecryptStringFromBytes_Aes(nbuffer);
receiveCb(Encoding.UTF8.GetBytes(nnbuffer));
}
@@ -117,14 +139,8 @@ public class WebSocPipeLine(TSocket socket, bool isAES) : AbsPipeLine(i
{
if (Socket.State == WebSocketState.Open)
{
- //await SendMsg(
- // new SyncMsg
- // {
- // Type = SyncMsgType.Error,
- // Step = SyncProcessStep.Finally,
- // Body = CloseReason ?? ""
- // }
- //);
+ //CloseReason 最大不能超过123bytes.https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close
+ //若传递超过这个限制,此处表现WebSocket将会卡住,无法关闭。
if (Encoding.UTF8.GetBytes(CloseReason ?? "").Length > 120)
{
await SendMsg(
@@ -156,9 +172,9 @@ public class WebSocPipeLine(TSocket socket, bool isAES) : AbsPipeLine(i
{
string msgStr = JsonSerializer.Serialize(msg);
var it = AESHelper.EncryptStringToBytes_Aes(msgStr);
- //var xx = new ArraySegment(it);
if (IsAES)
{
+ // 加密后的字符,使用Binary 发送,加密通常不会发送到最前端,通常是 js 写的websocket
await Socket.SendAsync(
new ArraySegment(it),
WebSocketMessageType.Binary,
diff --git a/Server/Common/DirExtension.cs b/Server/Common/DirExtension.cs
index 8d9d27b..d7d4cfe 100644
--- a/Server/Common/DirExtension.cs
+++ b/Server/Common/DirExtension.cs
@@ -1,5 +1,8 @@
namespace Common;
+///
+/// Dir比较方法
+///
public static class DirExtension
{
///
@@ -248,6 +251,13 @@ public static class DirExtension
return cDir;
}
+
+ ///
+ /// 根据Dirobject记录的信息,写入磁盘
+ ///
+ ///
+ /// 文件操作类,它是如何写入文件的方法
+ ///
public static void WriteByThisInfo(this Dir thisDir, FileDirOpStra fileDirOp)
{
static void f(Dir dir, FileDirOpStra fileDirOp)
@@ -285,6 +295,13 @@ public static class DirExtension
f(thisDir, fileDirOp);
}
+ ///
+ /// 从文件夹中提取文件信息
+ ///
+ ///
+ /// 只提取这些信息,最高级别
+ /// 忽略这些文件信息
+ ///
public static void ExtractInfo(
this Dir thisDir,
List? cherryPicks = null,
@@ -334,7 +351,12 @@ public static class DirExtension
}
}
}
-
+ ///
+ /// 添加一个子对象,这个不包含文件或文件夹的创建
+ ///
+ ///
+ ///
+ ///
public static void AddChild(this Dir thisDir, AFileOrDir child)
{
if (child.FormatedPath[..thisDir.FormatedPath.Length] != thisDir.FormatedPath)
@@ -371,6 +393,16 @@ public static class DirExtension
}
}
+
+ ///
+ /// 合并diffdir中的内容
+ ///
+ ///
+ ///
+ /// 是否更新对象
+ /// 是否更新文件夹和文件
+ ///
+ ///
public static void Combine(
this Dir thisDir,
FileDirOpStra? fileDirOp,
@@ -495,6 +527,14 @@ public static class DirExtension
}
}
+ ///
+ /// clone一个新的对象
+ ///
+ ///
+ /// 重设的操作类型
+ /// 是否重设操作类型
+ ///
+ ///
public static Dir Clone(
this Dir thisDir,
NextOpType? optype = null,
@@ -536,6 +576,13 @@ public static class DirExtension
return ndir;
}
+ ///
+ /// 改变根路径位置
+ ///
+ ///
+ ///
+ ///
+ ///
public static Dir ResetRootPath(this Dir thisDir, string oldPath, string newPath)
{
thisDir.FormatedPath = thisDir.FormatedPath.Replace(oldPath, newPath);
@@ -553,6 +600,10 @@ public static class DirExtension
return thisDir;
}
+ ///
+ /// 文件操作权限检查(废弃)
+ ///
+ ///
public static void AccessCheck(this Dir thisDir)
{
//不是核心关注点,下面实现有bug。不校验所有文件夹权限,创建时会抛出错误,此时手动处理吧。
@@ -639,247 +690,3 @@ public static class DirExtension
//});
}
}
-
-///
-/// 文件夹结构,它包含文件和文件夹
-///
-/// 绝对路径
-/// 子文件或文件夹
-// public class Dirxx(string path, List? children = null, NextOpType? nextOp = null)
-// : AFileOrDir(path, DirOrFile.Dir, nextOp)
-// {
-// public List Children { get; set; } = children ?? [];
-
-/* public override bool IsEqual(AFileOrDir other)
-{
- if (other is not Dir otherDir)
- {
- return false;
- }
- else
- {
- if (this.FormatedPath != otherDir.FormatedPath || this.NextOp != otherDir.NextOp)
- {
- return false;
- }
- if (this.Children.Count != otherDir.Children.Count)
- {
- return false;
- }
- this.Children.Sort(AFileOrDir.Compare);
- otherDir.Children.Sort(AFileOrDir.Compare);
- for (int i = 0; i < this.Children.Count; i++)
- {
- if (!this.Children[i].IsEqual(otherDir.Children[i]))
- {
- return false;
- }
- }
- return true;
- }
-} */
-
-///
-/// clone, 但是更改根目录
-///
-/// 操作步骤
-/// 旧根路径
-/// 新根路径
-/// 是否重置下步操作
-///
-// public Dir Clone(
-// NextOpType? optype,
-// string oldRootPath,
-// string newRootPath,
-// bool IsResetNextOpType = false
-// )
-// {
-// var ndir = this.Clone(optype, IsResetNextOpType);
-// ndir.ResetRootPath(oldRootPath, newRootPath);
-// return ndir;
-// }
-
-///
-/// clone,不克隆文件
-///
-///
-///
-///
-///
-// public Dir Clone(NextOpType? optype = null, bool IsResetNextOpType = false) { }
-
-///
-/// 重设置根目录
-///
-///
-///
-// public void ResetRootPath(string oldPath, string newPath)
-// {
-// this.FormatedPath = this.FormatedPath.Replace(oldPath, newPath);
-// this.Children.ForEach(e =>
-// {
-// if (e is File file)
-// {
-// file.FormatedPath = file.FormatedPath.Replace(oldPath, newPath);
-// }
-// else if (e is Dir dir)
-// {
-// dir.ResetRootPath(oldPath, newPath);
-// }
-// });
-// }
-
-///
-/// 文件夹合并
-///
-/// 具体操作步骤
-/// 将要更新的内容
-/// 是否更新Object对象
-/// 是否更新文件目录树
-///
-// public void Combine(
-// FileDirOpStra? fileDirOp,
-// Dir diffdir,
-// bool IsUpdateObject = true,
-// bool IsUpdateDirFile = false
-// ) { }
-
-// ///
-// /// 合并两个文件夹,other不会发生改变,this将合并一个副本,这不会改变文件结构
-// ///
-// /// 它的一个clone将被合并的dir,它的NextOp 不应该是空,否则什么都不会发生
-// ///
-// public void CombineJustObject(Dir other)
-// {
-// Combine(null, other, true, false);
-// }
-
-// ///
-// /// 合并两个文件夹,other不会发生改变,this将不会改变,而文件结构会改变
-// ///
-// /// 它的一个clone将被合并的dir,它的NextOp 不应该是空,否则什么都不会发生
-// ///
-// public void CombineJustDirFile(FileDirOpStra fileDirOp, Dir diffDir)
-// {
-// Combine(fileDirOp, diffDir, false, true);
-// }
-
-// ///
-// /// 添加子节点,根目录相同,才会被添加进去
-// ///
-// ///
-// /// /
-// protected void AddChild(AFileOrDir child) { }
-
-// ///
-// /// 从文件夹中提取信息
-// ///
-// /// 绝对路径,只包含的文件或者目录
-// /// 绝对路径,排除的文件或目录
-// ///
-
-
-// ///
-// /// 写入目录文件树,首先必须定义写入文件的策略,此目录结构不包含文件内容,但有一个
-// /// 文件的修改时间,是否修改文件的修改时间,需要定义文件的写入策略 WriteFileStrageFunc
-// ///
-// ///
-
-
-// ///
-// /// 校验文件夹和文件权限
-// ///
-// // private void AccessCheck()j
-// // {
-// //不是核心关注点,下面实现有bug。不校验所有文件夹权限,创建时会抛出错误,此时手动处理吧。
-// // return;
-// //this.Children.ForEach(e =>
-// //{
-// // if (e is File file)
-// // {
-// // if (file.NextOp == null) { }
-// // else if (file.NextOp == NextOpType.Add)
-// // {
-// // if (
-// // !AccessWrapper.CheckDirAccess(
-// // Path.GetDirectoryName(file.FormatedPath)
-// // ?? throw new DirectoryNotFoundException(
-// // $"{file.FormatedPath} 此父路径不存在"
-// // ),
-// // [DirAcess.CreateFiles]
-// // )
-// // )
-// // {
-// // throw new UnauthorizedAccessException($"{file.FormatedPath} 无权限创建文件");
-// // }
-// // }
-// // else if (file.NextOp == NextOpType.Modify)
-// // {
-// // if (
-// // !(
-// // AccessWrapper.CheckFileAccess(file.FormatedPath, [FileAccess.Delete])
-// // && AccessWrapper.CheckDirAccess(
-// // Path.GetDirectoryName(file.FormatedPath)
-// // ?? throw new DirectoryNotFoundException(
-// // $"{file.FormatedPath} 此父路径不存在"
-// // ),
-// // [DirAcess.CreateFiles]
-// // )
-// // )
-// // )
-// // {
-// // throw new UnauthorizedAccessException(
-// // $"{file.FormatedPath} 无权限删除源文件或者创建新文件"
-// // );
-// // }
-// // }
-// // else if (file.NextOp == NextOpType.Del)
-// // {
-// // if (!AccessWrapper.CheckFileAccess(file.FormatedPath, [FileAccess.Delete]))
-// // {
-// // throw new UnauthorizedAccessException($"{file.FormatedPath} 无权限删除源文件");
-// // }
-// // }
-// // }
-// // else if (e is Dir dir)
-// // {
-// // if (dir.NextOp == null) { }
-// // else if (dir.NextOp == NextOpType.Add)
-// // {
-// // if (
-// // !AccessWrapper.CheckDirAccess(
-// // Path.GetDirectoryName(dir.FormatedPath)
-// // ?? throw new DirectoryNotFoundException(
-// // $"{dir.FormatedPath} 此父路径不存在"
-// // ),
-// // [DirAcess.CreateDirectories, DirAcess.CreateFiles]
-// // )
-// // )
-// // {
-// // throw new UnauthorizedAccessException($"{dir.FormatedPath} 无权限创建文件夹或者文件");
-// // }
-// // }
-// // else if (dir.NextOp == NextOpType.Del)
-// // {
-// // if (!AccessWrapper.CheckDirAccess(dir.FormatedPath, [DirAcess.Delete]))
-// // {
-// // throw new UnauthorizedAccessException($"{dir.FormatedPath} 无权限删除文件夹");
-// // }
-// // else
-// // {
-// // //校验是否拥有子文件或者文件夹的删除权限,
-// // dir.AccessCheck();
-// // }
-// // }
-// // }
-// //});
-// // }
-
-// ///
-// /// 比较两个目录文件树是否相同,不相同返回差异部分,左侧是右侧的下一个版本,任何一个节点的nextop != null,即所有
-// /// 节点都会打上标记
-// /// 文件夹的 NextOp 只有新增和删除
-// ///
-// ///
-// ///
-// }
diff --git a/Server/Common/FileDirBase.cs b/Server/Common/FileDirBase.cs
index 8fa825f..2b3a788 100644
--- a/Server/Common/FileDirBase.cs
+++ b/Server/Common/FileDirBase.cs
@@ -39,10 +39,10 @@ public class AFileOrDir
set { Path = value; }
}
- public bool IsEqual(AFileOrDir other)
- {
- return false;
- }
+ // public bool IsEqual(AFileOrDir other)
+ // {
+ // return false;
+ // }
public static int Compare(AFileOrDir l, AFileOrDir r)
{
@@ -69,7 +69,7 @@ public class File : AFileOrDir
public required DateTime MTime { get; set; }
- public new bool IsEqual(AFileOrDir other)
+ public bool IsEqual(AFileOrDir other)
{
if (other is not File otherFile)
{
@@ -96,7 +96,7 @@ public class Dir : AFileOrDir
public required List Children { get; set; }
- public new bool IsEqual(AFileOrDir other)
+ public bool IsEqual(AFileOrDir other)
{
if (other is not Dir otherDir)
{
@@ -116,7 +116,23 @@ public class Dir : AFileOrDir
otherDir.Children.Sort(AFileOrDir.Compare);
for (int i = 0; i < this.Children.Count; i++)
{
- if (!this.Children[i].IsEqual(otherDir.Children[i]))
+ var l = this.Children[i];
+ var r = otherDir.Children[i];
+ if (l is Dir ld && r is Dir rd)
+ {
+ if (!ld.IsEqual(rd))
+ {
+ return false;
+ }
+ }
+ else if (l is File lf && r is File rf)
+ {
+ if (!lf.IsEqual(rf))
+ {
+ return false;
+ }
+ }
+ else
{
return false;
}
diff --git a/Server/Common/FileDirOp.cs b/Server/Common/FileDirOp.cs
index 68cd78e..26ba936 100644
--- a/Server/Common/FileDirOp.cs
+++ b/Server/Common/FileDirOp.cs
@@ -321,391 +321,391 @@ public class FileDirOpForUnpack(string srcRootPath, string dstRootPath) : FileDi
}
}
-///
-/// 文件目录权限校验
-///
-public class FileDirOpForAccessCheck : FileDirOpStra
-{
- public override void FileCreate(string absolutePath, DateTime mtime)
- {
- throw new NotImplementedException();
- }
+// ///
+// /// 文件目录权限校验
+// ///
+// public class FileDirOpForAccessCheck : FileDirOpStra
+// {
+// public override void FileCreate(string absolutePath, DateTime mtime)
+// {
+// throw new NotImplementedException();
+// }
- public override void DirCreate(Dir dir, bool IsRecursion = true)
- {
- throw new NotImplementedException();
- }
+// public override void DirCreate(Dir dir, bool IsRecursion = true)
+// {
+// throw new NotImplementedException();
+// }
- public override void FileModify(string absolutePath, DateTime mtime)
- {
- throw new NotImplementedException();
- }
+// public override void FileModify(string absolutePath, DateTime mtime)
+// {
+// throw new NotImplementedException();
+// }
- public override void FileDel(string absolutePath)
- {
- throw new NotImplementedException();
- }
+// public override void FileDel(string absolutePath)
+// {
+// throw new NotImplementedException();
+// }
- public override void DirDel(Dir dir, bool IsRecursion = true)
- {
- throw new NotImplementedException();
- }
-}
+// public override void DirDel(Dir dir, bool IsRecursion = true)
+// {
+// throw new NotImplementedException();
+// }
+// }
-public enum FileAccess
-{
- Read,
- Write,
- Delete,
- Execute
-}
+// public enum FileAccess
+// {
+// Read,
+// Write,
+// Delete,
+// Execute
+// }
-public enum DirAcess
-{
- ///
- /// 读取权限
- ///
- Read,
+// public enum DirAcess
+// {
+// ///
+// /// 读取权限
+// ///
+// Read,
- ///
- /// 写入权限
- ///
- Write,
+// ///
+// /// 写入权限
+// ///
+// Write,
- ///
- /// 列出文件夹权限
- ///
- ListDirectory,
+// ///
+// /// 列出文件夹权限
+// ///
+// ListDirectory,
- ///
- /// 创建文件权限
- ///
- CreateFiles,
+// ///
+// /// 创建文件权限
+// ///
+// CreateFiles,
- ///
- /// 创建文件夹权限
- ///
- CreateDirectories,
+// ///
+// /// 创建文件夹权限
+// ///
+// CreateDirectories,
- ///
- /// 删除文件权限
- ///
- Delete,
+// ///
+// /// 删除文件权限
+// ///
+// Delete,
- ///
- /// 删除文件夹及其子文件
- ///
- DeleteSubdirectoriesAndFiles,
-}
+// ///
+// /// 删除文件夹及其子文件
+// ///
+// DeleteSubdirectoriesAndFiles,
+// }
-///
-/// 运行此软件的用户与目标软件的用户最好是 一个用户,一个用户组,或者运行此软件的用户具备最高权限。
-///
-public class AccessWrapper
-{
- ///
- ///
- ///
- ///
- public static void FreeThisDirAccess(string absolutePath)
- {
- if (
- CheckDirAccess(
- absolutePath,
- [
- DirAcess.Read,
- DirAcess.Write,
- DirAcess.Delete,
- DirAcess.ListDirectory,
- DirAcess.CreateFiles,
- DirAcess.CreateDirectories,
- DirAcess.DeleteSubdirectoriesAndFiles
- ]
- )
- ) { }
- else
- {
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- DirectoryInfo dirInfo = new(absolutePath);
- //获得该文件的访问权限
- var dirSecurity = dirInfo.GetAccessControl();
- //设定文件ACL继承
- InheritanceFlags inherits =
- InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit;
+// ///
+// /// 运行此软件的用户与目标软件的用户最好是 一个用户,一个用户组,或者运行此软件的用户具备最高权限。
+// ///
+// public class AccessWrapper
+// {
+// ///
+// ///
+// ///
+// ///
+// public static void FreeThisDirAccess(string absolutePath)
+// {
+// if (
+// CheckDirAccess(
+// absolutePath,
+// [
+// DirAcess.Read,
+// DirAcess.Write,
+// DirAcess.Delete,
+// DirAcess.ListDirectory,
+// DirAcess.CreateFiles,
+// DirAcess.CreateDirectories,
+// DirAcess.DeleteSubdirectoriesAndFiles
+// ]
+// )
+// ) { }
+// else
+// {
+// if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+// {
+// DirectoryInfo dirInfo = new(absolutePath);
+// //获得该文件的访问权限
+// var dirSecurity = dirInfo.GetAccessControl();
+// //设定文件ACL继承
+// InheritanceFlags inherits =
+// InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit;
- var cUser =
- (
- WindowsIdentity.GetCurrent().Groups
- ?? throw new Exception("GetWindowsIdentity failed. 你需要手动处理发布内容!--检查权限!")
- ).FirstOrDefault() ?? throw new NullReferenceException("can't be null");
- FileSystemAccessRule MdfRule =
- new(
- cUser,
- FileSystemRights.Modify,
- inherits,
- PropagationFlags.InheritOnly,
- AccessControlType.Allow
- );
- if (dirSecurity.ModifyAccessRule(AccessControlModification.Set, MdfRule, out _)) { }
- else
- {
- throw new Exception("AddAccessRule failed. 你需要手动处理发布内容!--检查权限!");
- }
- //设置访问权限
- dirInfo.SetAccessControl(dirSecurity);
- }
- else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
- {
- //TODO Linux文件权限
- }
- else
- {
- throw new NotSupportedException(
- $"{RuntimeInformation.OSDescription} is not supported."
- );
- }
- }
- }
+// var cUser =
+// (
+// WindowsIdentity.GetCurrent().Groups
+// ?? throw new Exception("GetWindowsIdentity failed. 你需要手动处理发布内容!--检查权限!")
+// ).FirstOrDefault() ?? throw new NullReferenceException("can't be null");
+// FileSystemAccessRule MdfRule =
+// new(
+// cUser,
+// FileSystemRights.Modify,
+// inherits,
+// PropagationFlags.InheritOnly,
+// AccessControlType.Allow
+// );
+// if (dirSecurity.ModifyAccessRule(AccessControlModification.Set, MdfRule, out _)) { }
+// else
+// {
+// throw new Exception("AddAccessRule failed. 你需要手动处理发布内容!--检查权限!");
+// }
+// //设置访问权限
+// dirInfo.SetAccessControl(dirSecurity);
+// }
+// else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+// {
+// //TODO Linux文件权限
+// }
+// else
+// {
+// throw new NotSupportedException(
+// $"{RuntimeInformation.OSDescription} is not supported."
+// );
+// }
+// }
+// }
- public static void FreeThisFileAccess(string absolutePath)
- {
- if (
- CheckFileAccess(
- absolutePath,
- [FileAccess.Read, FileAccess.Write, FileAccess.Delete, FileAccess.Execute]
- )
- ) { }
- else
- {
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- FileInfo fileInfo = new(absolutePath);
- //获得该文件的访问权限
- FileSecurity fileSecurity = fileInfo.GetAccessControl();
+// public static void FreeThisFileAccess(string absolutePath)
+// {
+// if (
+// CheckFileAccess(
+// absolutePath,
+// [FileAccess.Read, FileAccess.Write, FileAccess.Delete, FileAccess.Execute]
+// )
+// ) { }
+// else
+// {
+// if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+// {
+// FileInfo fileInfo = new(absolutePath);
+// //获得该文件的访问权限
+// FileSecurity fileSecurity = fileInfo.GetAccessControl();
- var cUser =
- (
- WindowsIdentity.GetCurrent().Groups
- ?? throw new NullReferenceException(
- "GetWindowsIdentity failed. 你需要手动处理发布内容!-- 检查权限"
- )
- ).FirstOrDefault() ?? throw new NullReferenceException("can't be null");
- FileSystemAccessRule MdfRule =
- new(cUser, FileSystemRights.Modify, AccessControlType.Allow);
- if (fileSecurity.ModifyAccessRule(AccessControlModification.Set, MdfRule, out _))
- { }
- else
- {
- throw new Exception("AddAccessRule failed. 你需要手动处理发布内容!--检查权限");
- }
- }
- else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
- {
- //TODO Linux文件权限
- }
- else
- {
- throw new NotSupportedException(
- $"{RuntimeInformation.OSDescription} is not supported."
- );
- }
- }
- }
+// var cUser =
+// (
+// WindowsIdentity.GetCurrent().Groups
+// ?? throw new NullReferenceException(
+// "GetWindowsIdentity failed. 你需要手动处理发布内容!-- 检查权限"
+// )
+// ).FirstOrDefault() ?? throw new NullReferenceException("can't be null");
+// FileSystemAccessRule MdfRule =
+// new(cUser, FileSystemRights.Modify, AccessControlType.Allow);
+// if (fileSecurity.ModifyAccessRule(AccessControlModification.Set, MdfRule, out _))
+// { }
+// else
+// {
+// throw new Exception("AddAccessRule failed. 你需要手动处理发布内容!--检查权限");
+// }
+// }
+// else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+// {
+// //TODO Linux文件权限
+// }
+// else
+// {
+// throw new NotSupportedException(
+// $"{RuntimeInformation.OSDescription} is not supported."
+// );
+// }
+// }
+// }
- public static bool CheckDirAccess(string absolutePath, DirAcess[] access)
- {
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- DirectoryInfo dirInfo = new(absolutePath);
- //获得该文件的访问权限
- var dirSecurity = dirInfo.GetAccessControl();
- var ac = dirSecurity
- .GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier))
- .Cast();
-#pragma warning disable CA1416 // Validate platform compatibility
- var it =
- from i in ac
- where
- (
- WindowsIdentity.GetCurrent().Groups
- ?? throw new NullReferenceException("未能获取当前用户组!")
- ).Contains(i.IdentityReference)
- select i;
-#pragma warning restore CA1416 // Validate platform compatibility
- List caccess = [];
- foreach (var i in it)
- {
- if (i.FileSystemRights.HasFlag(FileSystemRights.FullControl))
- {
- return true;
- }
- if (
- i.FileSystemRights.HasFlag(
- FileSystemRights.Read
- | FileSystemRights.Modify
- | FileSystemRights.ReadAndExecute
- )
- )
- {
- caccess.Add(DirAcess.Read);
- }
- if (i.FileSystemRights.HasFlag(FileSystemRights.Write | FileSystemRights.Modify))
- {
- caccess.Add(DirAcess.Write);
- }
- if (i.FileSystemRights.HasFlag(FileSystemRights.Modify | FileSystemRights.Delete))
- {
- caccess.Add(DirAcess.Delete);
- }
- if (
- i.FileSystemRights.HasFlag(
- FileSystemRights.ListDirectory | FileSystemRights.Modify
- )
- )
- {
- caccess.Add(DirAcess.ListDirectory);
- }
- if (
- i.FileSystemRights.HasFlag(
- FileSystemRights.CreateFiles | FileSystemRights.Modify
- )
- )
- {
- caccess.Add(DirAcess.CreateFiles);
- }
- if (
- i.FileSystemRights.HasFlag(
- FileSystemRights.CreateDirectories | FileSystemRights.Modify
- )
- )
- {
- caccess.Add(DirAcess.CreateDirectories);
- }
- if (
- i.FileSystemRights.HasFlag(
- FileSystemRights.DeleteSubdirectoriesAndFiles | FileSystemRights.Modify
- )
- )
- {
- caccess.Add(DirAcess.DeleteSubdirectoriesAndFiles);
- }
- }
- foreach (var i in access)
- {
- if (!caccess.Contains(i))
- {
- return false;
- }
- }
- return true;
- }
- else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
- {
- //TODO Linux文件权限
- return true;
- }
- else
- {
- throw new NotSupportedException(
- $"{RuntimeInformation.OSDescription} is not supported."
- );
- }
- }
+// public static bool CheckDirAccess(string absolutePath, DirAcess[] access)
+// {
+// if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+// {
+// DirectoryInfo dirInfo = new(absolutePath);
+// //获得该文件的访问权限
+// var dirSecurity = dirInfo.GetAccessControl();
+// var ac = dirSecurity
+// .GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier))
+// .Cast();
+// #pragma warning disable CA1416 // Validate platform compatibility
+// var it =
+// from i in ac
+// where
+// (
+// WindowsIdentity.GetCurrent().Groups
+// ?? throw new NullReferenceException("未能获取当前用户组!")
+// ).Contains(i.IdentityReference)
+// select i;
+// #pragma warning restore CA1416 // Validate platform compatibility
+// List caccess = [];
+// foreach (var i in it)
+// {
+// if (i.FileSystemRights.HasFlag(FileSystemRights.FullControl))
+// {
+// return true;
+// }
+// if (
+// i.FileSystemRights.HasFlag(
+// FileSystemRights.Read
+// | FileSystemRights.Modify
+// | FileSystemRights.ReadAndExecute
+// )
+// )
+// {
+// caccess.Add(DirAcess.Read);
+// }
+// if (i.FileSystemRights.HasFlag(FileSystemRights.Write | FileSystemRights.Modify))
+// {
+// caccess.Add(DirAcess.Write);
+// }
+// if (i.FileSystemRights.HasFlag(FileSystemRights.Modify | FileSystemRights.Delete))
+// {
+// caccess.Add(DirAcess.Delete);
+// }
+// if (
+// i.FileSystemRights.HasFlag(
+// FileSystemRights.ListDirectory | FileSystemRights.Modify
+// )
+// )
+// {
+// caccess.Add(DirAcess.ListDirectory);
+// }
+// if (
+// i.FileSystemRights.HasFlag(
+// FileSystemRights.CreateFiles | FileSystemRights.Modify
+// )
+// )
+// {
+// caccess.Add(DirAcess.CreateFiles);
+// }
+// if (
+// i.FileSystemRights.HasFlag(
+// FileSystemRights.CreateDirectories | FileSystemRights.Modify
+// )
+// )
+// {
+// caccess.Add(DirAcess.CreateDirectories);
+// }
+// if (
+// i.FileSystemRights.HasFlag(
+// FileSystemRights.DeleteSubdirectoriesAndFiles | FileSystemRights.Modify
+// )
+// )
+// {
+// caccess.Add(DirAcess.DeleteSubdirectoriesAndFiles);
+// }
+// }
+// foreach (var i in access)
+// {
+// if (!caccess.Contains(i))
+// {
+// return false;
+// }
+// }
+// return true;
+// }
+// else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+// {
+// //TODO Linux文件权限
+// return true;
+// }
+// else
+// {
+// throw new NotSupportedException(
+// $"{RuntimeInformation.OSDescription} is not supported."
+// );
+// }
+// }
- public static bool CheckFileAccess(string absolutePath, FileAccess[] access)
- {
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- FileInfo fileInfo = new(absolutePath);
- //获得该文件的访问权限
- FileSecurity fileSecurity = fileInfo.GetAccessControl();
+// public static bool CheckFileAccess(string absolutePath, FileAccess[] access)
+// {
+// if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+// {
+// FileInfo fileInfo = new(absolutePath);
+// //获得该文件的访问权限
+// FileSecurity fileSecurity = fileInfo.GetAccessControl();
- var ac = fileSecurity
- .GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier))
- .Cast();
-#pragma warning disable CA1416 // 验证平台兼容性
- var it =
- from i in ac
- where
- (
- WindowsIdentity.GetCurrent().Groups
- ?? throw new NullReferenceException("未能获取当前用户组!")
- ).Contains(i.IdentityReference)
- select i;
-#pragma warning restore CA1416 // 验证平台兼容性
+// var ac = fileSecurity
+// .GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier))
+// .Cast();
+// #pragma warning disable CA1416 // 验证平台兼容性
+// var it =
+// from i in ac
+// where
+// (
+// WindowsIdentity.GetCurrent().Groups
+// ?? throw new NullReferenceException("未能获取当前用户组!")
+// ).Contains(i.IdentityReference)
+// select i;
+// #pragma warning restore CA1416 // 验证平台兼容性
- List caccess = [];
- foreach (var i in it)
- {
- if (i.FileSystemRights.HasFlag(FileSystemRights.FullControl))
- {
- return true;
- }
- if (i.FileSystemRights.HasFlag(FileSystemRights.Read | FileSystemRights.Modify))
- {
- caccess.Add(FileAccess.Read);
- }
- if (i.FileSystemRights.HasFlag(FileSystemRights.Write | FileSystemRights.Modify))
- {
- caccess.Add(FileAccess.Write);
- }
- if (i.FileSystemRights.HasFlag(FileSystemRights.Write | FileSystemRights.Modify))
- {
- caccess.Add(FileAccess.Delete);
- }
- if (
- i.FileSystemRights.HasFlag(
- FileSystemRights.ExecuteFile | FileSystemRights.Modify
- )
- )
- {
- caccess.Add(FileAccess.Execute);
- }
- }
- foreach (var i in access)
- {
- if (!caccess.Contains(i))
- {
- return false;
- }
- }
- return true;
- }
- else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
- {
- //TODO Linux文件夹权限
- return true;
- }
- else
- {
- throw new NotSupportedException(
- $"{RuntimeInformation.OSDescription} is not supported."
- );
- }
- }
+// List caccess = [];
+// foreach (var i in it)
+// {
+// if (i.FileSystemRights.HasFlag(FileSystemRights.FullControl))
+// {
+// return true;
+// }
+// if (i.FileSystemRights.HasFlag(FileSystemRights.Read | FileSystemRights.Modify))
+// {
+// caccess.Add(FileAccess.Read);
+// }
+// if (i.FileSystemRights.HasFlag(FileSystemRights.Write | FileSystemRights.Modify))
+// {
+// caccess.Add(FileAccess.Write);
+// }
+// if (i.FileSystemRights.HasFlag(FileSystemRights.Write | FileSystemRights.Modify))
+// {
+// caccess.Add(FileAccess.Delete);
+// }
+// if (
+// i.FileSystemRights.HasFlag(
+// FileSystemRights.ExecuteFile | FileSystemRights.Modify
+// )
+// )
+// {
+// caccess.Add(FileAccess.Execute);
+// }
+// }
+// foreach (var i in access)
+// {
+// if (!caccess.Contains(i))
+// {
+// return false;
+// }
+// }
+// return true;
+// }
+// else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+// {
+// //TODO Linux文件夹权限
+// return true;
+// }
+// else
+// {
+// throw new NotSupportedException(
+// $"{RuntimeInformation.OSDescription} is not supported."
+// );
+// }
+// }
- ///
- /// 获取当前用户
- ///
- ///
- ///
+// ///
+// /// 获取当前用户
+// ///
+// ///
+// ///
- public static string GetCurrentUser()
- {
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- return System.Security.Principal.WindowsIdentity.GetCurrent().Name;
- }
- else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
- {
- return Environment.UserName;
- }
- else
- {
- throw new NotSupportedException(
- $"{RuntimeInformation.OSDescription} is not supported."
- );
- }
- }
-}
+// public static string GetCurrentUser()
+// {
+// if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+// {
+// return System.Security.Principal.WindowsIdentity.GetCurrent().Name;
+// }
+// else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+// {
+// return Environment.UserName;
+// }
+// else
+// {
+// throw new NotSupportedException(
+// $"{RuntimeInformation.OSDescription} is not supported."
+// );
+// }
+// }
+// }
diff --git a/Server/LocalServer/Controllers/LocalServerController.cs b/Server/LocalServer/Controllers/LocalServerController.cs
index 19fee47..8867b9b 100644
--- a/Server/LocalServer/Controllers/LocalServerController.cs
+++ b/Server/LocalServer/Controllers/LocalServerController.cs
@@ -10,36 +10,11 @@ namespace LocalServer.Controllers
{
private readonly LocalSyncServerFactory Factory = factory;
- private static async Task Echo(WebSocket webSocket)
- {
- var buffer = new byte[1024 * 4];
- var receiveResult = await webSocket.ReceiveAsync(
- new ArraySegment(buffer),
- CancellationToken.None
- );
-
- while (!receiveResult.CloseStatus.HasValue)
- {
- await webSocket.SendAsync(
- new ArraySegment(buffer, 0, receiveResult.Count),
- receiveResult.MessageType,
- receiveResult.EndOfMessage,
- CancellationToken.None
- );
-
- receiveResult = await webSocket.ReceiveAsync(
- new ArraySegment(buffer),
- CancellationToken.None
- );
- }
-
- await webSocket.CloseAsync(
- receiveResult.CloseStatus.Value,
- receiveResult.CloseStatusDescription,
- CancellationToken.None
- );
- }
-
+ ///
+ /// websoc 连接入口
+ ///
+ ///
+ ///
[Route("/websoc")]
public async Task WebsocketConnection(string Name)
{
@@ -50,8 +25,8 @@ namespace LocalServer.Controllers
if (Factory.GetServerByName(Name) == null)
{
var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync();
- //await Echo(webSocket);
var pipeLine = new WebSocPipeLine(webSocket, false);
+ //必须在此保留连接的上下文,否则 websocket 就直接断了。。。微软 这个设计措不及防
await Factory.CreateLocalSyncServer(
pipeLine,
Name,
@@ -75,18 +50,18 @@ namespace LocalServer.Controllers
}
}
- [Route("/macaddr")]
- public string GetMacAddress()
- {
- NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
- string macaddrs = "";
- foreach (NetworkInterface nic in nics)
- {
- PhysicalAddress physicalAddress = nic.GetPhysicalAddress();
- macaddrs += physicalAddress.ToString() + ";";
- }
- return macaddrs;
- }
- //TODO 是否在本地记载同步日志?
+ // [Route("/macaddr")]
+ // public string GetMacAddress()
+ // {
+ // NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
+ // string macaddrs = "";
+ // foreach (NetworkInterface nic in nics)
+ // {
+ // PhysicalAddress physicalAddress = nic.GetPhysicalAddress();
+ // macaddrs += physicalAddress.ToString() + ";";
+ // }
+ // return macaddrs;
+ // }
+ // //TODO 是否在本地记载同步日志?
}
}
diff --git a/Server/LocalServer/LocalSyncServer.cs b/Server/LocalServer/LocalSyncServer.cs
index 219ce86..bdf9011 100644
--- a/Server/LocalServer/LocalSyncServer.cs
+++ b/Server/LocalServer/LocalSyncServer.cs
@@ -8,63 +8,76 @@ public class LocalSyncServer
#pragma warning disable CA2211 // Non-constant fields should not be visible
public static string TempRootFile = "C:/TempPack";
public static string SqlPackageAbPath = "sqlpackage";
-
+ // 使用msdeploy 将会打包当前可运行的内容,它很有可能不包含最新的构建
//public static string MsdeployAbPath = "msdeploy";
//与visual studio 匹配的Msbuild 路径。在vs 中打开power shell 命令行,使用 `(get-Command -Name msbuild).Source `
+ //使用msbuild 会缺少.net frame的运行环境 bin\roslyn 里面的内容,第一次需要人为复制一下,后面就就好了。
public static string MSBuildAbPath = "MSBuild";
#pragma warning restore CA2211 // Non-constant fields should not be visible
+
+ ///
+ /// 连接状态,流程管理,LocalPipe 和 remotePipe 也在此处交换信息
+ ///
private StateHelpBase StateHelper;
+
public void SetStateHelper(StateHelpBase helper)
{
StateHelper = helper;
}
- public static string GetProjectOutPath(string project)
- {
- try
- {
- XDocument xdoc = XDocument.Load(project);
- // 获取根元素
- XElement rootElement = xdoc.Root ?? throw new NullReferenceException("Root");
- Console.WriteLine("根元素: " + rootElement.Name);
+ ///
+ /// 查找构建xml文件,获取构建信息,那这个不用了
+ ///
+ ///
+ // public static string GetProjectOutPath(string project)
+ // {
+ // try
+ // {
+ // XDocument xdoc = XDocument.Load(project);
+ // // 获取根元素
+ // XElement rootElement = xdoc.Root ?? throw new NullReferenceException("Root");
+ // Console.WriteLine("根元素: " + rootElement.Name);
- // 遍历子节点
- foreach (XElement element in rootElement.Elements())
- {
- if (element.Name.LocalName.Contains("PropertyGroup"))
- {
- var Conditon = element.Attribute("Condition");
+ // // 遍历子节点
+ // foreach (XElement element in rootElement.Elements())
+ // {
+ // if (element.Name.LocalName.Contains("PropertyGroup"))
+ // {
+ // var Conditon = element.Attribute("Condition");
- if (Conditon != null)
- {
- if (Conditon.Value.Contains("Release"))
- {
- foreach (XElement element2 in element.Elements())
- {
- if (element2.Name.LocalName == "OutputPath")
- {
- return element2.Value;
- }
- }
- }
- }
- }
- }
- return "bin/";
- }
- catch (Exception)
- {
- return "bin/";
- }
- }
+ // if (Conditon != null)
+ // {
+ // if (Conditon.Value.Contains("Release"))
+ // {
+ // foreach (XElement element2 in element.Elements())
+ // {
+ // if (element2.Name.LocalName == "OutputPath")
+ // {
+ // return element2.Value;
+ // }
+ // }
+ // }
+ // }
+ // }
+ // }
+ // return "bin/";
+ // }
+ // catch (Exception)
+ // {
+ // return "bin/";
+ // }
+ // }
public StateHelpBase GetStateHelper()
{
return StateHelper;
}
+ ///
+ /// 此次发布的配置
+ ///
public Config? SyncConfig;
public Config NotNullSyncConfig
@@ -79,13 +92,19 @@ public class LocalSyncServer
}
}
+ ///
+ /// 发布的名称
+ ///
public string Name;
///
- /// 发布源连接
+ /// jswebsocket 和 local server 的连接,它没有加密
///
public readonly AbsPipeLine LocalPipe;
+ ///
+ /// local server 和 remote server 的连接,它有加密
+ ///
public readonly AbsPipeLine RemotePipe;
///
@@ -107,6 +126,10 @@ public class LocalSyncServer
RemotePipe = remotePipe;
}
+ ///
+ /// 这个阻塞在,接口中有http上下文处
+ ///
+ ///
public async Task Connect()
{
try
@@ -125,6 +148,10 @@ public class LocalSyncServer
}
}
+ ///
+ /// 关闭连接
+ ///
+ ///
public void Close(string? CloseReason)
{
try
diff --git a/Server/LocalServer/StateHelper.cs b/Server/LocalServer/StateHelper.cs
index dd7fc00..3981388 100644
--- a/Server/LocalServer/StateHelper.cs
+++ b/Server/LocalServer/StateHelper.cs
@@ -2,19 +2,10 @@ using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.Json;
-using System.Text.Json.Serialization;
using Common;
namespace LocalServer;
-// enum StateWhenMsg
-// {
-// Authority = 0,
-// ConfigInfo = 1,
-// LocalPackAndUpload = 2,
-// RemoteUnPackAndRelease = 3,
-// }
-
public abstract class StateHelpBase(
LocalSyncServer context,
SyncProcessStep step = SyncProcessStep.Connect
@@ -147,18 +138,11 @@ public class DeployHelper(LocalSyncServer context)
h.DiffProcess();
}
else
- {
+ { // msbuild 只在windows 才有
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
//构建
- //var OutputPath = LocalSyncServer.GetProjectOutPath(
- // Context.NotNullSyncConfig.LocalProjectAbsolutePath
- //);
- //var AbOutPath = Path.Combine(
- // Context.NotNullSyncConfig.LocalProjectAbsolutePath,
- // OutputPath
- //);
ProcessStartInfo startbuildInfo =
new()
{
@@ -334,59 +318,52 @@ public class DeployMSSqlHelper(LocalSyncServer context)
}
else
{
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ var arguments =
+ $" /Action:Extract /TargetFile:{LocalSyncServer.TempRootFile}/{Context.NotNullSyncConfig.Id.ToString()}/{Context.NotNullSyncConfig.Id.ToString()}.dacpac"
+ // 不要log file 了
+ //+ $" /DiagnosticsFile:{LocalSyncServer.TempRootFile}/{Context.NotNullSyncConfig.Id.ToString()}/{Context.NotNullSyncConfig.Id.ToString()}.log"
+ + $" /p:ExtractAllTableData=false /p:VerifyExtraction=true /SourceServerName:{Context.NotNullSyncConfig.SrcDb.ServerName}"
+ + $" /SourceDatabaseName:{Context.NotNullSyncConfig.SrcDb.DatebaseName} /SourceUser:{Context.NotNullSyncConfig.SrcDb.User}"
+ + $" /SourcePassword:{Context.NotNullSyncConfig.SrcDb.Password} /SourceTrustServerCertificate:{Context.NotNullSyncConfig.SrcDb.TrustServerCertificate}"
+ + $" /p:ExtractReferencedServerScopedElements=False /p:IgnoreUserLoginMappings=True /p:IgnorePermissions=True";
+ if (Context.NotNullSyncConfig.SrcDb.SyncTablesData != null)
{
- var arguments =
- $" /Action:Extract /TargetFile:{LocalSyncServer.TempRootFile}/{Context.NotNullSyncConfig.Id.ToString()}/{Context.NotNullSyncConfig.Id.ToString()}.dacpac"
- // 不要log file 了
- //+ $" /DiagnosticsFile:{LocalSyncServer.TempRootFile}/{Context.NotNullSyncConfig.Id.ToString()}/{Context.NotNullSyncConfig.Id.ToString()}.log"
- + $" /p:ExtractAllTableData=false /p:VerifyExtraction=true /SourceServerName:{Context.NotNullSyncConfig.SrcDb.ServerName}"
- + $" /SourceDatabaseName:{Context.NotNullSyncConfig.SrcDb.DatebaseName} /SourceUser:{Context.NotNullSyncConfig.SrcDb.User}"
- + $" /SourcePassword:{Context.NotNullSyncConfig.SrcDb.Password} /SourceTrustServerCertificate:{Context.NotNullSyncConfig.SrcDb.TrustServerCertificate}"
- + $" /p:ExtractReferencedServerScopedElements=False /p:IgnoreUserLoginMappings=True /p:IgnorePermissions=True";
- if (Context.NotNullSyncConfig.SrcDb.SyncTablesData != null)
+ foreach (var t in Context.NotNullSyncConfig.SrcDb.SyncTablesData)
{
- foreach (var t in Context.NotNullSyncConfig.SrcDb.SyncTablesData)
- {
- arguments += $" /p:TableData={t}";
- }
+ arguments += $" /p:TableData={t}";
}
+ }
- ProcessStartInfo startInfo =
- new()
- {
- FileName = LocalSyncServer.SqlPackageAbPath, // The command to execute (can be any command line tool)
- Arguments = arguments,
- StandardOutputEncoding = System.Text.Encoding.UTF8,
- // 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)
+ ProcessStartInfo startInfo =
+ new()
{
- Context.LocalPipe.SendMsg(CreateMsg("数据库打包成功!")).Wait();
- PackAndSwitchNext();
- }
- else
- {
- Context.LocalPipe.SendMsg(CreateErrMsg(output)).Wait();
- throw new Exception("执行发布错误,错误信息参考上一条消息!");
- }
+ FileName = LocalSyncServer.SqlPackageAbPath, // The command to execute (can be any command line tool)
+ Arguments = arguments,
+ StandardOutputEncoding = System.Text.Encoding.UTF8,
+ // 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.LocalPipe.SendMsg(CreateMsg("数据库打包成功!")).Wait();
+ PackAndSwitchNext();
}
else
{
- throw new NotSupportedException("只支持windows!");
+ Context.LocalPipe.SendMsg(CreateErrMsg(output)).Wait();
+ throw new Exception("执行发布错误,错误信息参考上一条消息!");
}
}
}
@@ -410,6 +387,7 @@ public class UploadPackedHelper(LocalSyncServer context)
$"{LocalSyncServer.TempRootFile}/{Context.NotNullSyncConfig.Id}.zip",
(double current) =>
{
+ //这里可能需要降低获取上传进度的频率
Context
.LocalPipe.SendMsg(CreateMsg(current.ToString(), SyncMsgType.Process))
.Wait();
@@ -449,223 +427,4 @@ public class FinallyPublishHelper(LocalSyncServer context)
{
Context.LocalPipe.SendMsg(msg).Wait();
}
-}
-// ///
-// /// 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) { }
-// }
+}
\ No newline at end of file
diff --git a/Server/RemoteServer/Controllers/RemoteServerController.cs b/Server/RemoteServer/Controllers/RemoteServerController.cs
index 8d3acfa..33f79c5 100644
--- a/Server/RemoteServer/Controllers/RemoteServerController.cs
+++ b/Server/RemoteServer/Controllers/RemoteServerController.cs
@@ -24,8 +24,6 @@ public class SyncFilesController(RemoteSyncServerFactory factory, SqliteDbContex
var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync();
var pipeLine = new WebSocPipeLine(webSocket, true);
await Factory.CreateRemoteSyncServer(pipeLine, Name);
-
- var x = 11;
}
else
{
@@ -43,127 +41,11 @@ public class SyncFilesController(RemoteSyncServerFactory factory, SqliteDbContex
HttpContext.Response.StatusCode = StatusCodes.Status400BadRequest;
}
}
-
- [HttpGet("/GetSyncFilesLogs")]
- public IActionResult GetSyncFilesLogs(
- string? ClientName,
- int? Status,
- DateTime? SyncTimeStart,
- DateTime? SyncTimeEnd,
- int page,
- int rows
- )
- {
- var item =
- from i in _db.SyncLogHeads
- where
- (
- string.IsNullOrEmpty(ClientName)
- || (i.ClientName != null && i.ClientName.Contains(ClientName))
- )
- && (Status == null || i.Status == Status)
- && (SyncTimeStart == null || i.SyncTime >= SyncTimeStart)
- && (SyncTimeEnd == null || i.SyncTime <= SyncTimeEnd)
- orderby i.Id descending
- select new
- {
- Head = i,
- Files = (from j in _db.SyncLogFiles where j.HeadId == i.Id select j).ToList()
- };
-
- return Ok(item.Skip((page - 1) * rows).Take(rows).ToList());
- }
-
- public class InputFileInfo
- {
- public required string RelativePath { get; set; }
- public DateTime MTime { get; set; }
- }
-
- public class OutputFileInfo : InputFileInfo
- {
- ///
- /// 0 新增 1 修改 2 删除
- ///
- public int ServerOpType { get; set; }
- }
-
- public class ServerOpFileInfo : OutputFileInfo
- {
- public required string ServerRootDirPath { get; set; }
- public required string ClientRootDirPath { get; set; }
- }
-
- public class InputFiles
- {
- public required string ServerRootDirPath { get; set; }
-
- ///
- /// 0 special 1 exclude
- ///
- public int Type { get; set; }
- public List? Files { get; set; }
- }
-
- public class ServerOpFiles
- {
- public required string ServerRootDirPath { get; set; }
- public string? ClientRootDirPath { get; set; }
- public List? Files { get; set; }
- }
-
- [HttpPost("/GetFilesInfoByDir")]
- public IActionResult GetFilesInfoByDir([FromBody] InputFiles inputFiles)
- {
- return Ok(new { IsSuccess = true });
- }
-
- [HttpPost("/InitASync")]
- public IActionResult InitASync([FromBody] SyncLogHead head)
- {
- try
- {
- var CurrentSyncTaskCount = (
- from i in _db.SyncLogHeads
- where i.Status == 0
- select i
- ).Count();
- if (CurrentSyncTaskCount > 0)
- {
- throw new Exception("存在未完成的任务,请等待完成!");
- }
- head.Id = Guid.NewGuid();
- head.SyncTime = DateTime.Now;
- head.Status = 0;
- _db.SyncLogHeads.Add(head);
- _db.SaveChanges();
- return Ok(new { IsSuccess = true, head.Id });
- }
- catch (Exception e)
- {
- return Ok(new { IsSuccess = false, e.Message });
- }
- }
-
- [HttpGet("/CloseASync")]
- public IActionResult CloseASync(Guid Id, string Message, int Status)
- {
- try
- {
- var current =
- (from i in _db.SyncLogHeads where i.Id == Id select i).FirstOrDefault()
- ?? throw new Exception("任务不存在!");
- current.Status = Status;
- current.Message = Message;
- _db.SaveChanges();
- return Ok(new { IsSuccess = true });
- }
- catch (Exception e)
- {
- return Ok(new { IsSuccess = false, e.Message });
- }
- }
-
+ ///
+ /// 上传文件
+ ///
+ ///
+ ///
[HttpPost("/UploadFile")]
public async Task UploadFile(IFormFile file)
{
@@ -199,4 +81,124 @@ public class SyncFilesController(RemoteSyncServerFactory factory, SqliteDbContex
return StatusCode(500, new { IsSuccess = false, Message = $"上传文件失败: {ex.Message}" });
}
}
+
+ // [HttpGet("/GetSyncFilesLogs")]
+ // public IActionResult GetSyncFilesLogs(
+ // string? ClientName,
+ // int? Status,
+ // DateTime? SyncTimeStart,
+ // DateTime? SyncTimeEnd,
+ // int page,
+ // int rows
+ // )
+ // {
+ // var item =
+ // from i in _db.SyncLogHeads
+ // where
+ // (
+ // string.IsNullOrEmpty(ClientName)
+ // || (i.ClientName != null && i.ClientName.Contains(ClientName))
+ // )
+ // && (Status == null || i.Status == Status)
+ // && (SyncTimeStart == null || i.SyncTime >= SyncTimeStart)
+ // && (SyncTimeEnd == null || i.SyncTime <= SyncTimeEnd)
+ // orderby i.Id descending
+ // select new
+ // {
+ // Head = i,
+ // Files = (from j in _db.SyncLogFiles where j.HeadId == i.Id select j).ToList()
+ // };
+
+ // return Ok(item.Skip((page - 1) * rows).Take(rows).ToList());
+ // }
+
+ // public class InputFileInfo
+ // {
+ // public required string RelativePath { get; set; }
+ // public DateTime MTime { get; set; }
+ // }
+
+ // public class OutputFileInfo : InputFileInfo
+ // {
+ // ///
+ // /// 0 新增 1 修改 2 删除
+ // ///
+ // public int ServerOpType { get; set; }
+ // }
+
+ // public class ServerOpFileInfo : OutputFileInfo
+ // {
+ // public required string ServerRootDirPath { get; set; }
+ // public required string ClientRootDirPath { get; set; }
+ // }
+
+ // public class InputFiles
+ // {
+ // public required string ServerRootDirPath { get; set; }
+
+ // ///
+ // /// 0 special 1 exclude
+ // ///
+ // public int Type { get; set; }
+ // public List? Files { get; set; }
+ // }
+
+ // public class ServerOpFiles
+ // {
+ // public required string ServerRootDirPath { get; set; }
+ // public string? ClientRootDirPath { get; set; }
+ // public List? Files { get; set; }
+ // }
+
+ // [HttpPost("/GetFilesInfoByDir")]
+ // public IActionResult GetFilesInfoByDir([FromBody] InputFiles inputFiles)
+ // {
+ // return Ok(new { IsSuccess = true });
+ // }
+
+ // [HttpPost("/InitASync")]
+ // public IActionResult InitASync([FromBody] SyncLogHead head)
+ // {
+ // try
+ // {
+ // var CurrentSyncTaskCount = (
+ // from i in _db.SyncLogHeads
+ // where i.Status == 0
+ // select i
+ // ).Count();
+ // if (CurrentSyncTaskCount > 0)
+ // {
+ // throw new Exception("存在未完成的任务,请等待完成!");
+ // }
+ // head.Id = Guid.NewGuid();
+ // head.SyncTime = DateTime.Now;
+ // head.Status = 0;
+ // _db.SyncLogHeads.Add(head);
+ // _db.SaveChanges();
+ // return Ok(new { IsSuccess = true, head.Id });
+ // }
+ // catch (Exception e)
+ // {
+ // return Ok(new { IsSuccess = false, e.Message });
+ // }
+ // }
+
+ // [HttpGet("/CloseASync")]
+ // public IActionResult CloseASync(Guid Id, string Message, int Status)
+ // {
+ // try
+ // {
+ // var current =
+ // (from i in _db.SyncLogHeads where i.Id == Id select i).FirstOrDefault()
+ // ?? throw new Exception("任务不存在!");
+ // current.Status = Status;
+ // current.Message = Message;
+ // _db.SaveChanges();
+ // return Ok(new { IsSuccess = true });
+ // }
+ // catch (Exception e)
+ // {
+ // return Ok(new { IsSuccess = false, e.Message });
+ // }
+ // }
}
diff --git a/Server/RemoteServer/Program.cs b/Server/RemoteServer/Program.cs
index 8e8aeb7..6c11bb7 100644
--- a/Server/RemoteServer/Program.cs
+++ b/Server/RemoteServer/Program.cs
@@ -10,10 +10,6 @@ ConfigurationBuilder configurationBuilder = new();
// Add services to the container.
//添加配置文件路径
-RemoteSyncServerFactory.NamePwd =
-[
- .. (builder.Configuration.GetSection("NamePwds").Get[]>() ?? [])
-];
foreach (var x in builder.Configuration.GetSection("NamePwds").GetChildren())
{
var it = x.GetChildren();
diff --git a/Server/RemoteServer/RemoteSyncServerFactory.cs b/Server/RemoteServer/RemoteSyncServerFactory.cs
index 58f0389..c40f6fa 100644
--- a/Server/RemoteServer/RemoteSyncServerFactory.cs
+++ b/Server/RemoteServer/RemoteSyncServerFactory.cs
@@ -7,6 +7,10 @@ public class RemoteSyncServerFactory
private readonly object Lock = new();
#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
diff --git a/Server/RemoteServer/StateHelper.cs b/Server/RemoteServer/StateHelper.cs
index 3f025cd..b6dfa2c 100644
--- a/Server/RemoteServer/StateHelper.cs
+++ b/Server/RemoteServer/StateHelper.cs
@@ -6,13 +6,6 @@ using Common;
namespace RemoteServer;
-// enum StateWhenMsg
-// {
-// Authority = 0,
-// ConfigInfo = 1,
-// LocalPackAndUpload = 2,
-// RemoteUnPackAndRelease = 3,
-// }
public abstract class StateHelpBase(
RemoteSyncServer context,
@@ -151,8 +144,6 @@ public class FinallyPublishHelper(RemoteSyncServer context)
public void FinallyPublish()
{
// 发布数据库
- if (Context.NotNullSyncConfig.IsDeployDb)
- {
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
var arguments =
@@ -189,11 +180,6 @@ public class FinallyPublishHelper(RemoteSyncServer context)
Context.Pipe.SendMsg(CreateErrMsg(output)).Wait();
throw new Exception("执行发布错误,错误信息参考上一条消息!");
}
- }
- else
- {
- throw new NotSupportedException("只支持windows!");
- }
}
else
{
diff --git a/Server/ServerTest/PipeTest.cs b/Server/ServerTest/PipeTest.cs
index cfc4386..0768820 100644
--- a/Server/ServerTest/PipeTest.cs
+++ b/Server/ServerTest/PipeTest.cs
@@ -1,3 +1,4 @@
+using System.Runtime.InteropServices;
using System.Text.Json;
using Common;
using LocalServer;
@@ -13,68 +14,75 @@ public class PipeTest
[Fact]
public async void TestCase()
{
- var p1 = new TestPipe(false, "1");
- var x = Task.Run(async () =>
+ //msbuild ֻwindows
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
- var rs = p1.Work(
- (byte[] b) =>
- {
- var msg = JsonSerializer.Deserialize(b);
- if (msg.Body == "ɣ")
- {
- p1.Close("˳");
- }
- Console.WriteLine(b);
- return true;
- }
- );
- await foreach (var r in rs)
+ var p1 = new TestPipe(false, "1");
+ var x = Task.Run(async () =>
{
- Console.WriteLine(r);
+ var rs = p1.Work(
+ (byte[] b) =>
+ {
+ var msg = JsonSerializer.Deserialize(b);
+#pragma warning disable CS8602 // Dereference of a possibly null reference.
+ if (msg.Body == "ɣ")
+ {
+ _ = p1.Close("˳");
+ }
+#pragma warning restore CS8602 // Dereference of a possibly null reference.
+ Console.WriteLine(b);
+ return true;
+ }
+ );
+ await foreach (var r in rs)
+ {
+ Console.WriteLine(r);
+ }
+ });
+ //await p1.Close("sdf");
+ //await x;
+ var p2 = new TestPipe(false, "2");
+ p1.Other = p2;
+ p2.Other = p1;
+ var p3 = new TestPipe(true, "3");
+ var p4 = new TestPipe(true, "4");
+ p3.Other = p4;
+ p4.Other = p3;
+ LocalSyncServer.TempRootFile = "D:/FileSyncTest/stemp";
+ RemoteSyncServer.SqlPackageAbPath =
+ "C:\\Users\\ZHAOLEI\\.dotnet\\tools\\sqlpackage.exe";
+ //LocalSyncServer.MsdeployAbPath =
+ // "C:\\Program Files\\IIS\\Microsoft Web Deploy V3\\msdeploy.exe";
+ LocalSyncServer.SqlPackageAbPath = "C:\\Users\\ZHAOLEI\\.dotnet\\tools\\sqlpackage.exe";
+ LocalSyncServer.MSBuildAbPath =
+ "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\MSBuild\\Current\\Bin\\amd64\\MSBuild.exe";
+ RemoteSyncServer.TempRootFile = "D:/FileSyncTest/dtemp";
+ RemoteSyncServerFactory.NamePwd = [new Tuple("Test", "t123")];
+ var lf = new LocalSyncServerFactory();
+ var task1 = Task.Run(async () =>
+ {
+ await lf.CreateLocalSyncServer(p2, "Test", p3);
+ });
+
+ var rf = new RemoteSyncServerFactory();
+
+ var task2 = Task.Run(async () =>
+ {
+ await rf.CreateRemoteSyncServer(p4, "Test");
+ });
+ TestPipe.syncServerFactory = rf;
+ var starter = new SyncMsg
+ {
+ Body = JsonSerializer.Serialize(new PipeSeed().TestConfig),
+ Type = SyncMsgType.General,
+ Step = SyncProcessStep.Connect
+ };
+ await p1.SendMsg(starter);
+ await x;
+ if (p1.ErrResult != "˳")
+ {
+ Assert.Fail(p1.ErrResult);
}
- });
- //await p1.Close("sdf");
- //await x;
- var p2 = new TestPipe(false, "2");
- p1.Other = p2;
- p2.Other = p1;
- var p3 = new TestPipe(true, "3");
- var p4 = new TestPipe(true, "4");
- p3.Other = p4;
- p4.Other = p3;
- LocalSyncServer.TempRootFile = "D:/FileSyncTest/stemp";
- RemoteSyncServer.SqlPackageAbPath = "C:\\Users\\ZHAOLEI\\.dotnet\\tools\\sqlpackage.exe";
- //LocalSyncServer.MsdeployAbPath =
- // "C:\\Program Files\\IIS\\Microsoft Web Deploy V3\\msdeploy.exe";
- LocalSyncServer.SqlPackageAbPath = "C:\\Users\\ZHAOLEI\\.dotnet\\tools\\sqlpackage.exe";
- LocalSyncServer.MSBuildAbPath =
- "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\MSBuild\\Current\\Bin\\amd64\\MSBuild.exe";
- RemoteSyncServer.TempRootFile = "D:/FileSyncTest/dtemp";
- RemoteSyncServerFactory.NamePwd = [new Tuple("Test", "t123")];
- var lf = new LocalSyncServerFactory();
- var task1 = Task.Run(async () =>
- {
- await lf.CreateLocalSyncServer(p2, "Test", p3);
- });
-
- var rf = new RemoteSyncServerFactory();
-
- var task2 = Task.Run(async () =>
- {
- await rf.CreateRemoteSyncServer(p4, "Test");
- });
- TestPipe.syncServerFactory = rf;
- var starter = new SyncMsg
- {
- Body = JsonSerializer.Serialize(new PipeSeed().TestConfig),
- Type = SyncMsgType.General,
- Step = SyncProcessStep.Connect
- };
- await p1.SendMsg(starter);
- await x;
- if (p1.ErrResult != "˳")
- {
- Assert.Fail(p1.ErrResult);
}
}
}
diff --git a/Server/ServerTest/TestPipe.cs b/Server/ServerTest/TestPipe.cs
index f96897f..5bdae1e 100644
--- a/Server/ServerTest/TestPipe.cs
+++ b/Server/ServerTest/TestPipe.cs
@@ -15,7 +15,9 @@ namespace ServerTest
public TestPipe? Other;
public string? ErrResult;
public string Id = id;
+#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
public static RemoteSyncServerFactory syncServerFactory;
+#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
public override async IAsyncEnumerable Work(
Func receiveCb,
@@ -44,7 +46,7 @@ namespace ServerTest
//}
Task.Run(() =>
{
- var it = syncServerFactory.GetServerByName("Test");
+ var it = syncServerFactory.GetServerByName("Test")?? throw new NullReferenceException("找不到服务名称!");
var h = new UnPackAndReleaseHelper(it);
it.SetStateHelpBase(h);
h.UnPack();