From 3f67529e0f492f30851f091fea7f97a01cb502e5 Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期二, 03 二月 2026 11:05:23 +0800
Subject: [PATCH] 添加机器人/套接字任务支持;更新枚举与 .gitignore 文件
---
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/TaskService.cs | 39 +
.gitignore | 9
Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/v18/DocumentLayout.json | 228 +++++++--
项目资料/设备协议/高常温堆垛机与输送线/堆垛机与上位机交互信息.xlsx | 0
Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/CodeChunks.db | 0
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineJob/ConveyorLineTaskCommand.cs | 2
项目资料/设备协议/拘束机对接协议/拘束机对接协议-汇川5U.xlsx | 0
Code/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/18.0.988.22099/SemanticSymbols.db | 0
Code/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/v18/DocumentLayout.json | 2
项目资料/设备协议/分容柜接口协议/化成分容柜接口协议1.1.xls | 0
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/SocketServerOptions.cs | 55 ++
项目资料/设备协议/高常温堆垛机与输送线/WCS-输送线对接协议说明-V260202.docx | 0
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/TaskEnum/TaskTypeEnum.cs | 6
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json | 13
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/SocketServerHostedService.cs | 35 +
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.cs | 63 ++
项目资料/设备协议/机械手协议/交互流程表(1).xlsx | 0
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/TaskEnum/TaskStatusEnum.cs | 41 +
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/FormationStackerCraneJob/FormationStackerCraneTaskCommand.cs | 2
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Program.cs | 3
项目资料/设备协议/化成库堆垛机协议/PlcLink_堆垛机项目.xlsx | 0
Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/appsettings.json | 2
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Core/Enums/RouterInOutType.cs | 4
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Robot/RobotCraneDevice.cs | 16
Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/SemanticSymbols.db | 0
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Dispose.cs | 18
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotJob.cs | 297 ++++++++++++
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineJob/CommonConveyorLineJob.cs | 5
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/TaskEnum/TaskEnumHelper.cs | 8
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Clients.cs | 94 +++
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Server.cs | 164 ++++++
/dev/null | 0
项目资料/需要对接的设备信息/陕煤硬件设备对接.xls | 0
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_ITaskInfoService/ITaskService.cs | 14
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/QuartzNet/QuartzNetExtension.cs | 133 ++--
项目资料/设备协议/高常温堆垛机与输送线/WCS输送对接地址表.xlsx | 0
Code/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/18.0.988.22099/CodeChunks.db | 0
Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Messaging.cs | 175 +++++++
38 files changed, 1,287 insertions(+), 141 deletions(-)
diff --git a/.gitignore b/.gitignore
index 413dc58..5f351a2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -396,3 +396,12 @@
Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/CodeChunks.db
Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/SemanticSymbols.db
Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/v18/DocumentLayout.json
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/0272CC30DEEFE244BD51E6AD406E11CA/2841A59D75EBB84B92E801077DB88BA4/2C0CE2B065FDC35419958E23E64252B6
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/0272CC30DEEFE244BD51E6AD406E11CA/2841A59D75EBB84B92E801077DB88BA4/48EC962EDBF70FC42B1C2628B04CD8DB
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/0272CC30DEEFE244BD51E6AD406E11CA/2841A59D75EBB84B92E801077DB88BA4/5E1AAAA5BACAE48E8D86545A7EFEB583
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/0272CC30DEEFE244BD51E6AD406E11CA/2841A59D75EBB84B92E801077DB88BA4/86F5B814633CDE33B1AD91E6EF4A0AD5
+Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots/0272CC30DEEFE244BD51E6AD406E11CA/2841A59D75EBB84B92E801077DB88BA4/915864713A7919AB693EE494165DF029
+/Code/WCS/WIDESEAWCS_Server/.vs/CopilotSnapshots
+/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/copilot-chat
+/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices
+/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices
diff --git a/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/CodeChunks.db b/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/CodeChunks.db
index d3ffae8..60ffaa7 100644
--- a/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/CodeChunks.db
+++ b/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/CodeChunks.db
Binary files differ
diff --git a/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/SemanticSymbols.db b/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/SemanticSymbols.db
index 5865a4f..3118942 100644
--- a/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/SemanticSymbols.db
+++ b/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/CopilotIndices/18.0.988.22099/SemanticSymbols.db
Binary files differ
diff --git a/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/v18/DocumentLayout.json b/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/v18/DocumentLayout.json
index 1fae43c..9aa49c8 100644
--- a/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/v18/DocumentLayout.json
+++ b/Code/WCS/WIDESEAWCS_Server/.vs/WIDESEAWCS_Server/v18/DocumentLayout.json
@@ -3,28 +3,56 @@
"WorkspaceRootPath": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\",
"Documents": [
{
- "AbsoluteMoniker": "D:0:0:{6236BFFF-173D-44A8-9FC3-7C001EA30347}|WIDESEAWCS_QuartzJob\\WIDESEAWCS_QuartzJob.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_quartzjob\\stackercrane\\spec\\speformationstackercrane.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
- "RelativeMoniker": "D:0:0:{6236BFFF-173D-44A8-9FC3-7C001EA30347}|WIDESEAWCS_QuartzJob\\WIDESEAWCS_QuartzJob.csproj|solutionrelative:wideseawcs_quartzjob\\stackercrane\\spec\\speformationstackercrane.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ "AbsoluteMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_tasks\\robotjob\\robotjob.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|solutionrelative:wideseawcs_tasks\\robotjob\\robotjob.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
- "AbsoluteMoniker": "D:0:0:{6236BFFF-173D-44A8-9FC3-7C001EA30347}|WIDESEAWCS_QuartzJob\\WIDESEAWCS_QuartzJob.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_quartzjob\\stackercrane\\enum\\formationstackercranestatus.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
- "RelativeMoniker": "D:0:0:{6236BFFF-173D-44A8-9FC3-7C001EA30347}|WIDESEAWCS_QuartzJob\\WIDESEAWCS_QuartzJob.csproj|solutionrelative:wideseawcs_quartzjob\\stackercrane\\enum\\formationstackercranestatus.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ "AbsoluteMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_tasks\\socketserver\\tcpsocketserver.messaging.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|solutionrelative:wideseawcs_tasks\\socketserver\\tcpsocketserver.messaging.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
- "AbsoluteMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_tasks\\formationstackercranejob\\formationstackercranedbname.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
- "RelativeMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|solutionrelative:wideseawcs_tasks\\formationstackercranejob\\formationstackercranedbname.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ "AbsoluteMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_tasks\\socketserver\\tcpsocketserver.server.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|solutionrelative:wideseawcs_tasks\\socketserver\\tcpsocketserver.server.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
- "AbsoluteMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_tasks\\formationstackercranejob\\formationstackercranetaskcommand.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
- "RelativeMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|solutionrelative:wideseawcs_tasks\\formationstackercranejob\\formationstackercranetaskcommand.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ "AbsoluteMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_tasks\\socketserver\\tcpsocketserver.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|solutionrelative:wideseawcs_tasks\\socketserver\\tcpsocketserver.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_tasks\\socketserver\\tcpsocketserver.clients.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|solutionrelative:wideseawcs_tasks\\socketserver\\tcpsocketserver.clients.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{83F18A31-5983-4587-A0B2-414BF70E50B5}|WIDESEAWCS_TaskInfoService\\WIDESEAWCS_TaskInfoService.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_taskinfoservice\\taskservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{83F18A31-5983-4587-A0B2-414BF70E50B5}|WIDESEAWCS_TaskInfoService\\WIDESEAWCS_TaskInfoService.csproj|solutionrelative:wideseawcs_taskinfoservice\\taskservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{9FBC654C-51DE-422D-9E1E-6A38268DE1E2}|WIDESEAWCS_Common\\WIDESEAWCS_Common.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_common\\taskenum\\taskstatusenum.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{9FBC654C-51DE-422D-9E1E-6A38268DE1E2}|WIDESEAWCS_Common\\WIDESEAWCS_Common.csproj|solutionrelative:wideseawcs_common\\taskenum\\taskstatusenum.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{9FBC654C-51DE-422D-9E1E-6A38268DE1E2}|WIDESEAWCS_Common\\WIDESEAWCS_Common.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_common\\taskenum\\taskenumhelper.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{9FBC654C-51DE-422D-9E1E-6A38268DE1E2}|WIDESEAWCS_Common\\WIDESEAWCS_Common.csproj|solutionrelative:wideseawcs_common\\taskenum\\taskenumhelper.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{9FBC654C-51DE-422D-9E1E-6A38268DE1E2}|WIDESEAWCS_Common\\WIDESEAWCS_Common.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_common\\taskenum\\tasktypeenum.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{9FBC654C-51DE-422D-9E1E-6A38268DE1E2}|WIDESEAWCS_Common\\WIDESEAWCS_Common.csproj|solutionrelative:wideseawcs_common\\taskenum\\tasktypeenum.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_tasks\\stackercranejob\\commonstackercranejob.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|solutionrelative:wideseawcs_tasks\\stackercranejob\\commonstackercranejob.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{7279A2AE-8D1F-4E66-A73A-01AF7927A336}|WIDESEAWCS_ITaskInfoService\\WIDESEAWCS_ITaskInfoService.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_itaskinfoservice\\itaskservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{7279A2AE-8D1F-4E66-A73A-01AF7927A336}|WIDESEAWCS_ITaskInfoService\\WIDESEAWCS_ITaskInfoService.csproj|solutionrelative:wideseawcs_itaskinfoservice\\itaskservice.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_tasks\\formationstackercranejob\\formationcommonstackercranejob.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|solutionrelative:wideseawcs_tasks\\formationstackercranejob\\formationcommonstackercranejob.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
- "AbsoluteMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_tasks\\stackercranejob\\commonstackercranejob.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
- "RelativeMoniker": "D:0:0:{294E4915-0241-4C8C-BA99-7588B945863A}|WIDESEAWCS_Tasks\\WIDESEAWCS_Tasks.csproj|solutionrelative:wideseawcs_tasks\\stackercranejob\\commonstackercranejob.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ "AbsoluteMoniker": "D:0:0:{6236BFFF-173D-44A8-9FC3-7C001EA30347}|WIDESEAWCS_QuartzJob\\WIDESEAWCS_QuartzJob.csproj|d:\\git\\shanmeixinnengyuan\\code\\wcs\\wideseawcs_server\\wideseawcs_quartzjob\\quartznet\\quartznetextension.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{6236BFFF-173D-44A8-9FC3-7C001EA30347}|WIDESEAWCS_QuartzJob\\WIDESEAWCS_QuartzJob.csproj|solutionrelative:wideseawcs_quartzjob\\quartznet\\quartznetextension.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
}
],
"DocumentGroupContainers": [
@@ -34,7 +62,7 @@
"DocumentGroups": [
{
"DockedWidth": 200,
- "SelectedChildIndex": 6,
+ "SelectedChildIndex": 11,
"Children": [
{
"$type": "Bookmark",
@@ -50,80 +78,164 @@
},
{
"$type": "Document",
- "DocumentIndex": 3,
- "Title": "FormationStackerCraneTaskCommand.cs",
- "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\FormationStackerCraneJob\\FormationStackerCraneTaskCommand.cs",
- "RelativeDocumentMoniker": "WIDESEAWCS_Tasks\\FormationStackerCraneJob\\FormationStackerCraneTaskCommand.cs",
- "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\FormationStackerCraneJob\\FormationStackerCraneTaskCommand.cs",
- "RelativeToolTip": "WIDESEAWCS_Tasks\\FormationStackerCraneJob\\FormationStackerCraneTaskCommand.cs",
- "ViewState": "AgIAAEcAAAAAAAAAAAAiwDAAAAAVAAAAAAAAAA==",
+ "DocumentIndex": 8,
+ "Title": "TaskTypeEnum.cs",
+ "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Common\\TaskEnum\\TaskTypeEnum.cs",
+ "RelativeDocumentMoniker": "WIDESEAWCS_Common\\TaskEnum\\TaskTypeEnum.cs",
+ "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Common\\TaskEnum\\TaskTypeEnum.cs",
+ "RelativeToolTip": "WIDESEAWCS_Common\\TaskEnum\\TaskTypeEnum.cs",
+ "ViewState": "AgIAADYAAAAAAAAAAAAuwEwAAAAZAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
- "WhenOpened": "2026-01-29T09:17:51.622Z",
- "EditorCaption": ""
+ "WhenOpened": "2026-02-02T07:43:32.381Z"
},
{
"$type": "Document",
- "DocumentIndex": 2,
- "Title": "FormationStackerCraneDBName.cs",
- "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\FormationStackerCraneJob\\FormationStackerCraneDBName.cs",
- "RelativeDocumentMoniker": "WIDESEAWCS_Tasks\\FormationStackerCraneJob\\FormationStackerCraneDBName.cs",
- "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\FormationStackerCraneJob\\FormationStackerCraneDBName.cs",
- "RelativeToolTip": "WIDESEAWCS_Tasks\\FormationStackerCraneJob\\FormationStackerCraneDBName.cs",
- "ViewState": "AgIAAAAAAAAAAAAAAAAAAC4AAAAQAAAAAAAAAA==",
+ "DocumentIndex": 7,
+ "Title": "TaskEnumHelper.cs",
+ "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Common\\TaskEnum\\TaskEnumHelper.cs",
+ "RelativeDocumentMoniker": "WIDESEAWCS_Common\\TaskEnum\\TaskEnumHelper.cs",
+ "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Common\\TaskEnum\\TaskEnumHelper.cs",
+ "RelativeToolTip": "WIDESEAWCS_Common\\TaskEnum\\TaskEnumHelper.cs",
+ "ViewState": "AgIAABEAAAAAAAAAAAApwBgAAAAkAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
- "WhenOpened": "2026-01-29T09:13:24.922Z",
- "EditorCaption": ""
+ "WhenOpened": "2026-02-02T07:13:45.107Z"
},
{
"$type": "Document",
- "DocumentIndex": 1,
- "Title": "FormationStackerCraneStatus.cs",
- "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_QuartzJob\\StackerCrane\\Enum\\FormationStackerCraneStatus.cs",
- "RelativeDocumentMoniker": "WIDESEAWCS_QuartzJob\\StackerCrane\\Enum\\FormationStackerCraneStatus.cs",
- "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_QuartzJob\\StackerCrane\\Enum\\FormationStackerCraneStatus.cs",
- "RelativeToolTip": "WIDESEAWCS_QuartzJob\\StackerCrane\\Enum\\FormationStackerCraneStatus.cs",
- "ViewState": "AgIAAEAAAAAAAAAAAAArwFQAAAAQAAAAAAAAAA==",
+ "DocumentIndex": 5,
+ "Title": "TaskService.cs",
+ "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_TaskInfoService\\TaskService.cs",
+ "RelativeDocumentMoniker": "WIDESEAWCS_TaskInfoService\\TaskService.cs",
+ "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_TaskInfoService\\TaskService.cs",
+ "RelativeToolTip": "WIDESEAWCS_TaskInfoService\\TaskService.cs",
+ "ViewState": "AgIAAGECAAAAAAAAAAAvwHMCAADaAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
- "WhenOpened": "2026-01-29T03:35:09.011Z",
- "EditorCaption": ""
+ "WhenOpened": "2026-02-02T07:10:41.925Z"
},
{
"$type": "Document",
- "DocumentIndex": 0,
- "Title": "SpeFormationStackerCrane.cs",
- "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_QuartzJob\\StackerCrane\\Spec\\SpeFormationStackerCrane.cs",
- "RelativeDocumentMoniker": "WIDESEAWCS_QuartzJob\\StackerCrane\\Spec\\SpeFormationStackerCrane.cs",
- "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_QuartzJob\\StackerCrane\\Spec\\SpeFormationStackerCrane.cs",
- "RelativeToolTip": "WIDESEAWCS_QuartzJob\\StackerCrane\\Spec\\SpeFormationStackerCrane.cs",
- "ViewState": "AgIAAN8AAAAAAAAAAAAnwPEAAAAUAAAAAAAAAA==",
- "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
- "WhenOpened": "2026-01-29T03:12:53.832Z",
- "EditorCaption": ""
- },
- {
- "$type": "Document",
- "DocumentIndex": 4,
+ "DocumentIndex": 11,
"Title": "FormationCommonStackerCraneJob.cs",
"DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\FormationStackerCraneJob\\FormationCommonStackerCraneJob.cs",
"RelativeDocumentMoniker": "WIDESEAWCS_Tasks\\FormationStackerCraneJob\\FormationCommonStackerCraneJob.cs",
"ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\FormationStackerCraneJob\\FormationCommonStackerCraneJob.cs",
"RelativeToolTip": "WIDESEAWCS_Tasks\\FormationStackerCraneJob\\FormationCommonStackerCraneJob.cs",
- "ViewState": "AgIAAEEAAAAAAAAAAAAqwFQAAAAVAAAAAAAAAA==",
+ "ViewState": "AgIAAFkAAAAAAAAAAAAWwG0AAAAkAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
- "WhenOpened": "2026-01-29T03:12:40.035Z",
- "EditorCaption": ""
+ "WhenOpened": "2026-02-02T07:08:40.6Z"
},
{
"$type": "Document",
- "DocumentIndex": 5,
+ "DocumentIndex": 10,
+ "Title": "ITaskService.cs",
+ "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_ITaskInfoService\\ITaskService.cs",
+ "RelativeDocumentMoniker": "WIDESEAWCS_ITaskInfoService\\ITaskService.cs",
+ "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_ITaskInfoService\\ITaskService.cs",
+ "RelativeToolTip": "WIDESEAWCS_ITaskInfoService\\ITaskService.cs",
+ "ViewState": "AgIAACAAAAAAAAAAAAAjwDUAAAAnAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-02-02T07:08:06.875Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 6,
+ "Title": "TaskStatusEnum.cs",
+ "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Common\\TaskEnum\\TaskStatusEnum.cs",
+ "RelativeDocumentMoniker": "WIDESEAWCS_Common\\TaskEnum\\TaskStatusEnum.cs",
+ "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Common\\TaskEnum\\TaskStatusEnum.cs",
+ "RelativeToolTip": "WIDESEAWCS_Common\\TaskEnum\\TaskStatusEnum.cs",
+ "ViewState": "AgIAAJYAAAAAAAAAAAAAwJ8AAAAWAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-02-02T07:05:39.323Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 9,
"Title": "CommonStackerCraneJob.cs",
"DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\StackerCraneJob\\CommonStackerCraneJob.cs",
"RelativeDocumentMoniker": "WIDESEAWCS_Tasks\\StackerCraneJob\\CommonStackerCraneJob.cs",
"ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\StackerCraneJob\\CommonStackerCraneJob.cs",
"RelativeToolTip": "WIDESEAWCS_Tasks\\StackerCraneJob\\CommonStackerCraneJob.cs",
- "ViewState": "AgIAAJ4AAAAAAAAAAAAkwLQAAAATAAAAAAAAAA==",
+ "ViewState": "AgIAAGwAAAAAAAAAAAApwH4AAAA1AAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
- "WhenOpened": "2026-01-29T02:59:35.12Z",
+ "WhenOpened": "2026-02-02T06:13:24.454Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 12,
+ "Title": "QuartzNetExtension.cs",
+ "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_QuartzJob\\QuartzNet\\QuartzNetExtension.cs",
+ "RelativeDocumentMoniker": "WIDESEAWCS_QuartzJob\\QuartzNet\\QuartzNetExtension.cs",
+ "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_QuartzJob\\QuartzNet\\QuartzNetExtension.cs",
+ "RelativeToolTip": "WIDESEAWCS_QuartzJob\\QuartzNet\\QuartzNetExtension.cs",
+ "ViewState": "AgIAAHAAAAAAAAAAAAAAAIYAAABzAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-02-02T06:11:52.348Z"
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 0,
+ "Title": "RobotJob.cs",
+ "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\RobotJob\\RobotJob.cs",
+ "RelativeDocumentMoniker": "WIDESEAWCS_Tasks\\RobotJob\\RobotJob.cs",
+ "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\RobotJob\\RobotJob.cs",
+ "RelativeToolTip": "WIDESEAWCS_Tasks\\RobotJob\\RobotJob.cs",
+ "ViewState": "AgIAACMAAAAAAAAAAAAAwD4AAABRAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-02-02T03:52:06.502Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 1,
+ "Title": "TcpSocketServer.Messaging.cs",
+ "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\SocketServer\\TcpSocketServer.Messaging.cs",
+ "RelativeDocumentMoniker": "WIDESEAWCS_Tasks\\SocketServer\\TcpSocketServer.Messaging.cs",
+ "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\SocketServer\\TcpSocketServer.Messaging.cs",
+ "RelativeToolTip": "WIDESEAWCS_Tasks\\SocketServer\\TcpSocketServer.Messaging.cs",
+ "ViewState": "AgIAACMAAAAAAAAAAAAkwD4AAAAQAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-02-02T03:38:35.325Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 3,
+ "Title": "TcpSocketServer.cs",
+ "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\SocketServer\\TcpSocketServer.cs",
+ "RelativeDocumentMoniker": "WIDESEAWCS_Tasks\\SocketServer\\TcpSocketServer.cs",
+ "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\SocketServer\\TcpSocketServer.cs",
+ "RelativeToolTip": "WIDESEAWCS_Tasks\\SocketServer\\TcpSocketServer.cs",
+ "ViewState": "AgIAACQAAAAAAAAAAAAowDYAAAA/AAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-02-02T03:37:56.495Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 4,
+ "Title": "TcpSocketServer.Clients.cs",
+ "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\SocketServer\\TcpSocketServer.Clients.cs",
+ "RelativeDocumentMoniker": "WIDESEAWCS_Tasks\\SocketServer\\TcpSocketServer.Clients.cs",
+ "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\SocketServer\\TcpSocketServer.Clients.cs",
+ "RelativeToolTip": "WIDESEAWCS_Tasks\\SocketServer\\TcpSocketServer.Clients.cs",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAAE0AAAAhAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-02-02T03:37:53.636Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 2,
+ "Title": "TcpSocketServer.Server.cs",
+ "DocumentMoniker": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\SocketServer\\TcpSocketServer.Server.cs",
+ "RelativeDocumentMoniker": "WIDESEAWCS_Tasks\\SocketServer\\TcpSocketServer.Server.cs",
+ "ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WCS\\WIDESEAWCS_Server\\WIDESEAWCS_Tasks\\SocketServer\\TcpSocketServer.Server.cs",
+ "RelativeToolTip": "WIDESEAWCS_Tasks\\SocketServer\\TcpSocketServer.Server.cs",
+ "ViewState": "AgIAAFMAAAAAAAAAAAAQwGwAAAAAAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-02-02T03:37:49.526Z",
"EditorCaption": ""
}
]
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/TaskEnum/TaskEnumHelper.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/TaskEnum/TaskEnumHelper.cs
index 6ea2329..ccf165e 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/TaskEnum/TaskEnumHelper.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/TaskEnum/TaskEnumHelper.cs
@@ -32,7 +32,7 @@
return TaskTypeGroup.OutbondGroup;
}
// 灏濊瘯灏嗕换鍔$被鍨嬭浆鎹负TaskInStatusEnum鏋氫妇绫诲瀷锛屽鏋滄垚鍔燂紝杩斿洖InboundGroup
- else if (!int.TryParse(Enum.Parse<TaskInStatusEnum>(taskTypeStr).ToString(), out result))
+ else if (!int.TryParse(Enum.Parse<TaskOutboundTypeEnum>(taskTypeStr).ToString(), out result))
{
return TaskTypeGroup.InboundGroup;
}
@@ -76,6 +76,12 @@
// 鑾峰彇TaskOutStatusEnum鏋氫妇绫诲瀷鐨勭储寮曞垪琛�
return type.GetEnumIndexList().Where(x => x > currentStatus && x < (int)TaskOutStatusEnum.OutFinish).OrderBy(x => x).FirstOrDefault();
}
+ // 濡傛灉type鏄疶askRobotStatusEnum鏋氫妇绫诲瀷
+ else if (type == typeof(TaskRobotStatusEnum))
+ {
+ // 鑾峰彇TaskOutStatusEnum鏋氫妇绫诲瀷鐨勭储寮曞垪琛�
+ return type.GetEnumIndexList().Where(x => x > currentStatus && x < (int)TaskRobotStatusEnum.RobotFinish).OrderBy(x => x).FirstOrDefault();
+ }
// 濡傛灉浠ヤ笂鏉′欢閮戒笉婊¤冻锛屾姏鍑篘otImplementedException寮傚父
else
{
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/TaskEnum/TaskStatusEnum.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/TaskEnum/TaskStatusEnum.cs
index 1919700..7830784 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/TaskEnum/TaskStatusEnum.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/TaskEnum/TaskStatusEnum.cs
@@ -144,4 +144,43 @@
[Description("鍑哄簱浠诲姟寮傚父")]
OutException = 199,
}
-}
+
+ public enum TaskRobotStatusEnum
+ {
+ /// <summary>
+ /// 鏈烘鎵嬫柊寤轰换鍔�
+ /// </summary>
+ [Description("鏈烘鎵嬫柊寤轰换鍔�")]
+ RobotNew = 300,
+
+ /// <summary>
+ /// 鏈烘鎵嬫墽琛屼腑
+ /// </summary>
+ [Description("鏈烘鎵嬫墽琛屼腑")]
+ RobotExecuting = 310,
+
+ /// <summary>
+ /// 鏈烘鎵嬪畬鎴�
+ /// </summary>
+ [Description("鏈烘鎵嬪畬鎴�")]
+ RobotFinish = 390,
+
+ /// <summary>
+ /// 鏈烘鎵嬩换鍔℃寕璧�
+ /// </summary>
+ [Description("鏈烘鎵嬩换鍔℃寕璧�")]
+ RobotPending = 397,
+
+ /// <summary>
+ /// 鏈烘鎵嬩换鍔″彇娑�
+ /// </summary>
+ [Description("鏈烘鎵嬩换鍔″彇娑�")]
+ RobotCancel = 398,
+
+ /// <summary>
+ /// 鏈烘鎵嬩换鍔″紓甯�
+ /// </summary>
+ [Description("鏈烘鎵嬩换鍔″紓甯�")]
+ RobotException = 399,
+ }
+}
\ No newline at end of file
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/TaskEnum/TaskTypeEnum.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/TaskEnum/TaskTypeEnum.cs
index 33dfdfc..2e991fc 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/TaskEnum/TaskTypeEnum.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Common/TaskEnum/TaskTypeEnum.cs
@@ -71,6 +71,10 @@
public enum TaskOtherTypeEnum
{
-
+ /// <summary>
+ /// 鏈烘鎵嬩换鍔�
+ /// </summary>
+ [Description("鏈烘鎵�")]
+ RobotToManual = 400,
}
}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Core/Enums/RouterInOutType.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Core/Enums/RouterInOutType.cs
index 0ac7177..4a9982d 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Core/Enums/RouterInOutType.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Core/Enums/RouterInOutType.cs
@@ -13,12 +13,12 @@
/// 鍏ュ簱璺敱
/// </summary>
[Description("鍏ュ簱璺敱")]
- In = 1,
+ In = 200,
/// <summary>
/// 鍑哄簱璺敱
/// </summary>
[Description("鍑哄簱璺敱")]
- Out = 2,
+ Out = 100,
}
}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_ITaskInfoService/ITaskService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_ITaskInfoService/ITaskService.cs
index a6002ad..c70133d 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_ITaskInfoService/ITaskService.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_ITaskInfoService/ITaskService.cs
@@ -49,6 +49,11 @@
public List<int> TaskOutboundTypes { get; }
/// <summary>
+ /// 鎵�鏈夊嚭搴撲换鍔$被鍨�
+ /// </summary>
+ public List<int> TaskRobotTypes { get; }
+
+ /// <summary>
/// 鎺ユ敹WMS浠诲姟淇℃伅
/// </summary>
/// <param name="taskDTOs">WMS浠诲姟瀵硅薄闆嗗悎</param>
@@ -103,6 +108,15 @@
/// <returns>杩斿洖浠诲姟瀹炰綋瀵硅薄锛屽彲鑳戒负null</returns>
Dt_Task QueryStackerCraneTask(string deviceNo, string currentAddress = "");
+
+ /// <summary>
+ /// 鏍规嵁璁惧缂栧彿銆佸綋鍓嶅湴鍧�鎸夌収浼樺厛绾т互鍙婂垱寤烘椂闂存帓搴忔煡璇换鍔℃睜鏂板鐨勪换鍔�
+ /// </summary>
+ /// <param name="deviceNo">璁惧缂栧彿</param>
+ /// <param name="currentAddress">褰撳墠鍦板潃</param>
+ /// <returns>杩斿洖浠诲姟瀹炰綋瀵硅薄锛屽彲鑳戒负null</returns>
+ Dt_Task QueryRobotCraneTask(string deviceNo,string currentAddress = "");
+
/// <summary>
/// 鏍规嵁璁惧缂栧彿銆佸綋鍓嶅湴鍧�鎸夌収浼樺厛绾т互鍙婂垱寤烘椂闂存帓搴忔煡璇换鍔℃睜鍏ュ簱绫诲瀷鐨勬柊澧炵殑浠诲姟
/// </summary>
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/QuartzNet/QuartzNetExtension.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/QuartzNet/QuartzNetExtension.cs
index 95605e7..9991cd6 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/QuartzNet/QuartzNetExtension.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/QuartzNet/QuartzNetExtension.cs
@@ -1,14 +1,7 @@
-锘縰sing System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-using System.Threading.Tasks;
-using WIDESEAWCS_Core.Helper;
+锘縰sing System.Reflection;
using WIDESEAWCS_Core;
+using WIDESEAWCS_Core.Helper;
using WIDESEAWCS_QuartzJob.DTO;
-using Microsoft.Extensions.Logging;
-using WIDESEAWCS_QuartzJob.QuartzExtensions;
using WIDESEAWCS_QuartzJob.Service;
namespace WIDESEAWCS_QuartzJob.QuartzNet
@@ -54,62 +47,67 @@
{
try
{
- #region 杩炴帴PLC
- // 鍔犺浇绋嬪簭闆�
- Assembly assembly = Assembly.Load($"WIDESEAWCS_Communicator");
- // 鑾峰彇绫诲瀷
- Type? type = assembly.GetType($"WIDESEAWCS_Communicator.{x.DevicePlcType}");
- // 鍒涘缓瀹炰緥
- object? obj = Activator.CreateInstance(type, new object[] { x.DeviceIp, x.DevicePort, x.DeviceName });
- // 璋冪敤杩炴帴鏂规硶
- bool? connectResult = (bool)type.InvokeMember("Connect", BindingFlags.Default | BindingFlags.InvokeMethod, null, obj, new object[] { });
- // 鍒ゆ柇杩炴帴缁撴灉
- if (connectResult ?? false) ConsoleHelper.WriteSuccessLine(type.Name + x.DeviceCode + "杩炴帴鎴愬姛"); else ConsoleHelper.WriteErrorLine(type.Name + x.DeviceCode + "杩炴帴澶辫触");
- #endregion
-
-
-
- #region 瀹炰緥鍖栬澶囧璞�
- List<DeviceProDTO> devicePros = x.ProtocolList.Select(d => new DeviceProDTO
+ if (!x.DeviceName.Contains("鏈烘鎵�"))
{
- // 璁惧瀛愮紪鐮�
- DeviceChildCode = d.DeviceChildCode,
- // 璁惧鏁版嵁绫诲瀷
- DeviceDataType = d.DeviceProDataType,
- // 璁惧ID
- DeviceId = d.DeviceId,
- // 璁惧鍗忚ID
- DeviceProId = d.Id,
- // 璁惧鍗忚鏁版嵁鍧�
- DeviceProDataBlock = d.DeviceProDataBlock,
- // 璁惧鍗忚鏁版嵁闀垮害
- DeviceProDataLength = d.DeviceProDataLength,
- // 璁惧鍗忚鍋忕Щ閲�
- DeviceProOffset = d.DeviceProOffset,
- // 璁惧鍗忚鍙傛暟鎻忚堪
- DeviceProParamDes = d.DeviceProParamDes,
- // 璁惧鍗忚鍙傛暟鍚嶇О
- DeviceProParamName = d.DeviceProParamName,
- // 璁惧鍗忚鍙傛暟绫诲瀷
- DeviceProParamType = d.DeviceProParamType,
- // 璁惧PLC绫诲瀷
- DevicePlcType = x.DevicePlcType
- }).ToList();
+ #region 杩炴帴PLC
- // 鏍规嵁璁惧绫诲瀷鑾峰彇璁惧鍗忚璇︽儏
- List<DeviceProtocolDetailDTO> deviceProtocolDetails = _deviceProtocolDetailService.GetDeviceProtocolDetailsByDeviceType(x.DeviceType);
+ // 鍔犺浇绋嬪簭闆�
+ Assembly assembly = Assembly.Load($"WIDESEAWCS_Communicator");
+ // 鑾峰彇绫诲瀷
+ Type? type = assembly.GetType($"WIDESEAWCS_Communicator.{x.DevicePlcType}");
+ // 鍒涘缓瀹炰緥
+ object? obj = Activator.CreateInstance(type, new object[] { x.DeviceIp, x.DevicePort, x.DeviceName });
+ // 璋冪敤杩炴帴鏂规硶
+ bool? connectResult = (bool)type.InvokeMember("Connect", BindingFlags.Default | BindingFlags.InvokeMethod, null, obj, new object[] { });
+ // 鍒ゆ柇杩炴帴缁撴灉
+ if (connectResult ?? false) ConsoleHelper.WriteSuccessLine(type.Name + x.DeviceCode + "杩炴帴鎴愬姛"); else ConsoleHelper.WriteErrorLine(type.Name + x.DeviceCode + "杩炴帴澶辫触");
- // 鍔犺浇璁惧绋嬪簭闆�
- Assembly assemblyDevice = Assembly.Load($"WIDESEAWCS_QuartzJob");
- // 鑾峰彇璁惧绫诲瀷瀵瑰簲鐨勭被鍨�
- Type typeDevice = assemblyDevice.GetType($"WIDESEAWCS_QuartzJob.{x.DeviceType}");
- // 鍒涘缓璁惧瀹炰緥
- object deviceInstance = Activator.CreateInstance(typeDevice, new object[] { obj, devicePros, deviceProtocolDetails, x.DeviceCode, x.DeviceName });
- #endregion
+ #endregion 杩炴帴PLC
- x.Device = (IDevice)deviceInstance;
+ #region 瀹炰緥鍖栬澶囧璞�
- Storage.Devices.Add((IDevice)deviceInstance);
+ List<DeviceProDTO> devicePros = x.ProtocolList.Select(d => new DeviceProDTO
+ {
+ // 璁惧瀛愮紪鐮�
+ DeviceChildCode = d.DeviceChildCode,
+ // 璁惧鏁版嵁绫诲瀷
+ DeviceDataType = d.DeviceProDataType,
+ // 璁惧ID
+ DeviceId = d.DeviceId,
+ // 璁惧鍗忚ID
+ DeviceProId = d.Id,
+ // 璁惧鍗忚鏁版嵁鍧�
+ DeviceProDataBlock = d.DeviceProDataBlock,
+ // 璁惧鍗忚鏁版嵁闀垮害
+ DeviceProDataLength = d.DeviceProDataLength,
+ // 璁惧鍗忚鍋忕Щ閲�
+ DeviceProOffset = d.DeviceProOffset,
+ // 璁惧鍗忚鍙傛暟鎻忚堪
+ DeviceProParamDes = d.DeviceProParamDes,
+ // 璁惧鍗忚鍙傛暟鍚嶇О
+ DeviceProParamName = d.DeviceProParamName,
+ // 璁惧鍗忚鍙傛暟绫诲瀷
+ DeviceProParamType = d.DeviceProParamType,
+ // 璁惧PLC绫诲瀷
+ DevicePlcType = x.DevicePlcType
+ }).ToList();
+
+ // 鏍规嵁璁惧绫诲瀷鑾峰彇璁惧鍗忚璇︽儏
+ List<DeviceProtocolDetailDTO> deviceProtocolDetails = _deviceProtocolDetailService.GetDeviceProtocolDetailsByDeviceType(x.DeviceType);
+
+ // 鍔犺浇璁惧绋嬪簭闆�
+ Assembly assemblyDevice = Assembly.Load($"WIDESEAWCS_QuartzJob");
+ // 鑾峰彇璁惧绫诲瀷瀵瑰簲鐨勭被鍨�
+ Type typeDevice = assemblyDevice.GetType($"WIDESEAWCS_QuartzJob.{x.DeviceType}");
+ // 鍒涘缓璁惧瀹炰緥
+ object deviceInstance = Activator.CreateInstance(typeDevice, new object[] { obj, devicePros, deviceProtocolDetails, x.DeviceCode, x.DeviceName });
+
+ #endregion 瀹炰緥鍖栬澶囧璞�
+
+ x.Device = (IDevice)deviceInstance;
+
+ Storage.Devices.Add((IDevice)deviceInstance);
+ }
}
catch (Exception ex)
{
@@ -123,8 +121,17 @@
});
for (int i = 0; i < dispatches.Count; i++)
{
- DeviceInfoDTO? deviceProInfo = deviceInfos.FirstOrDefault(x => x.Id == dispatches[i].Id);
- dispatches[i].JobParams = deviceProInfo?.Device;
+ var targetDevice = deviceInfos.FirstOrDefault(x => x.Id == dispatches[i].Id);
+
+ if (targetDevice is null) continue;
+
+ // 浣跨敤妯″紡鍖归厤
+ dispatches[i].JobParams = targetDevice switch
+ {
+ { DeviceName: var name } when name.Contains("鏈烘鎵�")
+ => new RobotCraneDevice { DeviceCode = targetDevice.DeviceCode, DeviceName = targetDevice.DeviceName, IPAddress = targetDevice.DeviceIp + ":" + targetDevice.DevicePort },
+ _ => targetDevice.Device
+ };
WebResponseContent responseContent = await _schedulerCenter.AddScheduleJobAsync(dispatches[i]);
if (responseContent.Status) ConsoleHelper.WriteSuccessLine(dispatches[i].Name + "璋冨害鏈嶅姟娣诲姞鎴愬姛"); else ConsoleHelper.WriteErrorLine(dispatches[i].Name + "璋冨害鏈嶅姟娣诲姞澶辫触");
}
@@ -137,4 +144,4 @@
}
}
}
-}
+}
\ No newline at end of file
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Robot/RobotCraneDevice.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Robot/RobotCraneDevice.cs
new file mode 100644
index 0000000..d251e27
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_QuartzJob/Robot/RobotCraneDevice.cs
@@ -0,0 +1,16 @@
+锘縰sing System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace WIDESEAWCS_QuartzJob
+{
+ public class RobotCraneDevice
+ {
+ public string Device { get; set; }
+ public string DeviceCode { get; set; }
+ public string DeviceName { get; set; }
+ public string IPAddress { get; set; }
+ }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Program.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Program.cs
index a7cb7e0..29d6719 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Program.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Program.cs
@@ -25,6 +25,7 @@
using WIDESEAWCS_QuartzJob.Seed;
using WIDESEAWCS_Server.Filter;
using WIDESEAWCS_Server.HostedService;
+using WIDESEAWCS_Tasks.SocketServer;
using WIDESEAWCS_WCSServer.Filter;
var builder = WebApplication.CreateBuilder(args);
@@ -73,6 +74,8 @@
builder.Services.AddHttpContextSetup();
builder.Services.AddHostedService<QuartzJobHostedService>();//任务调度 启动服务
+builder.Services.AddSingleton<TcpSocketServer>();
+builder.Services.AddHostedService<SocketServerHostedService>();
builder.Services.AddMvc(options =>
{
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json
index fe6dfbb..dac24a5 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/appsettings.json
@@ -44,5 +44,16 @@
"PrintSql": true, //鎵撳嵃SQL璇彞
"LogAOPEnable": true, //鏄惁璁板綍AOP鏃ュ織
"WebSocketEnable": true, //鏄惁寮�鍚疻ebSocket鏈嶅姟
- "WebSocketPort": 9296 //WebSocket鏈嶅姟绔彛
+ "WebSocketPort": 9296, //WebSocket鏈嶅姟绔彛
+ "SocketServer": {
+ "Enabled": true,
+ "Port": 2000,
+ "IpAddress": "0.0.0.0",
+ "Backlog": 100,
+ "EncodingName": "utf-8",
+ "AutoDetectEncoding": true,
+ "IdleTimeoutSeconds": 300,
+ "EnableHeartbeat": true,
+ "LogFilePath": "socketserver.log"
+ }
}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/TaskService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/TaskService.cs
index 5f9e946..472fba7 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/TaskService.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_TaskInfoService/TaskService.cs
@@ -1,4 +1,5 @@
锘�#region << 鐗� 鏈� 娉� 閲� >>
+
/*----------------------------------------------------------------
* 鍛藉悕绌洪棿锛歐IDESEAWCS_TaskInfoService
* 鍒涘缓鑰咃細鑳$搴�
@@ -11,8 +12,9 @@
* 淇敼鏃堕棿锛�
* 鐗堟湰锛歏1.0.1
* 淇敼璇存槑锛�
- *
+ *
*----------------------------------------------------------------*/
+
#endregion << 鐗� 鏈� 娉� 閲� >>
using AutoMapper;
@@ -44,11 +46,14 @@
{nameof(Dt_Task.CreateDate),OrderByType.Asc},
};
- public Dictionary<string, OrderByType> TaskOrderBy { get { return _taskOrderBy; } set { _taskOrderBy = value; } }
+ public Dictionary<string, OrderByType> TaskOrderBy
+ { get { return _taskOrderBy; } set { _taskOrderBy = value; } }
public List<int> TaskInboundTypes => typeof(TaskInboundTypeEnum).GetEnumIndexList();
public List<int> TaskOutboundTypes => typeof(TaskOutboundTypeEnum).GetEnumIndexList();
+
+ public List<int> TaskRobotTypes => typeof(TaskOtherTypeEnum).GetEnumIndexList();
public TaskService(ITaskRepository BaseDal, IRouterService routerService, ITaskExecuteDetailService taskExecuteDetailService, ITaskExecuteDetailRepository taskExecuteDetailRepository, IMapper mapper) : base(BaseDal)
{
@@ -359,6 +364,17 @@
task.TargetAddress = task.NextAddress;
}
}
+ else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OtherGroup)
+ {
+ if (task.TaskState >= (int)TaskRobotStatusEnum.RobotNew)
+ {
+ return content = WebResponseContent.Instance.Error($"璇ヤ换鍔$姸鎬佷笉鍙烦杞埌涓嬩竴姝�,浠诲姟鍙�:銆恵task.TaskNum}銆�,浠诲姟鐘舵��:銆恵task.TaskState}銆�");
+ }
+
+ int nextStatus = task.TaskState.GetNextNotCompletedStatus<TaskRobotStatusEnum>();
+
+ task.TaskState = nextStatus;
+ }
else
{
throw new Exception($"浠诲姟绫诲瀷閿欒,鏈壘鍒拌浠诲姟绫诲瀷,浠诲姟鍙�:銆恵task.TaskNum}銆�,浠诲姟绫诲瀷:銆恵task.TaskType}銆�");
@@ -452,7 +468,7 @@
}
else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup && task.TaskState == (int)TaskInStatusEnum.SC_InExecuting)
{
- //todo
+ //todo
int nextStatus = task.TaskState.GetNextNotCompletedStatus<TaskInStatusEnum>();
task.TaskState = nextStatus;
task.ModifyDate = DateTime.Now;
@@ -481,7 +497,6 @@
}
else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OtherGroup)
{
-
}
else
{
@@ -598,5 +613,19 @@
BaseDal.DeleteAndMoveIntoHty(tasks, OperateTypeEnum.浜哄伐鍒犻櫎);
return WebResponseContent.Instance.OK($"鎴愬姛鍒犻櫎{tasks.Count}鏉℃暟鎹�");
}
+
+ /// <summary>
+ /// 鏍规嵁璁惧缂栧彿銆佸綋鍓嶅湴鍧�鎸夌収浼樺厛绾т互鍙婂垱寤烘椂闂存帓搴忔煡璇换鍔℃睜鏂板鐨勪换鍔�
+ /// </summary>
+ /// <param name="deviceNo">璁惧缂栧彿</param>
+ /// <param name="currentAddress">褰撳墠鍦板潃</param>
+ /// <returns>杩斿洖浠诲姟瀹炰綋瀵硅薄锛屽彲鑳戒负null</returns>
+ public Dt_Task QueryRobotCraneTask(string deviceNo, string currentAddress = "")
+ {
+ if (string.IsNullOrEmpty(currentAddress))
+ return BaseDal.QueryFirst(x => x.Roadway == deviceNo && (TaskRobotTypes.Contains(x.TaskType) && x.TaskState <= (int)TaskRobotStatusEnum.RobotExecuting), TaskOrderBy);
+ else
+ return BaseDal.QueryFirst(x => x.Roadway == deviceNo && TaskRobotTypes.Contains(x.TaskType) && x.CurrentAddress == currentAddress && x.TaskState <= (int)TaskRobotStatusEnum.RobotExecuting, TaskOrderBy);
+ }
}
-}
+}
\ No newline at end of file
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineJob/CommonConveyorLineJob.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineJob/CommonConveyorLineJob.cs
index a7b7695..ee7b5cd 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineJob/CommonConveyorLineJob.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineJob/CommonConveyorLineJob.cs
@@ -63,11 +63,6 @@
List<Task> tasks = new List<Task>();
foreach (string childDeviceCode in childDeviceCodes)
{
- int num = new Random().Next(1, 100);
- if (num < 30)
- {
- throw new CommunicationException("閿欒娴嬭瘯", CommunicationErrorType.Unknown);
- }
ConveyorLineTaskCommand command = conveyorLine.ReadCustomer<ConveyorLineTaskCommand>(childDeviceCode);
if (command != null)
{
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineJob/ConveyorLineTaskCommand.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineJob/ConveyorLineTaskCommand.cs
index ac1c79d..958b40b 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineJob/ConveyorLineTaskCommand.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ConveyorLineJob/ConveyorLineTaskCommand.cs
@@ -28,7 +28,7 @@
{
public ushort InteractiveSignal { get; set; }
- [DataLength(25)]
+ [DataLength(254)]
public string Barcode { get; set; }
public int TargetAddress { get; set; }
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/FormationStackerCraneJob/FormationStackerCraneTaskCommand.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/FormationStackerCraneJob/FormationStackerCraneTaskCommand.cs
index 1c368a5..6a1eb8b 100644
--- a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/FormationStackerCraneJob/FormationStackerCraneTaskCommand.cs
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/FormationStackerCraneJob/FormationStackerCraneTaskCommand.cs
@@ -89,7 +89,7 @@
/// <summary>
/// 鎵樼洏鍙�
/// </summary>
- [DataLength(26)]
+ [DataLength(25)]
public string Barcode { get; set; }
#endregion <Public Menber>
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotJob.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotJob.cs
new file mode 100644
index 0000000..8503c91
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/RobotJob/RobotJob.cs
@@ -0,0 +1,297 @@
+锘縰sing Quartz;
+using System.Collections.Concurrent;
+using System.Net.Sockets;
+using WIDESEAWCS_Core.Helper;
+using WIDESEAWCS_ITaskInfoRepository;
+using WIDESEAWCS_ITaskInfoService;
+using WIDESEAWCS_Model.Models;
+using WIDESEAWCS_QuartzJob;
+using WIDESEAWCS_QuartzJob.Service;
+using WIDESEAWCS_Tasks.SocketServer;
+
+namespace WIDESEAWCS_Tasks
+{
+ [DisallowConcurrentExecution]
+ public class RobotJob : IJob
+ {
+ private readonly TcpSocketServer _TcpSocket;
+ private static readonly ConcurrentDictionary<string, RobotSocketState> _socketStates = new();
+ private static int _eventSubscribedFlag;
+ private readonly ITaskService _taskService;
+ private readonly ITaskExecuteDetailService _taskExecuteDetailService;
+ private readonly ITaskRepository _taskRepository;
+ private readonly IRouterService _routerService;
+
+ public RobotJob(TcpSocketServer TcpSocket, ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository, IRouterService routerService)
+ {
+ _TcpSocket = TcpSocket;
+ _taskService = taskService;
+ _taskExecuteDetailService = taskExecuteDetailService;
+ _taskRepository = taskRepository;
+ _routerService = routerService;
+ }
+
+ public Task Execute(IJobExecutionContext context)
+ {
+ bool flag = context.JobDetail.JobDataMap.TryGetValue("JobParams", out object? value);
+ RobotCraneDevice robotCrane = (RobotCraneDevice?)value ?? new RobotCraneDevice();
+ if (!flag || robotCrane.IsNullOrEmpty())
+ {
+ return Task.CompletedTask;
+ }
+
+ string ipAddress = robotCrane.IPAddress;
+
+ // 鑾峰彇鎴栧垱寤虹姸鎬�
+ RobotSocketState state = _socketStates.GetOrAdd(ipAddress, _ => new RobotSocketState
+ {
+ IPAddress = ipAddress,
+ RobotCrane = robotCrane
+ });
+
+ // 鏇存柊璁惧淇℃伅
+ state.RobotCrane = robotCrane;
+
+ // 妫�鏌ユ槸鍚︽湁璇ュ鎴风杩炴帴
+ var clientIds = _TcpSocket.GetClientIds();
+ if (!clientIds.Contains(ipAddress))
+ {
+ return Task.CompletedTask;
+ }
+
+ // 璁㈤槄涓�娆� message 浜嬩欢锛堝叏灞�涓�娆★級
+ if (Interlocked.CompareExchange(ref _eventSubscribedFlag, 1, 0) == 0)
+ {
+ _TcpSocket.MessageReceived += _TcpSocket_MessageReceived;
+ _TcpSocket.RobotReceived += _TcpSocket_RobotReceived;
+ }
+
+ if (!state.IsEventSubscribed)
+ {
+ _TcpSocket._clients.TryGetValue(ipAddress, out TcpClient client);
+ Task clientTask = _TcpSocket.HandleClientAsync(client, robotCrane.IPAddress, _TcpSocket._cts.Token, state);
+ state.IsEventSubscribed = true;
+ }
+
+ // 鑾峰彇浠诲姟骞剁紦瀛樺埌鐘舵�佷腑
+ Dt_Task? task = GetTask(robotCrane);
+ if (task != null)
+ {
+ state.CurrentTask = task;
+ }
+
+ return Task.CompletedTask;
+ }
+
+ /// <summary>
+ /// 浜嬩欢锛氬鎴风鏂紑杩炴帴鏃惰Е鍙�
+ /// </summary>
+ /// <param name="clientId"></param>
+ /// <returns></returns>
+ private Task<string?> _TcpSocket_RobotReceived(string clientId)
+ {
+ _socketStates.TryRemove(clientId, out _);
+ return Task.FromResult<string?>(null);
+ }
+
+ /// <summary>
+ /// 浜嬩欢锛氭敹鍒版秷鎭椂瑙﹀彂
+ /// </summary>
+ /// <param name="message"></param>
+ /// <param name="isJson"></param>
+ /// <param name="client"></param>
+ /// <param name="state"></param>
+ /// <returns></returns>
+ private async Task<string?> _TcpSocket_MessageReceived(string message, bool isJson, TcpClient client, RobotSocketState state)
+ {
+ string messageLower = message.ToLowerInvariant();
+
+ if (IsSimpleCommand(messageLower, state))
+ {
+ return null;
+ }
+
+ if (IsPrefixCommand(messageLower))
+ {
+ try
+ {
+ var parts = message.Split(',');
+ if (parts.Length >= 1)
+ {
+ var cmd = parts[0].ToLowerInvariant();
+ int[] positions = new int[4];
+ for (int i = 1; i <= 4 && i < parts.Length; i++)
+ {
+ int.TryParse(parts[i], out positions[i - 1]);
+ }
+
+ if (cmd.StartsWith("pickfinished"))
+ {
+ state.LastPickPositions = positions;
+ state.CurrentAction = "PickFinished";
+ }
+ else if (cmd.StartsWith("putfinished"))
+ {
+ state.LastPutPositions = positions;
+ state.CurrentAction = "PutFinished";
+ }
+ }
+ }
+ catch { }
+
+ return null;
+ }
+
+ return null;
+ }
+
+ /// <summary>
+ /// 鏈烘鎵嬬畝鍗曞懡浠ゅ鐞�
+ /// </summary>
+ /// <param name="message"></param>
+ /// <param name="state"></param>
+ /// <returns></returns>
+ private bool IsSimpleCommand(string message, RobotSocketState state)
+ {
+ switch (message)
+ {
+ case "homing":
+ state.CurrentAction = "Homing";
+ return true;
+
+ case "homed":
+ state.CurrentAction = "Homed";
+ return true;
+
+ case "picking":
+ state.CurrentAction = "Picking";
+ return true;
+
+ case "puting":
+ state.CurrentAction = "Putting";
+ return true;
+
+ case "allpickfinished":
+ state.CurrentAction = "AllPickFinished";
+ return true;
+
+ case "allputfinished":
+ state.CurrentAction = "AllPutFinished";
+ return true;
+
+ case "running":
+ state.OperStatus = "Running";
+ return true;
+
+ case "pausing":
+ state.OperStatus = "Pausing";
+ return true;
+
+ case "warming":
+ state.OperStatus = "Warming";
+ return true;
+
+ case "emstoping":
+ state.OperStatus = "Emstoping";
+ return true;
+
+ case "runmode,1":
+ state.RobotRunMode = 1;
+ return true;
+
+ case "runmodemode,2":
+ state.RobotRunMode = 2;
+ return true;
+
+ case "controlmode,1":
+ state.RobotControlMode = 1;
+ return true;
+
+ case "controlmode,2":
+ state.RobotControlMode = 2;
+ return true;
+
+ case "armobject,1":
+ state.RobotArmObject = 1;
+ return true;
+
+ case "armobject,0":
+ state.RobotArmObject = 0;
+ return true;
+
+ default:
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// 鏈烘鎵嬪墠缂�鍛戒护澶勭悊
+ /// </summary>
+ /// <param name="message"></param>
+ /// <returns></returns>
+ private static bool IsPrefixCommand(string message)
+ {
+ return message.StartsWith("pickfinished") || message.StartsWith("putfinished");
+ }
+
+ private Dt_Task? GetTask(RobotCraneDevice robotCrane)
+ {
+ return _taskService.QueryRobotCraneTask(robotCrane.DeviceCode);
+ }
+ }
+
+ public class RobotSocketState
+ {
+ public string IPAddress { get; set; } = string.Empty;
+
+ /// <summary>
+ /// 鏄惁宸茶闃呮秷鎭簨浠�
+ /// </summary>
+ public bool IsEventSubscribed { get; set; }
+
+ /// <summary>
+ /// 鏈烘鎵嬭繍琛屾ā寮�
+ /// </summary>
+ public int? RobotRunMode { get; set; }
+
+ /// <summary>
+ /// 鏈烘鎵嬫帶鍒舵ā寮�
+ /// </summary>
+ public int? RobotControlMode { get; set; }
+
+ /// <summary>
+ /// 鏈烘鎵嬫姄鍙栧璞�
+ /// </summary>
+ public int? RobotArmObject { get; set; }
+
+ /// <summary>
+ /// 鏈烘鎵嬭澶囦俊鎭�
+ /// </summary>
+ public RobotCraneDevice? RobotCrane { get; set; }
+
+ /// <summary>
+ /// 褰撳墠鍔ㄤ綔
+ /// </summary>
+ public string? CurrentAction { get; set; }
+
+ /// <summary>
+ /// 褰撳墠鐘舵��
+ /// </summary>
+ public string? OperStatus { get; set; }
+
+ /// <summary>
+ /// 鍙栬揣瀹屾垚浣嶇疆
+ /// </summary>
+ public int[]? LastPickPositions { get; set; }
+
+ /// <summary>
+ /// 鏀捐揣瀹屾垚浣嶇疆
+ /// </summary>
+ public int[]? LastPutPositions { get; set; }
+
+ /// <summary>
+ /// 褰撳墠鎶撳彇浠诲姟
+ /// </summary>
+ public Dt_Task? CurrentTask { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/SocketServerHostedService.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/SocketServerHostedService.cs
new file mode 100644
index 0000000..987ddbe
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/SocketServerHostedService.cs
@@ -0,0 +1,35 @@
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Options;
+
+namespace WIDESEAWCS_Tasks.SocketServer
+{
+ /// <summary>
+ /// Socket服务端托管服务
+ /// </summary>
+ public class SocketServerHostedService : IHostedService
+ {
+ private readonly TcpSocketServer _server;
+ private readonly SocketServerOptions _options;
+
+ public SocketServerHostedService(TcpSocketServer server, IOptions<SocketServerOptions> options)
+ {
+ _server = server;
+ _options = options.Value;
+ }
+
+ public Task StartAsync(CancellationToken cancellationToken)
+ {
+ if (!_options.Enabled)
+ {
+ return Task.CompletedTask;
+ }
+
+ return _server.StartAsync(cancellationToken);
+ }
+
+ public Task StopAsync(CancellationToken cancellationToken)
+ {
+ return _server.StopAsync(cancellationToken);
+ }
+ }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/SocketServerOptions.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/SocketServerOptions.cs
new file mode 100644
index 0000000..718497a
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/SocketServerOptions.cs
@@ -0,0 +1,55 @@
+using WIDESEAWCS_Core.Core;
+
+namespace WIDESEAWCS_Tasks.SocketServer
+{
+ /// <summary>
+ /// Socket服务端配置
+ /// </summary>
+ public class SocketServerOptions : IConfigurableOptions
+ {
+ /// <summary>
+ /// 是否启用
+ /// </summary>
+ public bool Enabled { get; set; } = true;
+
+ /// <summary>
+ /// 监听端口
+ /// </summary>
+ public int Port { get; set; } = 2000;
+
+ /// <summary>
+ /// 监听地址
+ /// </summary>
+ public string IpAddress { get; set; } = "0.0.0.0";
+
+ /// <summary>
+ /// 连接队列长度
+ /// </summary>
+ public int Backlog { get; set; } = 100;
+
+ /// <summary>
+ /// 文本编码名称(例如: utf-8, gbk)
+ /// </summary>
+ public string EncodingName { get; set; } = "utf-8";
+
+ /// <summary>
+ /// 是否自动检测编码(尝试 UTF-8 后回退到 GBK)
+ /// </summary>
+ public bool AutoDetectEncoding { get; set; } = true;
+
+ /// <summary>
+ /// 客户端空闲超时时间(秒),超过则断开
+ /// </summary>
+ public int IdleTimeoutSeconds { get; set; } = 300;
+
+ /// <summary>
+ /// 是否启用心跳检查
+ /// </summary>
+ public bool EnableHeartbeat { get; set; } = true;
+
+ /// <summary>
+ /// 日志文件路径(相对于程序运行目录)
+ /// </summary>
+ public string LogFilePath { get; set; } = "socketserver.log";
+ }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Clients.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Clients.cs
new file mode 100644
index 0000000..9654ae2
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Clients.cs
@@ -0,0 +1,94 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace WIDESEAWCS_Tasks.SocketServer
+{
+ public partial class TcpSocketServer
+ {
+ public IReadOnlyList<string> GetClientIds()
+ {
+ lock (_syncRoot)
+ {
+ return _clients.Keys.ToList();
+ }
+ }
+
+ public string? GetClientIdByDevice(string deviceId)
+ {
+ lock (_syncRoot)
+ {
+ return _deviceBindings.TryGetValue(deviceId, out var cid) ? cid : null;
+ }
+ }
+
+ public Task<bool> SendToDeviceAsync(string deviceId, string message)
+ {
+ var clientId = GetClientIdByDevice(deviceId);
+ if (clientId == null) return Task.FromResult(false);
+ return SendToClientAsync(clientId, message);
+ }
+
+ public async Task<bool> SendToClientAsync(string clientId, string message)
+ {
+ TcpClient? client;
+ SemaphoreSlim? sem = null;
+ Encoding? enc = null;
+ lock (_syncRoot)
+ {
+ _clients.TryGetValue(clientId, out client);
+ _clientLocks.TryGetValue(clientId, out sem);
+ _clientEncodings.TryGetValue(clientId, out enc);
+ }
+
+ if (client == null || !client.Connected)
+ {
+ return false;
+ }
+
+ enc ??= _textEncoding;
+
+ if (sem != null) await sem.WaitAsync();
+ try
+ {
+ var ns = client.GetStream();
+ var data = enc.GetBytes((message ?? string.Empty) + "\n");
+ await ns.WriteAsync(data, 0, data.Length);
+ }
+ finally
+ {
+ if (sem != null) sem.Release();
+ }
+ return true;
+ }
+
+ public async Task BroadcastAsync(string message)
+ {
+ List<TcpClient> clients;
+ lock (_syncRoot)
+ {
+ clients = _clients.Values.ToList();
+ }
+
+ await Task.WhenAll(clients.Select(c => Task.Run(async () =>
+ {
+ try { await SendAsync(c, message); } catch { }
+ })));
+ }
+
+ public static async Task SendAsync(TcpClient client, string message)
+ {
+ if (client == null || !client.Connected)
+ {
+ return;
+ }
+
+ NetworkStream stream = client.GetStream();
+ var data = Encoding.UTF8.GetBytes((message ?? string.Empty) + "\n");
+ await stream.WriteAsync(data, 0, data.Length);
+ }
+ }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Dispose.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Dispose.cs
new file mode 100644
index 0000000..d8f5ec9
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Dispose.cs
@@ -0,0 +1,18 @@
+using System;
+using System.IO;
+
+namespace WIDESEAWCS_Tasks.SocketServer
+{
+ public partial class TcpSocketServer
+ {
+ public void Dispose()
+ {
+ _cts?.Cancel();
+ _listener?.Stop();
+ _cts?.Dispose();
+ foreach (var sem in _clientLocks.Values) { try { sem.Dispose(); } catch { } }
+ _clientLocks.Clear();
+ Log($"[{DateTime.Now}] TcpSocketServer stopped");
+ }
+ }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Messaging.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Messaging.cs
new file mode 100644
index 0000000..9f186e4
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Messaging.cs
@@ -0,0 +1,175 @@
+using HslCommunication.Core.IMessage;
+using System;
+using System.Net.Sockets;
+using System.Text;
+using System.Text.Json;
+using System.Threading;
+using System.Threading.Tasks;
+using WIDESEAWCS_QuartzJob;
+
+namespace WIDESEAWCS_Tasks.SocketServer
+{
+ public partial class TcpSocketServer
+ {
+ public async Task HandleClientAsync(TcpClient client, string clientId, CancellationToken cancellationToken, RobotSocketState robotCrane)
+ {
+ using (client)
+ using (NetworkStream networkStream = client.GetStream())
+ using (StreamReader reader = new(networkStream, _textEncoding, false, 1024, true))
+ using (StreamWriter writer = new(networkStream, _textEncoding, 1024, true) { AutoFlush = true })
+ {
+ CancellationTokenSource? localCts = null;
+ if (_options.EnableHeartbeat || _options.IdleTimeoutSeconds > 0)
+ {
+ localCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
+ }
+
+ try
+ {
+ while (!cancellationToken.IsCancellationRequested && client.Connected)
+ {
+ string? message;
+ try
+ {
+ var ct = localCts?.Token ?? cancellationToken;
+ message = await reader.ReadLineAsync().WaitAsync(ct);
+ }
+ catch (OperationCanceledException)
+ {
+ break;
+ }
+
+ if (message == null)
+ {
+ break;
+ }
+
+ UpdateClientStatus(clientId, message);
+
+ string messageLower = message.ToLowerInvariant();
+
+ if (TryHandleRegister(messageLower, message, clientId, networkStream, cancellationToken))
+ {
+ continue;
+ }
+
+ if (MessageReceived != null)
+ {
+ try { _ = MessageReceived.Invoke(message, false, client, robotCrane); } catch { }
+ }
+ }
+ }
+ finally
+ {
+ try { localCts?.Cancel(); localCts?.Dispose(); } catch { }
+ RemoveClient(clientId);
+ try { _ = RobotReceived.Invoke(clientId); } catch { }
+ }
+ }
+ }
+
+ private bool TryHandleRegister(string messageLower, string message, string clientId, NetworkStream networkStream, CancellationToken cancellationToken)
+ {
+ if (!messageLower.StartsWith("register,"))
+ {
+ return false;
+ }
+
+ string deviceId = message.Substring("register,".Length).Trim();
+ if (!string.IsNullOrEmpty(deviceId))
+ {
+ lock (_syncRoot)
+ {
+ _deviceBindings[deviceId] = clientId;
+ }
+
+ _ = WriteToClientAsync(clientId, networkStream, $"Registered,{deviceId}", cancellationToken);
+ }
+
+ return true;
+ }
+
+ private void UpdateClientStatus(string clientId, string message)
+ {
+ lock (_syncRoot)
+ {
+ _clientLastActive[clientId] = DateTime.Now;
+
+ if (!_clientEncodings.ContainsKey(clientId))
+ {
+ if (_options.AutoDetectEncoding && _autoDetectedGb2312 != null)
+ {
+ bool isUtf8 = TryParseJsonSilent(message) || IsLikelyUtf8(_textEncoding.GetBytes(message));
+ _clientEncodings[clientId] = isUtf8 ? _textEncoding : _autoDetectedGb2312;
+ }
+ else
+ {
+ _clientEncodings[clientId] = _textEncoding;
+ }
+ }
+ }
+ }
+
+ private async Task WriteToClientAsync(string clientId, NetworkStream networkStream, string message, CancellationToken cancellationToken)
+ {
+ SemaphoreSlim? sem = null;
+ Encoding? enc = null;
+ lock (_syncRoot)
+ {
+ _clientLocks.TryGetValue(clientId, out sem);
+ _clientEncodings.TryGetValue(clientId, out enc);
+ }
+
+ enc ??= _textEncoding;
+
+ if (sem != null) await sem.WaitAsync(cancellationToken);
+ try
+ {
+ var data = enc.GetBytes(message + "\n");
+ await networkStream.WriteAsync(data, 0, data.Length, cancellationToken);
+ }
+ finally
+ {
+ if (sem != null) sem.Release();
+ }
+ }
+
+ private static bool TryParseJsonSilent(string message)
+ {
+ if (string.IsNullOrWhiteSpace(message)) return false;
+ char c = message.TrimStart()[0];
+ if (c != '{' && c != '[') return false;
+ try { JsonDocument.Parse(message); return true; } catch { return false; }
+ }
+
+ private static bool IsLikelyUtf8(byte[] data)
+ {
+ int i = 0;
+ while (i < data.Length)
+ {
+ byte b = data[i];
+ if (b <= 0x7F) { i++; continue; }
+ if (b >= 0xC2 && b <= 0xDF)
+ {
+ if (i + 1 >= data.Length) return false;
+ if ((data[i + 1] & 0xC0) != 0x80) return false;
+ i += 2; continue;
+ }
+ if (b >= 0xE0 && b <= 0xEF)
+ {
+ if (i + 2 >= data.Length) return false;
+ if ((data[i + 1] & 0xC0) != 0x80 || (data[i + 2] & 0xC0) != 0x80) return false;
+ i += 3; continue;
+ }
+ if (b >= 0xF0 && b <= 0xF4)
+ {
+ if (i + 3 >= data.Length) return false;
+ if ((data[i + 1] & 0xC0) != 0x80 || (data[i + 2] & 0xC0) != 0x80 || (data[i + 3] & 0xC0) != 0x80) return false;
+ i += 4; continue;
+ }
+ return false;
+ }
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Server.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Server.cs
new file mode 100644
index 0000000..2c35f71
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.Server.cs
@@ -0,0 +1,164 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace WIDESEAWCS_Tasks.SocketServer
+{
+ public partial class TcpSocketServer
+ {
+ public Task StartAsync(CancellationToken cancellationToken)
+ {
+ if (IsRunning || !_options.Enabled)
+ {
+ return Task.CompletedTask;
+ }
+
+ IPAddress ipAddress = IPAddress.Any;
+ if (IPAddress.TryParse(_options.IpAddress, out IPAddress? parsedAddress))
+ {
+ ipAddress = parsedAddress;
+ }
+
+ _listener = new TcpListener(ipAddress, _options.Port);
+ _listener.Start(_options.Backlog);
+ _cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
+ IsRunning = true;
+
+ _ = AcceptLoopAsync(_cts.Token);
+ _monitorTask = Task.Run(() => MonitorClientsAsync(_cts.Token));
+
+ return Task.CompletedTask;
+ }
+
+ public async Task StopAsync(CancellationToken cancellationToken)
+ {
+ if (!IsRunning)
+ {
+ return;
+ }
+
+ _cts?.Cancel();
+ _listener?.Stop();
+
+ Task[] tasks;
+ lock (_syncRoot)
+ {
+ tasks = _clientTasks.ToArray();
+ }
+
+ if (tasks.Length > 0)
+ {
+ await Task.WhenAll(tasks);
+ }
+
+ IsRunning = false;
+ }
+
+ private async Task AcceptLoopAsync(CancellationToken cancellationToken)
+ {
+ while (!cancellationToken.IsCancellationRequested)
+ {
+ TcpClient? client = null;
+ try
+ {
+ client = await _listener!.AcceptTcpClientAsync().WaitAsync(cancellationToken);
+ }
+ catch (OperationCanceledException)
+ {
+ break;
+ }
+ catch (ObjectDisposedException)
+ {
+ break;
+ }
+ catch
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ break;
+ }
+ }
+
+ if (client == null)
+ {
+ continue;
+ }
+
+ string clientId = GetClientId(client);
+ lock (_syncRoot)
+ {
+ _clients[clientId] = client;
+ _clientLocks[clientId] = new SemaphoreSlim(1, 1);
+ }
+ }
+ }
+
+ private void RemoveClient(string clientId)
+ {
+ lock (_syncRoot)
+ {
+ if (_clients.TryGetValue(clientId, out var client))
+ {
+ try { client.Close(); } catch { }
+ _clients.Remove(clientId);
+ }
+
+ if (_clientLocks.TryGetValue(clientId, out var sem))
+ {
+ _clientLocks.Remove(clientId);
+ sem.Dispose();
+ }
+
+ _clientLastActive.Remove(clientId);
+ _clientEncodings.Remove(clientId);
+
+ var deviceIds = _deviceBindings.Where(kv => kv.Value == clientId).Select(kv => kv.Key).ToList();
+ foreach (var deviceId in deviceIds)
+ {
+ _deviceBindings.Remove(deviceId);
+ }
+ }
+ }
+
+ private async Task MonitorClientsAsync(CancellationToken cancellationToken)
+ {
+ while (!cancellationToken.IsCancellationRequested)
+ {
+ try
+ {
+ List<string> toRemove = new();
+ lock (_syncRoot)
+ {
+ foreach (var kv in _clientLastActive)
+ {
+ if (_options.IdleTimeoutSeconds > 0 && DateTime.Now - kv.Value > TimeSpan.FromSeconds(_options.IdleTimeoutSeconds))
+ {
+ toRemove.Add(kv.Key);
+ }
+ }
+ }
+
+ foreach (var cid in toRemove)
+ {
+ RemoveClient(cid);
+ Log($"[{DateTime.Now}] TcpSocketServer disconnect idle client {cid}");
+ }
+ }
+ catch
+ {
+ }
+
+ try { await Task.Delay(1000, cancellationToken); } catch { }
+ }
+ }
+
+ public static string GetClientId(TcpClient client)
+ {
+ return client.Client.RemoteEndPoint?.ToString() ?? Guid.NewGuid().ToString();
+ }
+ }
+}
diff --git a/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.cs b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.cs
new file mode 100644
index 0000000..16371be
--- /dev/null
+++ b/Code/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/SocketServer/TcpSocketServer.cs
@@ -0,0 +1,63 @@
+using Microsoft.Extensions.Options;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using WIDESEAWCS_QuartzJob;
+
+namespace WIDESEAWCS_Tasks.SocketServer
+{
+ /// <summary>
+ /// TCP Socket服务端(基于行协议,按换行符分割消息)
+ /// </summary>
+ public partial class TcpSocketServer : IDisposable
+ {
+ private readonly SocketServerOptions _options;
+ public readonly object _syncRoot = new();
+ private TcpListener? _listener;
+ public CancellationTokenSource? _cts;
+ public readonly List<Task> _clientTasks = new();
+ public readonly Dictionary<string, TcpClient> _clients = new();
+ public readonly Dictionary<string, string> _deviceBindings = new();
+ public readonly Dictionary<string, SemaphoreSlim> _clientLocks = new();
+ public readonly Dictionary<string, Encoding> _clientEncodings = new();
+ public readonly Dictionary<string, DateTime> _clientLastActive = new();
+ public readonly Encoding _textEncoding;
+ public readonly Encoding? _autoDetectedGb2312;
+ private readonly string _logFile;
+ private Task? _monitorTask;
+
+ public TcpSocketServer(IOptions<SocketServerOptions> options)
+ {
+ _options = options.Value;
+ if (_options.AutoDetectEncoding)
+ {
+ _textEncoding = Encoding.UTF8;
+ try { _autoDetectedGb2312 = Encoding.GetEncoding("GBK"); } catch { _autoDetectedGb2312 = null; }
+ }
+ else
+ {
+ try { _textEncoding = Encoding.GetEncoding(_options.EncodingName ?? "utf-8"); }
+ catch { _textEncoding = Encoding.UTF8; }
+ _autoDetectedGb2312 = null;
+ }
+
+ _logFile = Path.Combine(AppContext.BaseDirectory ?? ".", _options.LogFilePath ?? "socketserver.log");
+ Log($"[{DateTime.Now}] TcpSocketServer starting");
+ }
+
+ public bool IsRunning { get; private set; }
+
+ public event Func<string, bool, TcpClient, RobotSocketState, Task<string?>>? MessageReceived;
+ public event Func<string, Task<string?>>? RobotReceived;
+
+ private void Log(string message)
+ {
+ Console.WriteLine(message);
+ try { File.AppendAllText(_logFile, message + Environment.NewLine); } catch { }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Code/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/18.0.988.22099/CodeChunks.db b/Code/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/18.0.988.22099/CodeChunks.db
index 5c5f537..c1f0f8e 100644
--- a/Code/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/18.0.988.22099/CodeChunks.db
+++ b/Code/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/18.0.988.22099/CodeChunks.db
Binary files differ
diff --git a/Code/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/18.0.988.22099/SemanticSymbols.db b/Code/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/18.0.988.22099/SemanticSymbols.db
index 9cc78e2..51bbf48 100644
--- a/Code/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/18.0.988.22099/SemanticSymbols.db
+++ b/Code/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/18.0.988.22099/SemanticSymbols.db
Binary files differ
diff --git a/Code/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/v18/DocumentLayout.json b/Code/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/v18/DocumentLayout.json
index 0bb113c..ab43d7c 100644
--- a/Code/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/v18/DocumentLayout.json
+++ b/Code/WMS/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/v18/DocumentLayout.json
@@ -36,7 +36,7 @@
"RelativeDocumentMoniker": "WIDESEA_WMSServer\\appsettings.json",
"ToolTip": "D:\\Git\\ShanMeiXinNengYuan\\Code\\WMS\\WIDESEA_WMSServer\\WIDESEA_WMSServer\\appsettings.json",
"RelativeToolTip": "WIDESEA_WMSServer\\appsettings.json",
- "ViewState": "AgIAAAAAAAAAAAAAAAAAABwAAAAZAAAAAAAAAA==",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAAB4AAAAZAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001642|",
"WhenOpened": "2026-01-26T08:48:58.694Z",
"EditorCaption": ""
diff --git a/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/appsettings.json b/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/appsettings.json
index 96be5b6..da6c29a 100644
--- a/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/appsettings.json
+++ b/Code/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/appsettings.json
@@ -28,7 +28,7 @@
"PrintSql": false, //鎵撳嵃SQL璇彞
"ApiName": "WIDESEA",
"ExpMinutes": 120,
- "DBSeedEnable": true,
+ "DBSeedEnable": false,
"PDAVersion": "4",
"WebSocketPort": 9296
}
diff --git "a/\351\241\271\347\233\256\350\265\204\346\226\231/\345\210\206\345\256\271\346\237\234\346\216\245\345\217\243\345\215\217\350\256\256/\345\214\226\346\210\220\345\210\206\345\256\271\346\237\234\346\216\245\345\217\243\345\215\217\350\256\2561.1.xls" "b/\351\241\271\347\233\256\350\265\204\346\226\231/\350\256\276\345\244\207\345\215\217\350\256\256/\345\210\206\345\256\271\346\237\234\346\216\245\345\217\243\345\215\217\350\256\256/\345\214\226\346\210\220\345\210\206\345\256\271\346\237\234\346\216\245\345\217\243\345\215\217\350\256\2561.1.xls"
similarity index 99%
rename from "\351\241\271\347\233\256\350\265\204\346\226\231/\345\210\206\345\256\271\346\237\234\346\216\245\345\217\243\345\215\217\350\256\256/\345\214\226\346\210\220\345\210\206\345\256\271\346\237\234\346\216\245\345\217\243\345\215\217\350\256\2561.1.xls"
rename to "\351\241\271\347\233\256\350\265\204\346\226\231/\350\256\276\345\244\207\345\215\217\350\256\256/\345\210\206\345\256\271\346\237\234\346\216\245\345\217\243\345\215\217\350\256\256/\345\214\226\346\210\220\345\210\206\345\256\271\346\237\234\346\216\245\345\217\243\345\215\217\350\256\2561.1.xls"
index 44f5461..24c0a4c 100644
--- "a/\351\241\271\347\233\256\350\265\204\346\226\231/\345\210\206\345\256\271\346\237\234\346\216\245\345\217\243\345\215\217\350\256\256/\345\214\226\346\210\220\345\210\206\345\256\271\346\237\234\346\216\245\345\217\243\345\215\217\350\256\2561.1.xls"
+++ "b/\351\241\271\347\233\256\350\265\204\346\226\231/\350\256\276\345\244\207\345\215\217\350\256\256/\345\210\206\345\256\271\346\237\234\346\216\245\345\217\243\345\215\217\350\256\256/\345\214\226\346\210\220\345\210\206\345\256\271\346\237\234\346\216\245\345\217\243\345\215\217\350\256\2561.1.xls"
Binary files differ
diff --git "a/\351\241\271\347\233\256\350\265\204\346\226\231/\345\214\226\346\210\220\345\272\223\345\240\206\345\236\233\346\234\272\345\215\217\350\256\256/PlcLink_\345\240\206\345\236\233\346\234\272\351\241\271\347\233\256.xlsx" "b/\351\241\271\347\233\256\350\265\204\346\226\231/\350\256\276\345\244\207\345\215\217\350\256\256/\345\214\226\346\210\220\345\272\223\345\240\206\345\236\233\346\234\272\345\215\217\350\256\256/PlcLink_\345\240\206\345\236\233\346\234\272\351\241\271\347\233\256.xlsx"
similarity index 100%
rename from "\351\241\271\347\233\256\350\265\204\346\226\231/\345\214\226\346\210\220\345\272\223\345\240\206\345\236\233\346\234\272\345\215\217\350\256\256/PlcLink_\345\240\206\345\236\233\346\234\272\351\241\271\347\233\256.xlsx"
rename to "\351\241\271\347\233\256\350\265\204\346\226\231/\350\256\276\345\244\207\345\215\217\350\256\256/\345\214\226\346\210\220\345\272\223\345\240\206\345\236\233\346\234\272\345\215\217\350\256\256/PlcLink_\345\240\206\345\236\233\346\234\272\351\241\271\347\233\256.xlsx"
Binary files differ
diff --git "a/\351\241\271\347\233\256\350\265\204\346\226\231/\350\256\276\345\244\207\345\215\217\350\256\256/\346\213\230\346\235\237\346\234\272\345\257\271\346\216\245\345\215\217\350\256\256/\346\213\230\346\235\237\346\234\272\345\257\271\346\216\245\345\215\217\350\256\256-\346\261\207\345\267\2355U.xlsx" "b/\351\241\271\347\233\256\350\265\204\346\226\231/\350\256\276\345\244\207\345\215\217\350\256\256/\346\213\230\346\235\237\346\234\272\345\257\271\346\216\245\345\215\217\350\256\256/\346\213\230\346\235\237\346\234\272\345\257\271\346\216\245\345\215\217\350\256\256-\346\261\207\345\267\2355U.xlsx"
new file mode 100644
index 0000000..bb105f6
--- /dev/null
+++ "b/\351\241\271\347\233\256\350\265\204\346\226\231/\350\256\276\345\244\207\345\215\217\350\256\256/\346\213\230\346\235\237\346\234\272\345\257\271\346\216\245\345\215\217\350\256\256/\346\213\230\346\235\237\346\234\272\345\257\271\346\216\245\345\215\217\350\256\256-\346\261\207\345\267\2355U.xlsx"
Binary files differ
diff --git "a/\351\241\271\347\233\256\350\265\204\346\226\231/\350\256\276\345\244\207\345\215\217\350\256\256/\346\234\272\346\242\260\346\211\213\345\215\217\350\256\256/\344\272\244\344\272\222\346\265\201\347\250\213\350\241\250\0501\051.xlsx" "b/\351\241\271\347\233\256\350\265\204\346\226\231/\350\256\276\345\244\207\345\215\217\350\256\256/\346\234\272\346\242\260\346\211\213\345\215\217\350\256\256/\344\272\244\344\272\222\346\265\201\347\250\213\350\241\250\0501\051.xlsx"
new file mode 100644
index 0000000..3971a56
--- /dev/null
+++ "b/\351\241\271\347\233\256\350\265\204\346\226\231/\350\256\276\345\244\207\345\215\217\350\256\256/\346\234\272\346\242\260\346\211\213\345\215\217\350\256\256/\344\272\244\344\272\222\346\265\201\347\250\213\350\241\250\0501\051.xlsx"
Binary files differ
diff --git "a/\351\241\271\347\233\256\350\265\204\346\226\231/\350\256\276\345\244\207\345\215\217\350\256\256/\351\253\230\345\270\270\346\270\251\345\240\206\345\236\233\346\234\272\344\270\216\350\276\223\351\200\201\347\272\277/WCS-\350\276\223\351\200\201\347\272\277\345\257\271\346\216\245\345\215\217\350\256\256\350\257\264\346\230\216-V260202.docx" "b/\351\241\271\347\233\256\350\265\204\346\226\231/\350\256\276\345\244\207\345\215\217\350\256\256/\351\253\230\345\270\270\346\270\251\345\240\206\345\236\233\346\234\272\344\270\216\350\276\223\351\200\201\347\272\277/WCS-\350\276\223\351\200\201\347\272\277\345\257\271\346\216\245\345\215\217\350\256\256\350\257\264\346\230\216-V260202.docx"
new file mode 100644
index 0000000..5ca1c16
--- /dev/null
+++ "b/\351\241\271\347\233\256\350\265\204\346\226\231/\350\256\276\345\244\207\345\215\217\350\256\256/\351\253\230\345\270\270\346\270\251\345\240\206\345\236\233\346\234\272\344\270\216\350\276\223\351\200\201\347\272\277/WCS-\350\276\223\351\200\201\347\272\277\345\257\271\346\216\245\345\215\217\350\256\256\350\257\264\346\230\216-V260202.docx"
Binary files differ
diff --git "a/\351\241\271\347\233\256\350\265\204\346\226\231/\350\256\276\345\244\207\345\215\217\350\256\256/\351\253\230\345\270\270\346\270\251\345\240\206\345\236\233\346\234\272\344\270\216\350\276\223\351\200\201\347\272\277/WCS\350\276\223\351\200\201\345\257\271\346\216\245\345\234\260\345\235\200\350\241\250.xlsx" "b/\351\241\271\347\233\256\350\265\204\346\226\231/\350\256\276\345\244\207\345\215\217\350\256\256/\351\253\230\345\270\270\346\270\251\345\240\206\345\236\233\346\234\272\344\270\216\350\276\223\351\200\201\347\272\277/WCS\350\276\223\351\200\201\345\257\271\346\216\245\345\234\260\345\235\200\350\241\250.xlsx"
new file mode 100644
index 0000000..738b139
--- /dev/null
+++ "b/\351\241\271\347\233\256\350\265\204\346\226\231/\350\256\276\345\244\207\345\215\217\350\256\256/\351\253\230\345\270\270\346\270\251\345\240\206\345\236\233\346\234\272\344\270\216\350\276\223\351\200\201\347\272\277/WCS\350\276\223\351\200\201\345\257\271\346\216\245\345\234\260\345\235\200\350\241\250.xlsx"
Binary files differ
diff --git "a/\351\241\271\347\233\256\350\265\204\346\226\231/\350\256\276\345\244\207\345\215\217\350\256\256/\351\253\230\345\270\270\346\270\251\345\240\206\345\236\233\346\234\272\344\270\216\350\276\223\351\200\201\347\272\277/\345\240\206\345\236\233\346\234\272\344\270\216\344\270\212\344\275\215\346\234\272\344\272\244\344\272\222\344\277\241\346\201\257.xlsx" "b/\351\241\271\347\233\256\350\265\204\346\226\231/\350\256\276\345\244\207\345\215\217\350\256\256/\351\253\230\345\270\270\346\270\251\345\240\206\345\236\233\346\234\272\344\270\216\350\276\223\351\200\201\347\272\277/\345\240\206\345\236\233\346\234\272\344\270\216\344\270\212\344\275\215\346\234\272\344\272\244\344\272\222\344\277\241\346\201\257.xlsx"
new file mode 100644
index 0000000..6d42a93
--- /dev/null
+++ "b/\351\241\271\347\233\256\350\265\204\346\226\231/\350\256\276\345\244\207\345\215\217\350\256\256/\351\253\230\345\270\270\346\270\251\345\240\206\345\236\233\346\234\272\344\270\216\350\276\223\351\200\201\347\272\277/\345\240\206\345\236\233\346\234\272\344\270\216\344\270\212\344\275\215\346\234\272\344\272\244\344\272\222\344\277\241\346\201\257.xlsx"
Binary files differ
diff --git "a/\351\241\271\347\233\256\350\265\204\346\226\231/\351\234\200\350\246\201\345\257\271\346\216\245\347\232\204\350\256\276\345\244\207\344\277\241\346\201\257/\351\231\225\347\205\244\347\241\254\344\273\266\350\256\276\345\244\207\345\257\271\346\216\245.xls" "b/\351\241\271\347\233\256\350\265\204\346\226\231/\351\234\200\350\246\201\345\257\271\346\216\245\347\232\204\350\256\276\345\244\207\344\277\241\346\201\257/\351\231\225\347\205\244\347\241\254\344\273\266\350\256\276\345\244\207\345\257\271\346\216\245.xls"
index b353b78..a1596bf 100644
--- "a/\351\241\271\347\233\256\350\265\204\346\226\231/\351\234\200\350\246\201\345\257\271\346\216\245\347\232\204\350\256\276\345\244\207\344\277\241\346\201\257/\351\231\225\347\205\244\347\241\254\344\273\266\350\256\276\345\244\207\345\257\271\346\216\245.xls"
+++ "b/\351\241\271\347\233\256\350\265\204\346\226\231/\351\234\200\350\246\201\345\257\271\346\216\245\347\232\204\350\256\276\345\244\207\344\277\241\346\201\257/\351\231\225\347\205\244\347\241\254\344\273\266\350\256\276\345\244\207\345\257\271\346\216\245.xls"
Binary files differ
diff --git "a/\351\241\271\347\233\256\350\265\204\346\226\231/\351\253\230\345\270\270\346\270\251\345\240\206\345\236\233\346\234\272/\345\240\206\345\236\233\346\234\272\351\200\232\344\277\241\345\215\217\350\256\256.xlsx" "b/\351\241\271\347\233\256\350\265\204\346\226\231/\351\253\230\345\270\270\346\270\251\345\240\206\345\236\233\346\234\272/\345\240\206\345\236\233\346\234\272\351\200\232\344\277\241\345\215\217\350\256\256.xlsx"
deleted file mode 100644
index 9e4ea08..0000000
--- "a/\351\241\271\347\233\256\350\265\204\346\226\231/\351\253\230\345\270\270\346\270\251\345\240\206\345\236\233\346\234\272/\345\240\206\345\236\233\346\234\272\351\200\232\344\277\241\345\215\217\350\256\256.xlsx"
+++ /dev/null
Binary files differ
diff --git "a/\351\241\271\347\233\256\350\265\204\346\226\231/\351\253\230\345\270\270\346\270\251\345\240\206\345\236\233\346\234\272/\346\250\241\346\213\237PLC\347\250\213\345\272\217.zip" "b/\351\241\271\347\233\256\350\265\204\346\226\231/\351\253\230\345\270\270\346\270\251\345\240\206\345\236\233\346\234\272/\346\250\241\346\213\237PLC\347\250\213\345\272\217.zip"
deleted file mode 100644
index a06de9c..0000000
--- "a/\351\241\271\347\233\256\350\265\204\346\226\231/\351\253\230\345\270\270\346\270\251\345\240\206\345\236\233\346\234\272/\346\250\241\346\213\237PLC\347\250\213\345\272\217.zip"
+++ /dev/null
Binary files differ
--
Gitblit v1.9.3