fix: websocket pipeline 测试修复了大量的问题,一大部分是对websocket和c# 不熟悉所致。
- 上传文件bug修复 - 继续测试修改bug - 代码审查处理,添加必要注释,风格规范性等
This commit is contained in:
parent
5517ea9df8
commit
35a0710ab5
11 changed files with 148 additions and 69 deletions
|
@ -120,7 +120,7 @@ public class AESHelper
|
||||||
|
|
||||||
// Declare the string used to hold
|
// Declare the string used to hold
|
||||||
// the decrypted text.
|
// the decrypted text.
|
||||||
string plaintext = null;
|
string plaintext = string.Empty;
|
||||||
|
|
||||||
// Create an Aes object
|
// Create an Aes object
|
||||||
// with the specified key and IV.
|
// with the specified key and IV.
|
||||||
|
|
|
@ -27,7 +27,7 @@ public abstract class AbsPipeLine(bool isAES)
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public abstract Task SendMsg(SyncMsg msg);
|
public abstract Task SendMsg(SyncMsg msg);
|
||||||
|
|
||||||
public abstract Task UploadFile(string filePath, string url, Func<double, bool> progressCb);
|
public abstract Task UploadFile(string url, string filePath, Func<double, bool> progressCb);
|
||||||
protected readonly bool IsAES = isAES;
|
protected readonly bool IsAES = isAES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,33 +37,27 @@ public class WebSocPipeLine<TSocket>(TSocket socket, bool isAES) : AbsPipeLine(i
|
||||||
public readonly TSocket Socket = socket;
|
public readonly TSocket Socket = socket;
|
||||||
|
|
||||||
public override async Task UploadFile(
|
public override async Task UploadFile(
|
||||||
string filePath,
|
|
||||||
string url,
|
string url,
|
||||||
|
string filePath,
|
||||||
Func<double, bool> progressCb
|
Func<double, bool> progressCb
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (Socket is HttpClient)
|
//throw new Exception("sdfsdf");
|
||||||
{
|
using var client = new HttpClient();
|
||||||
using var client = new HttpClient();
|
using var content = new MultipartFormDataContent();
|
||||||
using var content = new MultipartFormDataContent();
|
using var fileStream = new FileStream(filePath, FileMode.Open);
|
||||||
using var fileStream = new FileStream(filePath, FileMode.Open);
|
var progress = new Progress<double>(
|
||||||
var progress = new Progress<double>(
|
(current) =>
|
||||||
(current) =>
|
|
||||||
{
|
|
||||||
progressCb(current);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
var fileContent = new ProgressStreamContent(fileStream, progress);
|
|
||||||
content.Add(fileContent, "file", Path.GetFileName(filePath));
|
|
||||||
var it = await client.PostAsync("http://" + url + "/UploadPacked", content);
|
|
||||||
if (it.StatusCode != System.Net.HttpStatusCode.OK)
|
|
||||||
{
|
{
|
||||||
throw new Exception(it.Content.ReadAsStringAsync().Result);
|
progressCb(current);
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
else
|
//var fileContent = new ProgressStreamContent(fileStream, progress);
|
||||||
|
content.Add(new StreamContent(fileStream), "file", Path.GetFileName(filePath));
|
||||||
|
var it = await client.PostAsync("http://" + url + "/UploadFile", content);
|
||||||
|
if (it.StatusCode != System.Net.HttpStatusCode.OK)
|
||||||
{
|
{
|
||||||
throw new NotSupportedException("只支持HttpClient!");
|
throw new Exception(it.Content.ReadAsStringAsync().Result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +100,9 @@ public class WebSocPipeLine<TSocket>(TSocket socket, bool isAES) : AbsPipeLine(i
|
||||||
System.Buffer.BlockCopy(buffer, 0, nbuffer, 0, receiveResult.Count);
|
System.Buffer.BlockCopy(buffer, 0, nbuffer, 0, receiveResult.Count);
|
||||||
if (IsAES)
|
if (IsAES)
|
||||||
{
|
{
|
||||||
var nnbuffer = AESHelper.DecryptStringFromBytes_Aes(buffer);
|
//var msg1 = Encoding.UTF8.GetString(nbuffer);
|
||||||
|
//var n1Buffler = Encoding.UTF8.GetBytes(msg1);
|
||||||
|
var nnbuffer = AESHelper.DecryptStringFromBytes_Aes(nbuffer);
|
||||||
receiveCb(Encoding.UTF8.GetBytes(nnbuffer));
|
receiveCb(Encoding.UTF8.GetBytes(nnbuffer));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -129,24 +125,55 @@ public class WebSocPipeLine<TSocket>(TSocket socket, bool isAES) : AbsPipeLine(i
|
||||||
// Body = CloseReason ?? ""
|
// Body = CloseReason ?? ""
|
||||||
// }
|
// }
|
||||||
//);
|
//);
|
||||||
await Socket.CloseAsync(
|
if (Encoding.UTF8.GetBytes(CloseReason ?? "").Length > 120)
|
||||||
WebSocketCloseStatus.NormalClosure,
|
{
|
||||||
CloseReason,
|
await SendMsg(
|
||||||
CancellationToken.None
|
new SyncMsg
|
||||||
);
|
{
|
||||||
|
Type = SyncMsgType.Error,
|
||||||
|
Step = SyncProcessStep.CloseError,
|
||||||
|
Body = CloseReason ?? ""
|
||||||
|
}
|
||||||
|
);
|
||||||
|
await Socket.CloseAsync(
|
||||||
|
WebSocketCloseStatus.NormalClosure,
|
||||||
|
"查看上一条错误信息!",
|
||||||
|
CancellationToken.None
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await Socket.CloseAsync(
|
||||||
|
WebSocketCloseStatus.NormalClosure,
|
||||||
|
CloseReason,
|
||||||
|
CancellationToken.None
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task SendMsg(SyncMsg msg)
|
public override async Task SendMsg(SyncMsg msg)
|
||||||
{
|
{
|
||||||
string msgStr = JsonSerializer.Serialize(msg);
|
string msgStr = JsonSerializer.Serialize(msg);
|
||||||
await Socket.SendAsync(
|
var it = AESHelper.EncryptStringToBytes_Aes(msgStr);
|
||||||
IsAES
|
//var xx = new ArraySegment<byte>(it);
|
||||||
? AESHelper.EncryptStringToBytes_Aes(msgStr)
|
if (IsAES)
|
||||||
: new ArraySegment<byte>(Encoding.UTF8.GetBytes(msgStr)),
|
{
|
||||||
WebSocketMessageType.Text,
|
await Socket.SendAsync(
|
||||||
true,
|
new ArraySegment<byte>(it),
|
||||||
CancellationToken.None
|
WebSocketMessageType.Binary,
|
||||||
);
|
true,
|
||||||
|
CancellationToken.None
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await Socket.SendAsync(
|
||||||
|
new ArraySegment<byte>(Encoding.UTF8.GetBytes(msgStr)),
|
||||||
|
WebSocketMessageType.Text,
|
||||||
|
true,
|
||||||
|
CancellationToken.None
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,8 @@ public enum SyncProcessStep
|
||||||
DiffFileAndPack = 3,
|
DiffFileAndPack = 3,
|
||||||
PackSqlServer = 4,
|
PackSqlServer = 4,
|
||||||
UploadAndUnpack = 5,
|
UploadAndUnpack = 5,
|
||||||
Publish = 6
|
Publish = 6,
|
||||||
|
CloseError = 7
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SyncMsg
|
public class SyncMsg
|
||||||
|
|
|
@ -55,7 +55,7 @@ namespace LocalServer.Controllers
|
||||||
await Factory.CreateLocalSyncServer(
|
await Factory.CreateLocalSyncServer(
|
||||||
pipeLine,
|
pipeLine,
|
||||||
Name,
|
Name,
|
||||||
new WebSocPipeLine<ClientWebSocket>(new ClientWebSocket(), false)
|
new WebSocPipeLine<ClientWebSocket>(new ClientWebSocket(), true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -124,7 +124,7 @@ public class ConnectAuthorityHelper(LocalSyncServer context)
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
await Context.LocalPipe.Close(e.Message);
|
Context.Close(e.Message);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -301,6 +301,7 @@ public class DiffFileAndPackHelper(LocalSyncServer context)
|
||||||
e.DiffDirInfo.WriteByThisInfo(PackOp);
|
e.DiffDirInfo.WriteByThisInfo(PackOp);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Context.LocalPipe.SendMsg(CreateMsg("文件差异比较成功!")).Wait();
|
||||||
var n = new DeployMSSqlHelper(Context);
|
var n = new DeployMSSqlHelper(Context);
|
||||||
Context.SetStateHelper(n);
|
Context.SetStateHelper(n);
|
||||||
n.PackSqlServerProcess();
|
n.PackSqlServerProcess();
|
||||||
|
@ -414,8 +415,6 @@ public class UploadPackedHelper(LocalSyncServer context)
|
||||||
)
|
)
|
||||||
.Wait();
|
.Wait();
|
||||||
Context.LocalPipe.SendMsg(CreateMsg("上传完成!")).Wait();
|
Context.LocalPipe.SendMsg(CreateMsg("上传完成!")).Wait();
|
||||||
|
|
||||||
var x = Context.GetStateHelper().Step;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void HandleLocalMsg(SyncMsg msg)
|
protected override void HandleLocalMsg(SyncMsg msg)
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"AllowedHosts": "*",
|
"AllowedHosts": "*",
|
||||||
"TempDir": "D:/TempPack",
|
"TempDir": "D:\\FileSyncTest\\stemp",
|
||||||
"SqlPackageAbPath": "C:\\Users\\ZHAOLEI\\.dotnet\\tools\\sqlpackage.exe",
|
"SqlPackageAbPath": "C:\\Users\\ZHAOLEI\\.dotnet\\tools\\sqlpackage.exe",
|
||||||
//"MsdeployAbPath": "C:\\Program Files\\IIS\\Microsoft Web Deploy V3\\msdeploy.exe",
|
//"MsdeployAbPath": "C:\\Program Files\\IIS\\Microsoft Web Deploy V3\\msdeploy.exe",
|
||||||
"MSBuildAbPath": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\MSBuild\\Current\\Bin\\amd64\\MSBuild.exe"
|
"MSBuildAbPath": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\MSBuild\\Current\\Bin\\amd64\\MSBuild.exe"
|
||||||
|
|
|
@ -24,6 +24,8 @@ public class SyncFilesController(RemoteSyncServerFactory factory, SqliteDbContex
|
||||||
var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync();
|
var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync();
|
||||||
var pipeLine = new WebSocPipeLine<WebSocket>(webSocket, true);
|
var pipeLine = new WebSocPipeLine<WebSocket>(webSocket, true);
|
||||||
await Factory.CreateRemoteSyncServer(pipeLine, Name);
|
await Factory.CreateRemoteSyncServer(pipeLine, Name);
|
||||||
|
|
||||||
|
var x = 11;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -195,10 +197,7 @@ public class SyncFilesController(RemoteSyncServerFactory factory, SqliteDbContex
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
return StatusCode(
|
return StatusCode(500, new { IsSuccess = false, Message = $"上传文件失败: {ex.Message}" });
|
||||||
500,
|
|
||||||
new { IsSuccess = false, Message = $"Internal server error: {ex.Message}" }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,13 @@ RemoteSyncServerFactory.NamePwd =
|
||||||
[
|
[
|
||||||
.. (builder.Configuration.GetSection("NamePwds").Get<Tuple<string, string>[]>() ?? [])
|
.. (builder.Configuration.GetSection("NamePwds").Get<Tuple<string, string>[]>() ?? [])
|
||||||
];
|
];
|
||||||
|
foreach (var x in builder.Configuration.GetSection("NamePwds").GetChildren())
|
||||||
|
{
|
||||||
|
var it = x.GetChildren();
|
||||||
|
RemoteSyncServerFactory.NamePwd.Add(
|
||||||
|
new Tuple<string, string>(it.ElementAt(0).Value ?? "", it.ElementAt(1).Value ?? "")
|
||||||
|
);
|
||||||
|
}
|
||||||
RemoteSyncServer.SqlPackageAbPath =
|
RemoteSyncServer.SqlPackageAbPath =
|
||||||
builder.Configuration["SqlPackageAbPath"]
|
builder.Configuration["SqlPackageAbPath"]
|
||||||
?? "C:\\Users\\ZHAOLEI\\.dotnet\\tools\\sqlpackage.exe";
|
?? "C:\\Users\\ZHAOLEI\\.dotnet\\tools\\sqlpackage.exe";
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"AllowedHosts": "*",
|
"AllowedHosts": "*",
|
||||||
"TempDir":"D:/TempPack2",
|
"TempDir": "D:\\FileSyncTest\\dtemp",
|
||||||
"NamePwds":[
|
"NamePwds": [
|
||||||
["test","testpwd"]
|
[ "Test", "t123" ]
|
||||||
],
|
],
|
||||||
"SqlPackageAbPath": "C:\\Users\\ZHAOLEI\\.dotnet\\tools\\sqlpackage.exe",
|
"SqlPackageAbPath": "C:\\Users\\ZHAOLEI\\.dotnet\\tools\\sqlpackage.exe"
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,9 @@ const options = ref({
|
||||||
lineHeight: 24,
|
lineHeight: 24,
|
||||||
tabSize: 2,
|
tabSize: 2,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
let Pipe = null
|
||||||
|
const Msgs = ref([])
|
||||||
const code = ref(`
|
const code = ref(`
|
||||||
config = {
|
config = {
|
||||||
Name: "Test",
|
Name: "Test",
|
||||||
|
@ -51,7 +54,31 @@ config = {
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
`)
|
`)
|
||||||
|
var CStatus = ref('None')
|
||||||
|
function publishCB(MsgIt) {
|
||||||
|
|
||||||
|
if (MsgIt.Type == 2) {
|
||||||
|
Msgs.value[Msgs.value.length - 1] = MsgIt
|
||||||
|
} else {
|
||||||
|
Msgs.value.push(MsgIt)
|
||||||
|
}
|
||||||
|
if (MsgIt.Step == 6) {
|
||||||
|
if (MsgIt.Body == "发布完成!") {
|
||||||
|
CStatus.value = 'Success'
|
||||||
|
Pipe.ClosePipe()
|
||||||
|
window.alert("正确:发布完成!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (MsgIt.Step == 8) {
|
||||||
|
if (CStatus.value != "Success") {
|
||||||
|
window.alert("失败:请查看错误信息!")
|
||||||
|
}
|
||||||
|
CStatus.value = "None"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
function submit() {
|
function submit() {
|
||||||
|
Msgs.value = []
|
||||||
var config = {}
|
var config = {}
|
||||||
try {
|
try {
|
||||||
eval(code.value)
|
eval(code.value)
|
||||||
|
@ -60,8 +87,9 @@ function submit() {
|
||||||
}
|
}
|
||||||
cacheConfig.value[config.Name] = config
|
cacheConfig.value[config.Name] = config
|
||||||
updateStorage()
|
updateStorage()
|
||||||
var p = new ConnectPipe()
|
Pipe = new ConnectPipe()
|
||||||
p.OpenPipe(config,()=>{})
|
Pipe.OpenPipe(config, publishCB)
|
||||||
|
CStatus.value = "Process"
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
|
@ -89,9 +117,6 @@ function updateStorage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function publishCB(MsgIt) {
|
|
||||||
|
|
||||||
}
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
var cacheConfigStr = localStorage.getItem('config')
|
var cacheConfigStr = localStorage.getItem('config')
|
||||||
if (cacheConfigStr) {
|
if (cacheConfigStr) {
|
||||||
|
@ -111,11 +136,17 @@ onMounted(() => {
|
||||||
v-model:value="code"></MonacoEditor>
|
v-model:value="code"></MonacoEditor>
|
||||||
<div style="width: 800px;height: 700px;background-color: #1e1e1e;">
|
<div style="width: 800px;height: 700px;background-color: #1e1e1e;">
|
||||||
发布日志
|
发布日志
|
||||||
|
|
||||||
|
<p style="text-align: left;border: 1px solid gray;margin: 5px;" v-for="msg in Msgs">
|
||||||
|
<span :style="{ width: '100px', color: msg.Step > 6 ? 'red' : 'green' }">[{{ msg.Step
|
||||||
|
> 6 ? msg.Step > 7 ? "关闭" : "错误" : `${msg.Step}/${6}`}}]</span>
|
||||||
|
<span style="margin-left: 5px ;">{{ msg.Body }}</span>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<button style="margin-top: 20px;" @click="submit">发布</button>
|
<button :disabled="CStatus != 'None'" style="margin-top: 20px;" @click="submit">发布</button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|
|
@ -6,30 +6,45 @@ class ConnectPipe {
|
||||||
// this.#websocket = new WebSocket(`ws://${window.location.host}`)
|
// this.#websocket = new WebSocket(`ws://${window.location.host}`)
|
||||||
}
|
}
|
||||||
OpenPipe(config, MsgCb) {
|
OpenPipe(config, MsgCb) {
|
||||||
this.config = config;
|
|
||||||
|
|
||||||
// var webSocUrl = `ws://${window.location.host}:${window.location.port}/websoc?Name=${config.Name}`
|
// var webSocUrl = `ws://${window.location.host}:${window.location.port}/websoc?Name=${config.Name}`
|
||||||
var webSocUrl = "ws://127.0.0.1:6818/websoc?Name=Test"
|
var webSocUrl = "ws://127.0.0.1:6818/websoc?Name=Test";
|
||||||
this.#websocket = new WebSocket(webSocUrl);
|
this.#websocket = new WebSocket(webSocUrl);
|
||||||
this.#websocket.onopen = (event) => {
|
this.#websocket.onopen = (event) => {
|
||||||
// console.warn("websocket connected!");
|
var starter = {
|
||||||
this.#websocket.send(JSON.stringify(this.config));
|
Body: JSON.stringify(config),
|
||||||
|
Type: 1,
|
||||||
|
Step: 1,
|
||||||
|
};
|
||||||
|
// console.warn("websocket connected!");
|
||||||
|
this.#websocket.send(JSON.stringify(starter));
|
||||||
};
|
};
|
||||||
this.#websocket.onmessage = (event) => {
|
this.#websocket.onmessage = (event) => {
|
||||||
console.log(event.data)
|
// console.log(event.data);
|
||||||
|
MsgCb(JSON.parse(event.data))
|
||||||
};
|
};
|
||||||
this.#websocket.onclose = (event) => {
|
this.#websocket.onclose = (event) => {
|
||||||
console.warn(event.reason)
|
|
||||||
|
console.warn(event)
|
||||||
|
MsgCb({
|
||||||
|
Type: 0,
|
||||||
|
Step: 8,
|
||||||
|
Body:event.reason
|
||||||
|
})
|
||||||
|
|
||||||
};
|
};
|
||||||
this.#websocket.onerror = (e) => {
|
this.#websocket.onerror = (e) => {
|
||||||
console.error(e)
|
console.error(e);
|
||||||
if (this.#websocket.readyState) {
|
MsgCb({
|
||||||
//bla bla
|
Type: 0,
|
||||||
}
|
Body: "异常错误,查看 Console",
|
||||||
|
Step: 7,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
ClosePipe() {
|
||||||
|
this.#websocket.close();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default ConnectPipe;
|
export default ConnectPipe;
|
||||||
|
|
Loading…
Reference in a new issue